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

/login/auth not being redirected to on non-restful controller/action requests #51

Closed
charlesread opened this issue Mar 27, 2014 · 14 comments
Assignees
Milestone

Comments

@charlesread
Copy link

Hi Alvaro!

First of all I LOVE the plugin - thank you so much for creating it! My only "issue" with it is that the plugin seems to short-circuit Spring Security's default behavior of redirecting to /login/auth when browsing to a secured controller/action via a browser - it just comes back 403, obviously from the grails.plugin.springsecurity.rest.login.failureStatusCode configuration option. How can I get your WONDERFUL plugin to play more nicely in an environment with RESTful API(s) and traditional secured controllers/actions?

Edit: I see this mentioned in #31, but I am actually not quite sure how to do what you suggested as a work-around (I am relatively new to Grails and Java development, in general)

I am using Grails 2.3.7 with Spring Core 2.0 and version 1.3.1 of your plugin, if it helps.

Thanks again for the plugin!

:)

@alvarosanchez
Copy link
Member

I will need to see the logs. The filter of this plugin only executes if and only if the X-Auth-Token header is on the request. So is highly probably that the 403 is coming from Spring Security Core.

Enable debugging as specified in the documentation, and paste here the output.

@domenicbenz
Copy link

Hi Alvaro

Since I stumbled into the same issue I took some time trying to figure out what exactly goes wrong.
I think the problem is that you overwrite the default authenticationEntryPoint on line 109 in your plugin configuration:

class SpringSecurityRestGrailsPlugin{
...
authenticationEntryPoint(Http403ForbiddenEntryPoint)
...

This alters the standard behaviour of spring security core to always return 403 instead of redirecting to the login form.

-> Maybe you can simply fix this by creating & using a custom entry point (restAuthenticationEntryPoint) instead of overwriting the default?

Or maybe you don't need to overwrite it at all? If I configure it back to default in resources.groovy everything seems to be working...

resources.groovy:

...
// default 'authenticationEntryPoint'
    authenticationEntryPoint(AjaxAwareAuthenticationEntryPoint, '/login/auth') { // '/login/auth'
        ajaxLoginFormUrl = '/login/authAjax' // '/login/authAjax'
        forceHttps = false // false
        useForward = false // false
        portMapper = ref('portMapper')
        portResolver = ref('portResolver')
    }
...

Cheers & Thx for your work!

@alvarosanchez
Copy link
Member

@domenicbenz you are probably right. I will need to investigate further, because the issue can also be caused by accessDeniedHandler bean.

But yes, will try to provide new beans instead of reuse existing ones.

Thank you very much for your feedback!

@alvarosanchez
Copy link
Member

Dear all,

I've found the way to not collide with traditional Spring Security usage, so you won't have to provide any custom implementation.

This is going to take part of an upcoming 1.4.0.M1 release that will be released tomorrow.

@alvarosanchez alvarosanchez added this to the 1.3.5 milestone May 29, 2014
@charlesread
Copy link
Author

Very nice!

@domenicbenz
Copy link

nice! looking forward to the new release :)

@tircnf
Copy link

tircnf commented May 30, 2014

I tried the 1.4.0.M1 release, and now if I visit a page it responds with HTTP status 400/Token Header is missing.

I'm running with the following plugins.

   compile ":spring-security-core:2.0-RC3"
   compile ":spring-security-rest:1.4.0.M1"

@alvarosanchez
Copy link
Member

@tircnf too fast! The documentation wasn't published yet. But now it is.

I've included a new chapter explaining how to configure the filter chains for both scenarios:

http://alvarosanchez.github.io/grails-spring-security-rest/docs/guide/configuration.html

@charlesread @domenicbenz please try yourselves as well.

@tircnf
Copy link

tircnf commented May 30, 2014

Thanks for the quick response Alvaro! I added in those configuration options and my standard spring security started to work again.

I only started playing with this plugin yesterday. What is the easiest way to test the token generation from the command line?

Is there a curl command I can use to simulate a rest login?
I tried
curl -i -X POST -H "Content-Type: application/json" -d "{username:'admin', password:'pass'}" http://localhost:8080/api/login

but get an
HTTP/1.1 400 Bad Request.

sending in a GET or PUT request respond with
HTTP/1.1 405 Method Not Allowed

@tircnf
Copy link

tircnf commented May 31, 2014

in case anyone stumbles across this post... you aren't allowed to use single quotes in your json object.

the correct curl request is

curl -i -X POST -H "Content-Type: application/json" -d '{"username":"admin", "password":"pass"}' http://localhost:8080/api/login

notice the keys have to be quoted as well as values, and quoted with double quote, not a single quote.

@st-h
Copy link

st-h commented May 31, 2014

Personally I would really prefer if the http response on a missing token would be 401 instead of 400. If no token is set, the user is not authenticated and therefore an anonymous user. If he tries to access a protected resource, the correct response should be 401 unauthorized. In addition the http 400 gets pretty weird if the client does not know beforehand which resources are protected and which are not. The client would have to parse the response body in order to determine that authentication is required.

However, I really need to thank you for writing such a great plug-in. It's a huge relieve not having to directly deal with the spring-security-core plug-in anymore.

@alvarosanchez
Copy link
Member

In my understanding, a request made to a URL where the token header is mandatory, but missing, is clearly a bad request.

Anyways, I will make that configurable. It has been logged as #68.

@st-h
Copy link

st-h commented May 31, 2014

Thanks for making that configurable. If an endpoint per convention requires this header to be set, it kind of actually could make sense to treat that as a http 400. For other cases it is much easier to tell the client "you need to be authenticated here" and then the client can act accordingly. Anyways, as I was curios what the rfc would say, I just looked it up:
http://www.ietf.org/rfc/rfc2617.txt - 3.2.1
"If a server receives a request for an access-protected object, and an
acceptable Authorization header is not sent, the server responds with
a "401 Unauthorized" status code, and a WWW-Authenticate header as
per the framework defined above, which for the digest scheme is
utilized as follows:"
But there are always cases when those things are debatable, so +1 for the configuration option :)

@alvarosanchez
Copy link
Member

Okay, you convinced me. It will not only be configurable, but also the default value will be 401 :)

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

No branches or pull requests

5 participants