If I want to call request.isUserInRole("SOME_ROLE") this means that the request knows about the user making it (assuming the user is authenticated) , my question is : after the user is authenticated where does his information go so that the request knows about it later ? I know that in case of enterprise application , it's stored in a java.security.Principal object, is this the same in a simple web application ?
can I use request.isUserInRole("SOME_ROLE") while using FORM based authentication <auth-method>FORM</auth-method> .... will the authenticated user be reflected to the request automatically?
Usually in simple webapps, the logged in user information is put into http session.
Related
So, we are implementing this special kind of authorization, where after logging in, user is presented with basic dashboard. When trying to get to another location, he is asked to authorize with password.
The thing is that in order to present the basic dashboard, some requests are sent and need to come with 200 response, while the rest just returns error message and redirects to authorization screen.
To summarize, we're gonna have 3 kinds of endpoints:
- blocked, until user authorizes
- allowed to return proper data for the first time while each consecutive request will require authorization
- no authorization required
I cannot find a way to overcome the 2nd type. Is there a way to record the number of requests sent per specific endpoint? Or is there any way to actually allow first unauthorized use and then required authorization?
One way would be to authenticate user without any role the first time that users access to yours controllers.
Then when he try again to access you could sent them to login process if user is logged without role.
To securize this methods could use the annotation below:
#Secure("IsAuthenticated()==false || (IsAuthenticated() && hasRole("WRITE"))")
To securize manually a user should use the SecurityContextHolder class
We're using spring security (Authorisation and Resource server ) in our project.
client sends a token request (/oauth/token) with the oauth2 parameters.
spring security app creates a token for the user and respond to the client with the access_token, refresh_token, custom user object (name, organisation, email etc) and authorities (Roles).
Client adds additional roles (say ROLE_CLIENT, ROLE_USER).
spring application will store the above roles for the given user.
Next time when client sends a token request, spring security returns the previously created token (not expired yet) along with the user and authority information. This authority information is not having the latest roles (added in step4).
Here spring security always using the existing token (as it is not expired) and returning the valid token. Is this the expected behaviour even though the user object is being modified?
It sounds like you need to revoke the access token when the users roles change if you want the next request to get a new access token with the new roles and not return an existing token with existing roles if it's still valid.
At the point where you update the users roles you'd likely want to revoke the token.
I haven't personally tested this but I found a guide for it here https://www.baeldung.com/spring-security-oauth-revoke-tokens so your milage may vary.
I want to add that this does not sound like the normal OAuth2 process and you may be breaking a few conventions here which might bite you later. That said, you don't have to follow a standard if you're confident in your proposed solution.
Edit: To clarify the users roles and access is normally part of a resource and not part of the token exchange. For example you have a normal OAuth2 request which generates a token which you can exchange for an access token, as you've laid out in steps 1 and 2. Then you'd normally take that access token and request user access information from a resource such as "userinfo" service or something similar.
Your security service can also be a resource server but the two steps should be seen as different. Then when you want to modify the users roles you do this again through a resource. This means the next time you invoke the resource it'll have the up to date information without needing to authenticate the user again.
I know this has been asked already, but I am not able to get it to work.
Here is what I would like to get accomplished:
I am using Spring Security 3.2 to secure a REST-like service. No server side sessions.
I am not using basic auth, because that would mean that I need to store the user's password in a cookie on client side. Otherwise the user would need to login with each page refresh/ change. Storing a token is I guess the lesser evil.
A web client (browser, mobile app) calls a REST-like URL to login "/login" with username and password
The server authenticates the user and sends a token back to the client
The client stores the token and adds it to the http request header with each api call
The server checks the validity of the token and sends a response accordingly
I did not even look at the token generation part yet. I know it is backwards, but I wanted to get the token validation part implemented first.
I am trying to get this accomplished by using a custom filer (implementation of AbstractAuthenticationProcessingFilter), however I seem to have the wrong idea about it.
Defining it like this:
public TokenAuthenticationFilter() {
super("/");
}
will only trigger the filter for this exact URL.
I am sticking to some sample implementation, where it calls AbstractAuthenticationProcessingFilter#requiresAuthentication which does not accept wildcards.
I can of course alter that behavior, but this somehow makes me think that I am on the wrong path.
I also started implementing a custom AuthenticationProvider. Maybe that is the right thing?
Can someone give me a push into the right direction?
I think pre-auth filter is a better fit for your scenario.
Override AbstractPreAuthenticatedProcessingFilter's getPrincipal and getCredentials methods.
In case the token is not present in the header, return null from getPrincipal.
Flow:
User logs in for the first time, no header passed, so no
authentication object set in securityContext, normal authentication
process follows i.e. ExceptionTranslation filter redirtects the user
to /login page based on form-logon filter or your custom authenticationEntryPoint
After successful authentication, user requests secured url, pre-auth filter gets token from header authentication object set in
securityContext, if user have access he is allowed to access secured
url
I have a spring-mvc application that currently has two channels - web application and a REST service. Both have user's http session and I can easily get the "current user" in my service classes.
Now I need to develop another REST service where there are no http sessions and the current user depends on a request parameter. So the controller would read that request parameter and would find the current user.
Now I either need to:
1. modify my service layer methods to accept current user as parameter
or
2. just modify the class that gets the current user from the http session.
I also have the requirement to create an audit log and I'm going to use Spring AOP for that. The Aspect will need access to the "current user" too. So option #1 probably won't work for me and I will go with #2.
For option #2 I'll create an interceptor that will put the current user in a ThreadLocal variable. The controller for the new REST service will do the same and then in my service layer and in the audit log aspect I can get the current user from there.
I haven't done anything like this before and was wondering if there is a better approach. Or what kind of issues I should expect with this approach.
I will appreciate any comments and ideas.
Oz
Here is how I currently get the current user:
#Override
public User getCurrentUser()
{
Authentication currentUser = getAuthentication();
return userService.getByLoginName(currentUser.getName());
}
protected Authentication getAuthentication()
{
return SecurityContextHolder.getContext().getAuthentication();
}
I think a simple way to do what you need is to configure a servlet filter for your new REST webservice to populate the SecurityContextHolder with an Authentication object build from request parameters.
You can read this : http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e2171 for more details.
With this solution you don't need to modify the code to retrieve the current user. (note that the SecurityContextHolder is already using a ThreadLocal to store the SecurityContext and so the Authentication)
I'm just curious about how Google app engine's user service works. The way I understand it, the user logged in state is stored in the cookie. To get the cookie, one has to have a http servlet request object (for java servlet at least). But the user service api doesn't require any http servlet request as input, so how does it get the cookie to check the whether the user is logged in or not?
Tim
During requests, user setup is handled by Google's servlet implementation.
[I]f the user is signed in and get the user's email address or OpenID identifier using the standard servlet API, with the request object's getUserPrincipal() method.
During the login process, the service works using redirects, similar to OpenID or OAuth. Take a look a the URLs throughout the login process.
Users are redirected to a URL, which is handled by App Engine, on your app, something like:
http://app.appspot.com/_ah/login?continue=http://app.appspot.com/dosomething
The login handler redirects to the Google login service, something like:
https://www.google.com/accounts/ServiceLogin?service=ah&continue=http://app.appspot.com/_ah/login%3Fcontinue%3Dhttp://app.appspot.com/dosomething<mpl=gm&ahname=Your+App+Name&sig=hf3322hdsk98fd8fh3u29hfh24as
You login, then Google redirects you back to the app engine login handler:
http://app.appspot.com/_ah/login?continue=http://app.appspot.com/dosomething
When Google redirects, some query parameters will be passed to the App Engine login handler, and the built-in login handler will set the cookie.
You are then redirected to the URL you specified, or where you 'started' from. Something like:
http://app.appspot.com/dosomething
What about the in the subsequent calls? For example (continuing from your point 4)
User calls the servlet http://app.appspot.com/dosomethingelse
In the servlet dosoemthingelse, I can again call UserService like this
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String userId = user.getUserId();
How does this userService instance gets the cookie to know who is the currently logged in user?