Custom AccessDecisionManager in spring security - spring

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">

Related

Spring Authorization Server - Configure User Info Endpoint - Spring Roles in Resource Server

I have an existing resource server that is configured to use Spring user rules as security methods. I am trying to migrate onto the Spring Authorization server and trying to figure out how these roles can be accessed in the resource server.
When the user is authentication, I can see in debug logs that my roles are part of the authorized user details. But in the resource server, I am getting default roles from OidcService and scopes as granted authorities.
I know Spring Authorization server 0.21 has implemented the User Info endpoint, but there seems to be no sample or documentation available on how to configure that, and I am sure implementing it will solve my issue.
Another option that I am thinking about is to configure oauth2TokenCustomizer in the server and then add roles in JWT's claims. Then in the resource server think about overriding default OidcService and parse claims to add roles as granted authorities. But issue is with OidcUserService i don't see any code which can give me access to JWT claims.
public class CustomOAuth2Token implementsOAuth2TokenCustomizer<JwtEncodingContext> {
#Override
public void customize(JwtEncodingContext context) {
// Load user details and add roles to claims
}
}
Probably will have to provide a custom extension for OidcAuthorizationCodeAuthenticationProvider and then modify authenticated principal details.
I was facing the same issue.
Customizing the response of the "well-known" openid-configuration endpoint is somewhat tricky because the filter handling this endpoint has hardcoded mappings for which field go and do not go in the response.
I worked around this by:
copying this class into my codebase and giving it another name, in my case CustomOidcProviderConfigurationEndpointFilter
using my custom class as an objectPostProcessor for OidcProviderConfigurationEndpointFilter replacing it entirely instead of just customizing it.
This means your custom filter will supply the OidcProviderConfiguration object from now on.
You could then call the claim method on this object to add properties such as "userinfo_endpoint".
Note: I was unable to properly format the code snippet in the second link inside this post. If someone with administrative rights could edit this in, this would be nice.

Spring Boot. how to secure some pages but not all the pages

We are creating a spring boot web application to send RSS data to a Ticker Sign (ticker).
The URLs that send RSS data to the ticker sign do not need to be secured with ldap or other credentials.
But we have one page we we update a custom message that we send to the Ticker sign. We want to secure this page with the corporate ldap.
Is it possible to configure spring boot to only require a login for one page and the rest of the pages can remain unsecured.
You can create a role with all permission to access and grant that access just in some methods using Spring security annotation http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
<http use-expressions="true">
<intercept-url pattern="/*"
access="hasRole('admin')"/>
</http>
Then in your free access method
#PreAuthorize("hasRole('admin')")
public void create(Contact contact);
To use this it is very important that you name your URLs wisely i.e. if you want to assign admin role then make a URL look something like /admin/v1/something-here. It will make things readable and simple for you.

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.

How to handle requests if no matching spring security <intercept-url>?

I'm using spring 3.1.1 and spring security 3.1.0. I'd like to enforce a policy that all http requests that are not explicitly configured with an <intercept-url pattern="..." access="..."/> entry are handled in a particular way. For requests that match a configured <intercept-url/> I want to use typical role based access decisions. However, for non-matching requests, I want to either respond with a 404 (not found) (or maybe 403/forbidden). I want to do this so that I and other team members are forced to explicitly configure spring security and associated roles for any new endpoints.
I originally thought that I could use <intercept-url pattern="/**" access="denyAll"/> as the last intercept-url and that spring would do what I wanted. This technique works if the user is already authenticated but is a little strange for unauthenticated/anonymous users. For anonymous users, spring detects (in ExceptionTranslationFilter) that the user is anonymous and starts the authentication process when requests like /missingResource are processed. Typically this means that the user is redirected to a login form and, after logging in, is redirected back to /missingResource. So the user has to login in order to see a 404 (not found) page.
I ended up removing the intercept-url pattern="/**" access="denyAll"/> and writing a custom filter that runs after="FILTER_SECURITY_INTERCEPTOR" and responds with 404 for requests that are not matched by the FilterSecurityInterceptor but it seemed a little complicated. Is there a better or simpler way?
you can define a separate http element for intercept url /** with access ="denyAll" and add a custom entry-point-ref to avoid spring to redirect user to login form, you can use existing entryPoint Http403ForbiddenEntryPoint for showing 403 error response or implement your own by implementing AuthenticationEntryPoint.
Hope it helps.

Access to User ID in Spring

I'm doing some proof-of-concept work with Spring MVC and security. So far I've managed to write a simple web-app which has a secure webpage which requires a user to login and have the correct role before accessing the database and listing some data. I'm using Spring 2.0.8 by the way.
What I require is that, after the user has logged on, is to access the user principal object for the current session to pass into my DAO layer. I'd like to do this through the standard bean wiring, so it will have to be something determined at runtime.
Any pointers to get started ?
Cheers
Neil
SecurityContextHolder#getContext() will return a SecurityContext associated with the current user request.
From there, you can call getAuthentication().getPrincipal() to get the data associated with the logged-in user.
There is no need to inject any bean, the static method in SecurityContextHolder will take care of accessing the correct thread-local data.

Resources