Code Monkey home page Code Monkey logo

Comments (15)

tuupola avatar tuupola commented on May 22, 2024

Can you show me the code you are using?

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

middleware.php

`<?php

/*

*/
use App\Token;

use Slim\Middleware\JwtAuthentication;
use Slim\Middleware\HttpBasicAuthentication;
use Tuupola\Middleware\Cors;
use Gofabian\Negotiation\NegotiationMiddleware;
use Micheh\Cache\CacheUtil;

$container = $app->getContainer();

//var_dump($container);

$container["HttpBasicAuthentication"] = function ($container) {
return new HttpBasicAuthentication([
"secure" => false,
"path" => "/token",
//"realm" => "Protected",
//"relaxed" => ["192.168.50.52"],
"environment" => "REDIRECT_HTTP_AUTHORIZATION",
"users" => [
"test" => "1234"
],
"callback" => function ($request, $response, $arguments) {
// print_r($arguments);
// die;
},
"error" => function ($request, $response, $arguments) {
$data = [];
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response->write(json_encode($data, JSON_UNESCAPED_SLASHES));
}
]);
};

$container["token"] = function ($container) {
return new Token;
};

$container["JwtAuthentication"] = function ($container) {
return new JwtAuthentication([
//"cookie" => "taskiu",
"secure" => false,
"path" => "/",
"passthrough" => ["/token", "/info"],
"secret" => getenv("JWT_SECRET"),
"logger" => $container["logger"],
//"relaxed" => ["192.168.50.52"],
"environment" => ["HTTP_AUTHORIZATION", "REDIRECT_HTTP_AUTHORIZATION", "REDIRECT_REDIRECT_HTTP_AUTHORIZATION"],
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
},
"callback" => function ($request, $response, $arguments) use ($container) {
$container["token"]->hydrate($arguments["decoded"]);
}
]);
};

$container["Cors"] = function ($container) {
return new Cors([
"logger" => $container["logger"],
"origin" => ["*"],
"methods" => ["GET", "POST", "PUT", "PATCH", "DELETE"],
"headers.allow" => ["Authorization", "If-Match", "If-Unmodified-Since"],
"headers.expose" => ["Authorization", "Etag"],
"credentials" => true,
"cache" => 60,
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
]);
};

$container["Negotiation"] = function ($container) {
return new NegotiationMiddleware([
"accept" => ["application/json"]
]);
};

$app->add("HttpBasicAuthentication");
$app->add("JwtAuthentication");
$app->add("Cors");
$app->add("Negotiation");

$container["cache"] = function ($container) {
return new CacheUtil;
};
`

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

HttpBasicAuthentication.php

`<?php

/*

*/

namespace Slim\Middleware;

use Slim\Middleware\HttpBasicAuthentication\AuthenticatorInterface;
use Slim\Middleware\HttpBasicAuthentication\ArrayAuthenticator;
use Slim\Middleware\HttpBasicAuthentication\RequestMethodRule;
use Slim\Middleware\HttpBasicAuthentication\RequestPathRule;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class HttpBasicAuthentication
{
private $rules;
private $options = [
"secure" => true,
"relaxed" => ["localhost", "127.0.0.1"],
"users" => null,
"path" => null,
"passthrough" => null,
"realm" => "Protected",
"environment" => "HTTP_AUTHORIZATION",
"authenticator" => null,
"callback" => null,
"error" => null
];

public function __construct($options = [])
{
    /* Setup stack for rules */
    $this->rules = new \SplStack;

    /* Store passed in options overwriting any defaults */
    $this->hydrate($options);

    /* If array of users was passed in options create an authenticator */
    if (is_array($this->options["users"])) {
        $this->options["authenticator"] = new ArrayAuthenticator([
            "users" => $this->options["users"]
        ]);
    }

    /* If nothing was passed in options add default rules. */
    if (!isset($options["rules"])) {
        $this->addRule(new RequestMethodRule([
            "passthrough" => ["OPTIONS"]
        ]));
    }

    /* If path was given in easy mode add rule for it. */
    if (null !== $this->options["path"]) {
        $this->addRule(new RequestPathRule([
            "path" => $this->options["path"],
            "passthrough" => $this->options["passthrough"]
        ]));
    }

    /* There must be an authenticator either passed via options */
    /* or added because $this->options["users"] was an array. */
    if (null === $this->options["authenticator"]) {
        throw new \RuntimeException("Authenticator or users array must be given");
    }
}

public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
{
    $host = $request->getUri()->getHost();
    $scheme = $request->getUri()->getScheme();
    $server_params = $request->getServerParams();

    /* If rules say we should not authenticate call next and return. */
    if (false === $this->shouldAuthenticate($request)) {
        return $next($request, $response);
    }

    /* HTTP allowed only if secure is false or server is in relaxed array. */
    if ("https" !== $scheme && true === $this->options["secure"]) {
        if (!in_array($host, $this->options["relaxed"])) {
            $message = sprintf(
                "Insecure use of middleware over %s denied by configuration.",
                strtoupper($scheme)
            );
            throw new \RuntimeException($message);
        }
    }

    /* Just in case. */
    $user = false;
    $password = false;

    /* If using PHP in CGI mode. */
    if (isset($server_params[$this->options["environment"]])) {
        if (preg_match("/Basic\s+(.*)$/i", $server_params[$this->options["environment"]], $matches)) {
            list($user, $password) = explode(":", base64_decode($matches[1]), 2);
        }
    } else {
        if (isset($server_params["PHP_AUTH_USER"])) {
            $user = $server_params["PHP_AUTH_USER"];
        }
        if (isset($server_params["PHP_AUTH_PW"])) {
            $password = $server_params["PHP_AUTH_PW"];
        }
    }

    $params = ["user" => $user, "password" => $password];

    /* Check if user authenticates. */
    if (false === $this->options["authenticator"]($params)) {
        /* Set response headers before giving it to error callback */
        $response = $response
            ->withStatus(401)
            ->withHeader("WWW-Authenticate", sprintf('Basic realm="%s"', $this->options["realm"]));

        return $this->error($request, $response, [
            "message" => "Authentication failed"
        ]);
    }

    /* If callback returns false return with 401 Unauthorized. */
    if (is_callable($this->options["callback"])) {
        if (false === $this->options["callback"]($request, $response, $params)) {
            /* Set response headers before giving it to error callback */
            $response = $response
                ->withStatus(401)
                ->withHeader("WWW-Authenticate", sprintf('Basic realm="%s"', $this->options["realm"]));

            return $this->error($request, $response, [
                "message" => "Callback returned false"
            ]);
        }
    }


    /* Everything ok, call next middleware. */
    return $next($request, $response);
}

private function hydrate($data = [])
{
    foreach ($data as $key => $value) {
        $method = "set" . ucfirst($key);
        if (method_exists($this, $method)) {
            call_user_func([$this, $method], $value);
        }
    }
}

private function shouldAuthenticate(RequestInterface $request)
{
    /* If any of the rules in stack return false will not authenticate */
    foreach ($this->rules as $callable) {
        if (false === $callable($request)) {
            return false;
        }
    }
    return true;
}

/**
 * Call the error handler if it exists
 *
 * @return void
 */
public function error(RequestInterface $request, ResponseInterface $response, $arguments)
{
    if (is_callable($this->options["error"])) {
        $handler_response = $this->options["error"]($request, $response, $arguments);
        if (is_a($handler_response, "\Psr\Http\Message\ResponseInterface")) {
            return $handler_response;
        }
    }
    return $response;
}

public function getAuthenticator()
{
    return $this->options["authenticator"];
}

public function setAuthenticator($authenticator)
{
    $this->options["authenticator"] = $authenticator;
    return $this;
}

public function getUsers()
{
    return $this->options["users"];
}

/* Do not mess with users right now */
private function setUsers($users)
{
    $this->options["users"] = $users;
    return $this;
}

public function getPath()
{
    return $this->options["path"];
}

/* Do not mess with path right now */
private function setPath($path)
{
    $this->options["path"] = $path;
    return $this;
}

public function getPassthrough()
{
    return $this->options["passthrough"];
}

private function setPassthrough($passthrough)
{
    $this->options["passthrough"] = $passthrough;
    return $this;
}

public function getRealm()
{
    return $this->options["realm"];
}

public function setRealm($realm)
{
    $this->options["realm"] = $realm;
    return $this;
}

public function getEnvironment()
{
    return $this->options["environment"];
}

public function setEnvironment($environment)
{
    $this->options["environment"] = $environment;
    return $this;
}

/**
 * Get the secure flag
 *
 * @return boolean
 */
public function getSecure()
{
    return $this->options["secure"];
}

/**
 * Set the secure flag
 *
 * @return self
 */
public function setSecure($secure)
{
    $this->options["secure"] = !!$secure;
    return $this;
}

/**
 * Get hosts where secure rule is relaxed
 *
 * @return string
 */
public function getRelaxed()
{
    return $this->options["relaxed"];
}

/**
 * Set hosts where secure rule is relaxed
 *
 * @return self
 */
public function setRelaxed(array $relaxed)
{
    $this->options["relaxed"] = $relaxed;
    return $this;
}

/**
 * Get the callback
 *
 * @return string
 */
public function getCallback()
{
    return $this->options["callback"];
}

/**
 * Set the callback
 *
 * @return self
 */
public function setCallback($callback)
{
    $this->options["callback"] = $callback;
    return $this;
}

/**
 * Get the error handler
 *
 * @return string
 */
public function getError()
{
    return $this->options["error"];
}

/**
 * Set the error handler
 *
 * @return self
 */
public function setError($error)
{
    $this->options["error"] = $error;
    return $this;
}

public function getRules()
{
    return $this->rules;
}

public function setRules(array $rules)
{
    /* Clear the stack */
    unset($this->rules);
    $this->rules = new \SplStack;

    /* Add the rules */
    foreach ($rules as $callable) {
        $this->addRule($callable);
    }
    return $this;
}

public function addRule($callable)
{
    $this->rules->push($callable);
    return $this;
}

}
`

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

I use this REST client.

chrome://restclient/content/restclient.html

from slim-basic-auth.

tuupola avatar tuupola commented on May 22, 2024

HttpBasicAuthentication.php

Have you done some changes to the middleware or why did you post this code?

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

No i don't change anything in the HttpBasicAuthentication.php

from slim-basic-auth.

tuupola avatar tuupola commented on May 22, 2024

This is too big and confusing code dump. Can you show minimal code example which reproduces the problem together with example curl request showing the request and response headers. Something like:

$ curl --include --user user:password https//example.com/token

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

With curl testing it works fine. I think the REST client for chrome will "remember" de user basic auth, because i have removed it the credentials to test and it send equal.

One question: when i try like this i got a warning:
curl "http://taskiu.cesigrup.es/api/v1/public/token" --request POST --include --insecure --header "Content-Type: application/json" --data '["tareas.all"]' --user test:1234

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

This is the response

HTTP/1.1 201 Created
Date: Thu, 13 Apr 2017 14:27:39 GMT
Server: Apache
Content-Length: 432
Content-Type: application/json

{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0OTIwOTM2NTksImV4cCI6MTQ5MjEwMDg1OSwianRpIjoiNG1YOFEzYVlvWU9kdWRtakp4Wk96dyIsInN1YiI6bnVsbCwic2NvcGUiOm51bGx9.2TdEejv6NMvUoFFqXR2T5lXilS1LLH2b2hL-rN6OFno", "expires": 1492100859
}
Warning: array_filter() expects parameter 1 to be array, null given in <
b>/var/www/vhost/cesigrup.es/home/html/taskiu/api/v1/routes/token.php on line 34

from slim-basic-auth.

tuupola avatar tuupola commented on May 22, 2024

What is in token.php around line 34? It is not part of Basic Auth middleware.

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024
$scopes = array_filter($requested_scopes, function ($needle) use ($valid_scopes) {
    return in_array($needle, $valid_scopes);
});

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

I'm testing your example https://github.com/tuupola/slim-api-skeleton
With php 7

from slim-basic-auth.

tuupola avatar tuupola commented on May 22, 2024

Fresh install with slim-api-skeleton works ok for me. You might have changed some code which broke the token generation.

$ curl http://192.168.50.52/token --request POST --include --insecure --header "Content-Type: application/json" --data '["tareas.all"]' --user test:test

HTTP/1.1 201 Created
Date: Thu, 13 Apr 2017 14:40:02 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.6.30
Content-Length: 247
Connection: close
Content-Type: application/json

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0OTIwOTQ0MDMsImV4cCI6MTQ5MjEwMTYwMywianRpIjoiMTRKTXF4SjNTNU1OU0NWZ3NubVplWiIsInN1YiI6InRlc3QiLCJzY29wZSI6W119.tXlQa3RI27-vj34y2khhItkA2rVz5ooDzC3CUDol0SI",
    "expires": 1492101603
}

from slim-basic-auth.

manelj avatar manelj commented on May 22, 2024

Ok. Now it works. I am sending body like this { "data" : ["tareas.all"] } and it's wrong, it has to be only the array ["tareas.all"]

Can i ask you what does exactly this piece from middleware.php ?

$container["Negotiation"] = function ($container) { return new NegotiationMiddleware([ "accept" => ["application/json"] ]); };

from slim-basic-auth.

tuupola avatar tuupola commented on May 22, 2024

It adds the content negotiation middleware. The README contains quite good explanation what the middleware does.

from slim-basic-auth.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.