Comments (15)
Can you show me the code you are using?
from slim-basic-auth.
middleware.php
`<?php
/*
- This file is part of the Slim API skeleton package
- Copyright (c) 2016-2017 Mika Tuupola
- Licensed under the MIT license:
- http://www.opensource.org/licenses/mit-license.php
- Project home:
- https://github.com/tuupola/slim-api-skeleton
*/
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.
HttpBasicAuthentication.php
`<?php
/*
- This file is part of Slim HTTP Basic Authentication middleware
- Copyright (c) 2013-2017 Mika Tuupola
- Licensed under the MIT license:
- http://www.opensource.org/licenses/mit-license.php
- Project home:
- https://github.com/tuupola/slim-basic-auth
*/
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.
I use this REST client.
chrome://restclient/content/restclient.html
from slim-basic-auth.
HttpBasicAuthentication.php
Have you done some changes to the middleware or why did you post this code?
from slim-basic-auth.
No i don't change anything in the HttpBasicAuthentication.php
from slim-basic-auth.
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.
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.
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.
What is in token.php around line 34? It is not part of Basic Auth middleware.
from slim-basic-auth.
$scopes = array_filter($requested_scopes, function ($needle) use ($valid_scopes) {
return in_array($needle, $valid_scopes);
});
from slim-basic-auth.
I'm testing your example https://github.com/tuupola/slim-api-skeleton
With php 7
from slim-basic-auth.
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.
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.
It adds the content negotiation middleware. The README contains quite good explanation what the middleware does.
from slim-basic-auth.
Related Issues (20)
- Access user/passwd from Authenticator within Slim route handler HOT 1
- Specify callback for the relaxed configuration parameter HOT 3
- Authenticator misinterpretation of "authorization" header HOT 5
- Ignore is not working as expected
- Accessing slim request/app from inside custom authenticator HOT 2
- Uncaught Error: Interface 'Psr\Http\Message\ResponseFactoryInterface' not found HOT 2
- HTTP_X_FORWARDED_PROTO HOT 1
- ignore list HOT 1
- After/Before Callbacks never called? HOT 3
- Class 'Tuupola\Middleware\HttpBasicAuthentication' not found HOT 32
- 401 error in postman HOT 3
- Interface ResponseFactoryInterface not found HOT 5
- Authentification error HOT 4
- Connecting over HTTP when I should not be able to HOT 1
- "final class" and CloudFlare proxification error HOT 1
- Why does local(HTTP) connection work but not online(HTTPS)? HOT 16
- Add request object back to the error handler. HOT 3
- Allow using any callable as a rule
- Do not assume callbacks are a closure
- Before & After Callbacks Never Triggered
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from slim-basic-auth.