Don't wanna be here? Send us removal request.
Text
Authorization on a PreAuthenticated spring-security scenario (Round 2)
In my previous post we explored authorization in a preauthenticated scenario and spotted that it seems not working easily out of the box. It seems like there is a hole between the PreAuthenticatedGrantedAuthoritiesUserDetails service and the RequestHeaderAuthenticationFilter which makes no possible to use a request header based preauthenticated authentication system without additional classes.
Now, the good thing is that it is very easy to fix this. Lets see how!
As we saw, the main problem is that “user details service” expects a GrantedAuthoritiesContainer object in the “details” attribute of the PreAuthenticatedAuthenticationToken but no one puts it there (to understand why is this required, when there is a GrantedAuthorities collection present in the token, is a different story).
By default RequestHeaderAuthenticationFilter makes use of WebAuthenticationDetailsSource to provide WebAuthenticationDetails object with additional information present in the request, so we can extend WebAuthenticationDetailsSource with a replacement that makes use of, the more convenient, PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails which already has an attribute holding a collection of granted authorities. Our replacement will also take care about looking for an authorization header in the request, read authorization information there, and setting it up inside our new authentication details object.
One important thing that makes PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails very convenient is that it implements GrantedAuthoritiesContainer interface as well as extends WebAuthenticationDetails so it fits perfectly in the puzzle … just a little piece is missing to make it all works.
One simplistic implementation of that piece would be something like:
public class RequestHeaderAuthenticationDetailsSource extends WebAuthenticationDetailsSource { private static final String authorityHeader = "X-authority"; @Override public WebAuthenticationDetails buildDetails(HttpServletRequest context) { ArrayList<SimpleGrantedAuthority> authorities = new ArrayList<>(); String header = context.getHeader(authorityHeader); if (header != null) { authorities.add(new SimpleGrantedAuthority(header)); } return new PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(context, authorities); } }
Now you just needs to configure RequestHeaderAuthenticationFilter to use our new class declaring it at the `WebSecurityConfigurerAdapter` configuration file, like this:
@Bean public RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter( final AuthenticationManager authenticationManager) { RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter(); filter.setAuthenticationDetailsSource(new RequestHeaderAuthenticationDetailsSource()); filter.setAuthenticationManager(authenticationManager); filter.setExceptionIfHeaderMissing(false); return filter; }
So ... the good thing here is that we can have full spring-security authorization working with just one very simple class. The bad thing is that class should be not even required, in my opinion.
Happy Coding!
0 notes
Text
Authorization on a PreAuthenticated spring-security scenario (Round 1)
ONE of the most used scenario for a PreAuthenticated authentication in spring-security involves retrieving principal information from the header of the HTTP request using RequestHeaderAuthenticationFilter
Filter role is the creation of the PreAuthenticatedAuthenticationToken to pass it through the rest of the security process. Note that this filter inherits from AbstractPreAuthenticatedProcessingFilter which uses WebAuthenticationDetailsSource as default AuthenticationDetailsSource. In this point the method “buildDetails” is called on AuthenticationDetailsSource returning a WebAuthenticationDetails which is setted on the details attribute of the token and passed as attribute to the authenticate method of the AuthenticationManager.
PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken(principal, credentials); authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request)); Authentication authResult = this.authenticationManager.authenticate(authRequest); this.successfulAuthentication(request, response, authResult);
Now note that WebAuthenticationDetails is a simple POJO holding two attributes: remoteAddress, and sessionId which are took from the request object. When authenticate method is called on AuthenticationManager, security process starts trying all available AuthenticationProviders until one of them succeeds. PreAuthenticatedAuthenticationToken inherits from Authentication so it can fit as argument for authenticate method, so, eventually, our PreAuthenticatedAuthenticationProvider will be called and out token will be processed by PreAuthenticatedGrantedAuthoritiesUserDetailsService.
The problem is that when PreAuthenticatedGrantedAuthoritiesUserDetailsService receives the PreAuthenticatedAuthenticationToken it tries to cast, as GrantedAuthoritiesContainer, the content of the “details” field!!
This is very weird since PreAuthenticatedAuthenticationToken inherits from AbstractAuthenticationToken so there is a formal “authorities” attribute of type `Collection<GrantedAuthority>` in the class … but for some reasonWebAuthenticationDetails this is not used and the userdetails service expects a GrantedAuthoritiesContainer object in the details attribute:
((GrantedAuthoritiesContainer)token.getDetails()).getGrantedAuthorities()
However, as we’ve seen, the content of the details attribute in the PreAuthenticatedAuthenticationToken is a WebAuthenticationDetails object which is not a GrantedAuthoritiesContainer!!
Am i missing something here?
0 notes
Text
Preauthenticated principals with spring-security on spring-boot
TODAY i want to share how to set up spring-security over spring-boot application on a preauthenticated scenario.
Preauthentication is a spring-security scenario supported for quite a long time. It is often used when the authentication is provided using X.509 certificates, or when you relay in an external authentication system.
Imgaine a microservice architecture implementing an api-gateway pattern. In this case you might want to avoid implementing authentication in all microservices and rely on a perimetral authentication implemented at the api-gateway component. There are many ways to implement this, and we can talk about that in a different post, but the important thing is that even when you want to avoid authentication in all microservices you might want to know the principal. Probably to implement authorization of some kind. This can be from role based endpoint access to filtering information to be sure principal only access his own data.
There are several handy classes already available in the spring security under the package: org.springframework.security.web.authentication.preauth you may take a look at, like:
PreAuthenticatedAuthenticationProvider
PreauthenticatedGrantedAuthoritiesUserDetailsService
RequestHeaderAuthenticationFilter
With all those pieces you should have already an idea of what comes here: The plan is api-gateway component will place the result of the authentication as custom headers, and rest of the services will transform those headers in a principal object that will be injected in the securityContext where it could be used in @Secured, @PreAuthorize, or any other authorization method you like.
Now lets see the code!
All you need to do in order to confugure preauthenticated filtering in spring-boot is a usual configuration bean extending WebSecurityConfigurerAdapter
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter
Then you need to set the PreAuthenticatedAuthenticationProvider. e.g. like this:
@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(preauthAuthProvider()); }
@Bean public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { PreAuthenticatedAuthenticationProvider preauthAuthProvider = new PreAuthenticatedAuthenticationProvider(); preauthAuthProvider.setPreAuthenticatedUserDetailsService( new PreAuthenticatedGrantedAuthoritiesUserDetailsService() ); return preauthAuthProvider; }
Now you shall declare a RequestHeaderAuthenticationFilter
@Bean public RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter( final AuthenticationManager authenticationManager) { RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter(); }
There are many configuration options in this class, like customizing the principal header name. Look at the documentation for addtional details. NOTE the standard header for the principal id is SM_USER (this is related an external authentication provider called SiteMinder)
Finally you can configure the FilterChainProxy like this:
@Override protected void configure(final HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/**").authenticated() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and().securityContext() .and() .addFilterBefore(requestHeaderAuthenticationFilter(authenticationManager() LogoutFilter.class); }
With this simple configuration you can retrieve the principal id from standard or custom header and inject it in security context. There are plenty customization options on how the security process must behave depending on your needs, like what to do if header is absent, what HTTP status code should be used, and so on.
In next entry post i will write how to deal with authorization since there are a couple of tricky things to have in mind there.
Happy coding!!
0 notes
Text
Caveheats performing authorization on spring data rest endpoints
While doing some proof of concept using Spring Data Rest i realized about one tricky thing related securization of endpoints in Spring Data Rest.
Spring Data Rest has done a great job, and securization is easily implemented using usual @Secured, @PreAuthorize, @PostAuthorize, @PreFilter, and @PostFilter. Using these annotations aside with expression language linked with Spring ACL allows to access a very powerful securization mechanism (look for more in documentation).
As usual, these annotations can be used at class level and method level, and is in this second scenario where you must be careful. It is very important for you to understand the hierarchy of your repository since there are plenty overloaded methods and, some times, you can end with unexpected situations if you are not aware of this.
For exmple consider the scenario where you try to securize your “get all” endpoint. In this case it is easy to understand that you must work on “findAll” method. However if your repository extends PagingAndSortingRepository there are four different “findAll” method so you must review your repository hierarchy and be sure you are controlling all access points to your data.
0 notes
Text
First Post
Hi there,
This is my first attemp into the blog thingy. As many other developers i'll try to compile here all those information who has been useful to me and take me some time to find, or understand, with the hope that could be useful for others in time or space.
0 notes