Spring Security #RolesAllowed Works but #Secured gives me AccessDeniedException in Spring 3.2 with Spring Security 3.1 - spring

I am having an issue where my Controller method with #RolesAllowed works correctly but if I try to use #Secured I get an AccessDeniedException. While I would prefer to use the #RolesAllowed Annotation it has been declared that for this project we should Use #Secured because the name is less confusing when mapped to our legacy access rights.
I have the annotation configured as follows:
<security:global-method-security jsr250-annotations="enabled" secured-annotations="enabled" pre-post-annotations="enabled" />
When I use #RolesAllowed("COMPANY_SEE_REPORTS") which my user has, it works correctly. When I use #Secured("COMPANY_SEE_REPORTS") I get an AccessDeniedException. Just to make sure #RolesAllowed was working correctly I changed the role to a role that didn't exist and at that point #RolesAllowed threw. So my question is how can I get #Secured to work correctly?

Try to use a security role with a name that ends with ROLE
From Spring Security Reference:
RoleVoter
The most commonly used AccessDecisionVoter provided with Spring
Security is the simple RoleVoter, which treats configuration
attributes as simple role names and votes to grant access if the user
has been assigned that role.
It will vote if any ConfigAttribute begins with the prefix ROLE_. It
will vote to grant access if there is a GrantedAuthority which returns
a String representation (via the getAuthority() method) exactly equal
to one or more ConfigAttributes starting with the prefix ROLE_. If
there is no exact match of any ConfigAttribute starting with ROLE_,
the RoleVoter will vote to deny access. If no ConfigAttribute begins
with ROLE_, the voter will abstain.
But you can modify the RoleVoter prefix RoleVoter#setRolePrefix(String rolePrefix)

Related

Spring #PreAuthorize not working in RestController

I have GrantedAuthorities as [admin, player, user]
To test this I have injected Authentication object in method and invoked authentication.getAuthorities().
but when at REST Controller Method I put #PreAuthorize("hasRole('ROLE_player')")I am getting response for my REST web service as 403 forbidden.
I have custom roles defined which I am picking from database. I want to authorize REST call before execution of any business logic.
Tried with #Secured but still not working.
The default prefix for hasRole is ROLE_. If a prefix isn't supplied, spring will automatically add it. Since your roles in your database aren't prefixed with ROLE_ they will not match with hasRole.
// will be checking for ROLE_admin, your role in DB is admin
#PreAuthorize("hasRole('admin')")
You can update your roles in your db to prefix them with ROLE_ or you can alter the prefix spring uses on DefaultWebSecurityExpressionHandler. You should also be able to use hasAuthority rather than hasRole. The hasAuthority will not add any prefix to the supplied parameter.
#PreAuthorize("hasAuthority('admin')")
http://docs.spring.io/spring-security/site/docs/current/reference/html/el-access.html

Custom AccessDecisionManager in spring security

We are integrating our JSF2 application with Spring Security. We have done the basic setup and its working fine. However we need to implement a custom access decision manager to filter the requests.
For example if user with user privileges try to access a page dedicated to admin, in this case we need to check first whether the user is logged in or not , if logged in get his authorities. I have written a access decision manager and i am still in the process of enhancing it. But when i deploy i am getting below error.
java.lang.IllegalArgumentException: AccessDecisionManager does not support secure object class: class org.springframework.security.web.FilterInvocation
Any idea what is the reason for the same.
below is sample from my security-config.xml
disable-url-rewriting="true" access-decision-manager-ref="accessDecisionManager">

Spring Security, Customizing Authorization, AccessDecisionManager vs Security Filter

I'm going to implement a custom authorization based on ([User<-->Role<-->Right]) model and Rights should be compared to controller and method name (e.g. "controller|method").
I used customizing UserDetails and AuthenticationProvider to adjust granted authority (here), but as checked source codes and docs about how customizing the compare of authority I found there is a filter SecurityContextHolderAwareRequestWrapper) that implements isGranted and isUserInRole to compare authority, while the documents say using AccessDecisionManager voters to customize (As I understood). Which one should be used ? Where I have controller and method(action) name to compare authority with them ?
I got confused about Spring security a little. Is there any other resource than official docs that illustrate how it works, I mean sequence of actions and methods and how customize them.
There are several approaches:
Role based, where you assign each user a role and check the role before proceeding
Using Spring security expressions
There is also a new spring acl components which lets you perform acl control on class level and are stored in a database.
My personal usage so far has been 1 and 2, where you only assign roles to users.
But option 3 allows you to create finer grained security model, without having to rebuild your webapp when chaning the security model
Role Based
A role based security mechanism can be realised implementing the UserDetailsService interface and configuring spring security to use this class.
To learn on how to such a project can be realized, take a look at the following tutorials:
Form based login with in memory user database Link
Form based login with custom userdetails service Link
In short spring security performs the following behind the scenes:
Upon authentication (e.g. submitting a login form) an Authentication Object is created which holds the login credentials. For example the UsernamePasswordAuthenticationFilter creates an UsernamePasswordAuthenticationToken
The authentication object is passed to an AuthenticationManager, which can be thought of as the controller in the authentication process. The default implementation is the ProviderManager
The AuthenticationManager performs authentication via an AuthenticationProvider. The default implementation used is the DaoAuthenticationProvider.
The DaoAuthenticationProvider performs authentication by retrieving the UserDetails from a UserDetailsService. The UserDetails can be thought of as a data Object which contains the user credentials, but also the Authorities/Roles of the user! The DaoAuthenticationProvider retrieves the credentials via its loadUserByUsername method
and then compare it to the supplied UsernamePasswordAuthenticationToken.
UserDetailsService collects the user credentials, the authorities and builds an UserDetails object out of it. For example you can retrieve a password hash and authorities out of a database. When configuring the website url-patterns you can refer to the authorities in the access attribute. Furthermore, you can retrieve the Authentication object in your controller classes via the SecurityContextHolder.getContext().getAuthentication().
Furthemore to get a better understanding of the inner workings of these classes you can read the javadocs:
UserDetails - how the user credentials are stored and accessed
AuthenticationManager.authenticate(..) - contract on how AuthenticationExceptions are handled
UserDetailsService.loadUserByUsername(..)- contact on how username lookup failures are handled, e.g. user does not exist
Spel
Instead of checking authorities, SPEL enables you also to check other properties of a user.
You can use these in the URL patterns, but also annotate methods with #Preauthorize.
This way securing the business layer is less intrusive.
ACL Based
The ACL based model was introduced in spring security 3.0, but hasn't been well documented.
Their suggestion is to look at the Contacts XML example, since this one uses their new acl component.
Last this book contains great examples on how to further customize your security wishes.

Spring Security - JEE tag with user-service-ref attribute loses mapped roles

I'm pretty new to spring, let along spring security, and I've been looking at the Schema files and noticed a <jee> tag that appears under the <http> tag which acts like some sort of preauth filter magic. Using the mappable-roles attribute, I can get the role that I want but, when I specify a different user-service-ref attribute, specifying a UserDetailsService object, I lose the role.
My guess is because when I specify the UserDetailsService object, Spring assumes I don't need the role anymore... but I do!
Any ideas on this? Can I capture those details somehow? If not with this simple <jee> tag, what does the jee tag expand to for custom-filters and pre-auth, etc?
The <jee> tag creates (among others) a PreAuthenticatedAuthenticationProvider bean which delegates to a configured strategy for loading user details.
The default implementation of this strategy is PreAuthenticatedGrantedAuthoritiesUserDetailsService which will simply copy the roles it finds in the authentication token.
By overriding this default strategy with your custom UserDetailsService using the user-service-ref attribute you take the responsibility for assigning roles to the user. If you want to keep the default behavior regarding user roles, you can simply copy the related line from the above mentioned class, as the Java EE roles are still mapped, and are accessible in the auth token to your own code as well.

Spring security with multiple custom filters and roles

I am using Spring security with two filters:
- One filter for x.509 authentication for client certificates. All his filter does is extracts the username from certificate into principle.
- One filter to do header based authentication. The header should have username and roles. In this filter I check to make sure that there is a principal already present in the security context. If present I make sure that it matches whats in the headers. Then I extract the roles from the header and set the granted authorities.
I have a url pattern that I want to be made accessible to roles - 'ROLE_USER'
Now here is the problem. The request only hits the first filter(X.509), the role is missing in this header obviously and access is denied by spring security.
I cannot switch the order of the filters because if I do then X.509 filter provided by spring simply sees that principal is already present and does nothing making it useless.
Is there any way for the role check to be deferred until all filters are processed? Or any other way to achieve what I am trying to do.
Here is my spring security config:
<security:http auto-config="true" entry-point-ref="customEntryPoint">
<security:intercept-url pattern="/user/**" access="ROLE_USER"/>
<security:custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="x509Filter" />
<security:custom-filter after="FILTER_SECURITY_INTERCEPTOR" ref="headerFilter"/>
</security:http>
where the x509Filter is standard spring security filter configured as:
<beans:bean id="x509PrincipalExtractor" class="org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor">
<beans:property name="subjectDnRegex" value="CN=(.*?),"/>
</beans:bean>
I can provide scrubbed up customHeaderFilter if needed but at this point the control never reaches the filter so it is inconsequential as to what happens in it.
Any help/guidance would be greatly appreciated.
Thanks to the pointer from #Maksym, the problem was resolved by changing 'after' to 'before' in the customHeaderFilter as follows:
<security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="headerFilter"/>
FilterSecurityInterceptor is responsible for handling security of HTTP resources, including applying role checks. In my case X509Filter would fire setting principal but would not set any authorities. This would cause the interceptor to deny access to the resource and the headerFilter would not even come into the picture.
By setting the position of the headerFilter to before the interceptor allowed the principal and authentication object in the security context to be set up correctly with the given authorities, leading to the expected behavior.

Resources