Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stuck in authentication loop #5

Closed
repat opened this issue Dec 7, 2015 · 9 comments
Closed

Stuck in authentication loop #5

repat opened this issue Dec 7, 2015 · 9 comments

Comments

@repat
Copy link

repat commented Dec 7, 2015

Hi,

every time I open the my test page I get the prompt to enter details, enter them and get another prompt. This is due to the fact, that $request->getUser() and $request->getPassword() are always empty. In postman and curl I simply get the error message.

I installed laravel in a subfolder, could it be some redirect issue? Maybe I have to enter something in .htaccess?

thanks

@olssonm
Copy link
Owner

olssonm commented Dec 12, 2015

Hi, sorry for late reply (been afk for a while).

Anyhow, using subdirectory shouldn't matter – I'm more leaning into that it's an Apache/Server-issue.

Let's do some testing;

  1. Have you set an APP_KEY in your Laravel-environment?
  2. If you do a dd(app('request')->server);, do you get the PHP_AUTH_USER, PHP_AUTH_PW and/or HTTP_AUTHORIZATION?

Basic auth should work out of the box with NGINX, haven't worked much with it with Apache. As you say, it may very well be related to your .htaccess. If you don't get the parameters in "2" above, try checking out this thread that seems related: http://laravel.io/forum/05-10-2014-http-basic-auth-always-fails-on-ipage

@repat
Copy link
Author

repat commented Dec 12, 2015

No worries :) Thanks for supporting even if it's not the packages fault.

  1. yes
  2. I don't know where exactly I would put that. If I put it in the test method in the controller, it's never reached because I just get the authentication prompt over and over again. If I put it in the middleware, it's executed before the authentication header is sent, which triggers the authentication in the first place. When I cancel the auth request I get the output, but none of the above variables, even when I send the auth details with postman. Maybe I misunderstood? I'm new to Laravel.

I'm on a plane at the moment (free WiFi at Norwegian Air :)) so it's kind of a pain to test with satellite Internet but I'll try the tip from the laravel.io forum and get back to you. Seems like a pretty big hack though. I also did some further digging and found out it might be due to the fact that I run PHP 5.6 via fastcgi. Since it's on a managed server, I don't have much influence on these things.

I guess worst case is that I just have configure all of the authentication in a .htaccess with .htpasswd -.-

@olssonm
Copy link
Owner

olssonm commented Dec 12, 2015

Regarding dd(app('request')->server);: try authenticating once, then remove the auth.very_basic-filter on any route, and just put dd(app('request')->server);. If everything is configured as it is supposed to – a whole array of values should be outputed, among them PHP_AUTH_USER, PHP_AUTH_PW and HTTP_AUTHORIZATION.

Also, just to make sure, surely you've run $ php artisan vendor:publish? =)

@repat
Copy link
Author

repat commented Dec 12, 2015

Yes, I do get an array, with

"REDIRECT_REDIRECT_REMOTE_USER" => "Basic dXNlcjpwYXNzd29yZA=="

I've never seen it before like this. I'm googeling it now..

dXNlcjpwYXNzd29yZA== translates to user:password (which is what I set in the config file).

As far as I understood php artisan vendor:publish is to copy the config files from the vendor/ folder to config/? I think I did that, anyway I just did it again, before writing this. And the file definitely existed. Even so, I logged $request->getUser() and $request->getPassword(), and they shouldn't be empty.

update:

FastCGI on Apache doesn't play well with http_auth. You need to make these changes:
Edit the RewriteRule line in .htaccess to read thus:
RewriteRule . index.php [PT,E=REMOTE_USER:%{HTTP:Authorization},L]

This part would have to be in the Request class that comes from Symfony then?

if(isset($_SERVER['REDIRECT_REDIRECT_REMOTE_USER']))
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':',
base64_decode(substr($_SERVER['REDIRECT_REDIRECT_REMOTE_USER'], 6)));

https://groups.google.com/forum/#!msg/habari-users/H-tx4BwUmXU/UU6785nGcZoJ

fyi, .htaccess has this:

RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]

@repat
Copy link
Author

repat commented Dec 12, 2015

So you can do this:

list($user, $password) = explode(':', base64_decode(substr($_SERVER["REDIRECT_REDIRECT_HTTP_AUTHORIZATION"], 6)));

if you have this in your .htaccess:

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

(notice it said REMOTE_USER before, I changed it to HTTP_AUTHORIZATION, also since it's not the last Rewrite Rule, you can't use L here like in the quote from above).

Anyway, the extration of the username and password works like that, although it feels quite hacky.

But then the Closure $next is called and that doesn't work again, because it seems to be empty. So just like all the other things in the request, the REQUEST_URI is not included (although visible in dd(app('request')->server); if you remove the middleware after authenticating once) and therefore the user can't be redirected to the REQUEST_URI that is protected by the middleware. Seems like we would have to solve this at the very core (http://stackoverflow.com/a/33254772/2517690). Although the REMOTE and REMOTE_REMOTE prefix are not in front of REQUEST_URI... But calling the Closure on the $request object fails anyway. I don't really know Symfony well enough either :-/

Printing the $request variable ends in recursion and crashes the browser ;)

(I also use Route::group(['prefix' => 'myPrefix']) btw.)

The stacktrace:

ReflectionException in Route.php line 152:
Function () does not exist

in Route.php line 152
at ReflectionFunction->__construct('') in Route.php line 152
at Route->runCallable(object(Request)) in Route.php line 130
at Route->run(object(Request)) in Router.php line 708
at Router->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 139
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in VeryBasicAuth.php line 72
at VeryBasicAuth->handle(object(Request), object(Closure))

Unfortunately, I can't update the Apache that's running and I can't use CGIPassAuth on in my .htaccess, so that fastcgi would know of authentication headers because the Apache version is too old. Any other ideas :-/?.

Forgot to use ['uses' => 'MyController@method'] because I fiddled around too much. sorry. Now it works with that little hack of getting user/password out of REDIRECT_REDIRECTAUTH... and so on.

@repat repat closed this as completed Dec 12, 2015
@olssonm
Copy link
Owner

olssonm commented Dec 12, 2015

Cool! I'm looking into building a solution directly into the package. Might I ask what hosting solution you are using?

@repat
Copy link
Author

repat commented Dec 12, 2015

It's a managed server at https://all-inkl.com/server/server_l/ (would not have been my first choice but I didn't have a say in this ;))

PHP 5.3.28 (standard, Apache 2.0 Handler)
PHP 5.6.13 (FPM/FastCGI)

So my public/index.php is a index.php56 because laravel doesn't run under 5.3.28.

@olssonm
Copy link
Owner

olssonm commented Dec 12, 2015

Great, I'll look into it. Opened a new issue here; #6 – would be cool if there is a fix directly in the package for the folks that are stuck in a shared non-configurable environment.

Might get back to you when an update is ready and some testing is needed =)

@repat
Copy link
Author

repat commented Dec 12, 2015

Cool, thanks a lot. I think basically you would have to use that .htacces line and then go through the request and see at which point (how many REDIRECT_ there are) you find "Basic XXXX".

For now, I also put this in the config file, as well as an entry for mb_strlen("Basic ") (including space), so it's clear why the substr() begins at 6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants