Spring Security what is the difference between Authorization Manager and AccessDecisionManager? - spring-security

Spring Security what is the difference between Authorization Manager and AccessDecisionManager, and how do they interact with each other?

The AuthorizationManager, from Spring Security documentation:
AuthorizationManager supersedes both AccessDecisionManager and AccessDecisionVoter.
Applications that customize an AccessDecisionManager or AccessDecisionVoter are encouraged to change to using AuthorizationManager.
AuthorizationManagers are called by the AuthorizationFilter and are responsible for making final access control decisions.
The deprecated AccessDecisionManager, from Spring Security documentation:
The AccessDecisionManager is called by the AbstractSecurityInterceptor and is responsible for making final access control decisions.
In summary, the AuthorizationManager is a new API that supersedes the AccessDecisionManager. If you are using authorizeHttpRequests instead of authorizeRequest, you are already using the AuthorizationManager API.

Related

Java Spring Application - Integration with Azure AD for SSO

I have a Java Spring MVC application (note that its not spring boot).
We have a requirement to implement SSO for the users of our application. I did some research, the identity provider (IDP) in our case is Azure AD. The service provider would be my application in this case. I am thinking of using SAML protocol for SSO.
Also note - The application is http based (not HTTPS)
What I've done so far -
I've created an Enterprise Application on Azure and configured entityId and replyURL. I also added a user for this application.
Where I'm stuck -
Although I did read the related Spring documentation to achieve this, since I'm a newbie here, I still don't have a clear path as to how can I take this forward in my application. I found some solutions, they seem to be examples for spring boot. Can someone please help me with guides as to how this can be done in Java Spring? Which maven dependency I could use and any sample example to start working with SAML? A step by step explanation would be highly appreciated, thankyou.
Also, any other options than SAML would also be fine.
The Spring Security SAML extension (https://docs.spring.io/spring-security-saml/docs/1.0.0.RELEASE/reference/html/index.html) had an example web app. You may read the referenced doc and apply it to Spring Security SAML. It should not be too much difference.
I’m very glad to register the flow in the event of implementing Azure AD B2C OIDC/OAuth protocol with existing Spring MVC architecture.
Below Spring docs reveal that how was our existing project's spring-security layer being served in the context of filter-chain.
Pre-requisites
Authentication Filter - Form Based Login with Legacy IDP
Authentication Manager – Providing the user details authorities along with http session object
For accomplishing this Azure B2C Integration, we've gone thro' lot of repos but most of them are relying with Java config based but we were interested on Spring namespace with limited code/architectural change.
Then finally we came to the conclusion that how to extend the spring default auth-filter/manager for getting valid session object from security context based on the Azure provided (id/access) token after the successful user authentication.
Customizing Spring-Security
The detailed documentation on how to extend auth-filter/manager is available here with © reserved by terasoluna.org
We customized the spring security in such a manner that auth-filter will carry the token_validation against the given token from Azure and authentication manager will extract user details such as roles/privileges w.r.t to the object-id mapped in our DB's user entity.
Once the Spring security customization is done then we can able to integrate the Authorization-server [Azure in our case] and Resource-server [Existing Spring Application] by following the conventional methods.

What is the benefit of UserDetailsService provided by the Spring security

I am using spring security in my project and I do aware that the provided interface UserDetailsService is just like the normal interfaces we wrote, but I want to know is there any special purpose behind that the Spring people provide this interface containing single method?
What I observed that, we pass the Implementation class to the method userDetailsService() of AuthenticationBuilderManager, so we do not need to bother to invoke service explicitly in the controller.
Apart from this is there any other benefits ?
The UserDetailsService interface is used by DaoAuthenticationProvider for retrieving a username, password, and other attributes for authenticating with a username and password. The benefit of having a core interface for that is that users can define their own way to retrieve the UserDetails, and Spring Security just needs a #Bean of that type.
For example:
#Bean
UserDetailsService customUserDetailsService() {
return new FileSystemUserDetailsService();
}
Spring Security does not need to be aware that you are loading users from the OS file system since all it requires is that you provide a #Bean of the UserDetailsService type. This way it simplifies support for new data-access strategies.
There are more details in the Spring Security docs.

Can session scope beans be used with Spring Session and GemFire?

Can "session" scope beans be used with Spring Session and Pivotal GemFire?
When using Spring Session for "session" scope beans, Spring creates an extra HttpSession for this bean. Is this an existing issue?
What is the solution for this?
Regarding...
Can session scoped beans be used with Spring Session and GemFire?
Yes!
In fact, it does not matter which underlying "provider" is used with Spring Session either. For example, either Spring Session with GemFire/Geode (docs) or Spring Session with Redis (docs), etc, can be used and it will work just the same (in the same way).
As for...
If using Spring Session for session scoped beans Spring creates extra HttpSession for this bean, is this an existing issue?
Well, this is not exactly true.
You have to understand the underlying technologies in play here and how they all work together, including Spring Session, the Spring Framework, the Servlet Framework, your Web container (e.g. Tomcat), which is bound by the contract specified in the Java EE Servlet spec, and any other technologies you may have applied (e.g. Spring Security's Web support).
If we dive deep into Spring's architecture/infrastructure, you will begin to understand how it works, why it works and why your particular statement ("Spring creates an extra HttpSession for this bean") is not correct.
First, Spring Session registers an all important Servlet Filter, the o.s.session.web.http.SessionRepositoryFilter.
There are many different ways to do this, and the Javadoc for javax.servlet.Filter essentially hints that this is done via the Web Application "deployment descriptor".
Of course, given our menagerie of configuration options today, a Web Application deployment descriptor is pretty loosely defined, but we commonly know this to mean web.xml. However, that is not the only way in which we can configure, essentially, the Web Application's ServletContext.
Spring supports both web.xml based deployment descriptors as well as JavaConfig using the Servlet (3.0+) API.
In web.xml you would register (for example) the Spring Frameworks' o.s.web.filter.DelegatingFilterProxy, that delegates to an actual javax.servlet.Filter implementation (when Spring Session is in play, that would be the o.s.session.web.http.SessionRepositoryFilter, of course) which is also declared/defined as a "bean" (first this, then this) in the Spring container. This is necessary in order to auto-wire (inject) the appropriate Spring Session o.s.session.SessionRepository implementation (also a Spring managed bean defined in the container, e.g. for Redis) that knows how to delegate (HTTP) Session state management to the underlying "provider".
In the JavaConfig approach, the registration is performed via the core Spring Framework's o.s.web.WebApplicationInitializer concept. Read the Javadoc for more details.
Well, Spring Session provides such a WebApplicationInitializer to initialize (HTTP) Session management, the o.s.session.web.context.AbstractHttpSessionApplicationInitializer. Typically, when using Spring's Java-based Container Configuration and/or Annotation configuration approach, a developer would create a class that extends this Spring Session provided class and register the necessary configuration (e.g. connection criteria) for the underlying Session management provider; for example (see also this). The Config class is annotated with #EnableRedisHttpSession which imports the Spring #Configuration class that declares/defines the appropriate Spring Session SessionRepository implementation for the "provider" (e.g. again Redis), which is needed by the Servlet Filter (again SessionRepositoryFilter).
If you look at what the Spring Session AbstractHttpSessionApplicationInitializer does, you will see that it registers the Spring Session, SessionRepositoryFilter, indirectly via Spring Framework's DelegatingFilterProxy... from insert, then here, then here and finally, here.
As you can see, the Spring Session SessionRepositoryFilter is positioned first in the chain of Servlet Filters. The !insertBeforeOtherFilters is negated since the parameter in javax.servlet.FilterRegistration.Dynamic.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns...) is "isMatchAfter".
This is essential, since the Spring Session's o.s.session.web.http.SessionRepositoryFilter replaces both of the javax.servlet.http.HttpServletRequest and javax.servlet.http.HttpServletResponse. Specifically, by replacing the javax.servlet.http.HttpServletRequest, Spring Session can provide an implementation of javax.servlet.http.HttpSession (when HttpServletRequest.getSession(..) is called) that is backed by Spring Session and the provider of the developer's choice (e.g. Redis, GemFire), the whole purpose of Spring Session in the first place.
So, the Servlet Filters see the HTTP request/response before any framework code (e.g. Spring Framework's session scoped bean infrastructure), and especially before any of the Web Application's Controllers or Servlets, get to see the HTTP request/response.
So, when the core Spring Framework's session scoped bean infrastructure sees the (HTTP) Servlet request/response, it sees what Spring Session handed it, which is just an implementation the regular javax.servlet interfaces (e.g. HttpSession) backed by Spring Session.
Looking at the core Spring Framework's o.s.web.context.request.SessionScope "custom" implementation (which handles bean references/bean lifecycles for session scoped beans declared/defined in the Spring container), which extends o.s.web.context.request.AbstractRequestAttributesScope, you see that it just delegates to the o.s.web.context.request.SessionRequestAttributes class. This class is created primarily by Spring's DispatcherServlet, and defines all of its operations (e.g. setAttribute(name, value, scope)) in terms of the "provided" scope defined by the bean (definition) in question. See the source for more details. So the bean gets added to the appropriate HTTP session.
Sure, Spring "will" create a new javax.servlet.http.HttpSession on the first HTTP request, but not without Spring Session's infrastructure knowing about it, since what Spring is using in this case is an implementation of javax.servlet.http.HttpSession backed by Spring Session's "Session".
Also, getSession(true) is also just an indication that the HttpSession is "allowed" to be created if it does not already exist! A Servlet container simply does not keep creating new HTTP sessions for every HTTP request, so long as the session ID can be determined from the HTTP request (which is done via either URL injection... jsessionid or with a cookie, typically). See the javax.servlet.HttpServletRequest.getSession(boolean) for more details.
Anyway, the only other caveat to this entire story is, you need to make sure, especially for GemFire, that...
The Spring "session" scoped beans defined in the container are serializable, either using Java Serialization, or 1 of GemFire's serialization strategies. This includes whatever the bean references (other beans, object types, etc) unless those "references" are declared transient. NOTE: I am not entirely certain GemFire Reflection-based PDX serialization approach is entirely "aware" of "transient" fields. Be conscious of this.
You must make certain that the classes serialized in the session are on the GemFire Servers classpath.
I am working on a configuration option for Spring Session Data Geode/GemFire at the moment to support PDX, but that is not available yet.
Anyway, I hope this helps clear up the muddy waters a bit. I know it is a lot to digest, but it all should work as the user expects.
I will also add that I have not tested this either. However, after reviewing the code, I am pretty certain this should work.
I have made it a task to add tests and samples to cover this situation in the near future.
Cheers!
-John

Spring Session Rest and AuthenticationManager

From the Spring Session Rest sample: http://docs.spring.io/spring-session/docs/current/reference/html5/guides/rest.html
I have deployed the sample on Cloud Foundry and it works.
I am wondering how the session is working with Spring Security AuthenticationManager to authenticate the x-auth-token in the second request.
I checked the code in the Spring Session, but not found any details.
To my understanding, the authentication manager will look for the session in the SessionRepository by the x-auth-token.
Can someone show me how the authentication in the Spring Session Rest works?
Actually as far as Spring Security is concerned there's nothing different in this sample compared to an application that doesn't use Spring Session (i.e. uses Servlet container's internal session storage and JSESSIONID cookie).
Spring Session uses org.springframework.session.web.http.SessionRepositoryFilter to replace Servlet container's HttpSession implementation with a custom implementation backed by Spring Session. This filter also provides HttpSessionStrategy (either cookie based or, like in your sample, HTTP request header based) to correlate the information your provided (again, either via cookie or header) to the session stored in SessionRepository implementation of your choice. After that, it's all up to how your application uses the session.
Note that Spring Security's AuthenticationManager simply handles authentication requests for the provided Authentication token. It does not have any knowledge of session, or anything else web/Servlet API related.

Authorization using Spring-Security (or) Spring only

I have question related to authorization and spring security. To implement authorization checks in one of my services (under a Service Oriented Architecture environment), I was trying to see if I can use Spring-Security. While going through the Spring Security documentation, I read here that spring security uses spring's AOP internally.
Ref: You can elect to perform method authorization using AspectJ or Spring AOP, or you can elect to perform web request authorization using filters. You can use zero, one, two or three of these approaches together. The mainstream usage pattern is to perform some web request authorization, coupled with some Spring AOP method invocation authorization on the services layer.
We are already using Spring AOP in our service implementations. In my case, the requests that will be coming to my RESTful service will carry a custom built token object that should be processed to perform authorization checks.
Based on this, I would like to understand if I can simply use Spring and create an Aspect to catch an inbound request, extract and process the associated (custom built) token and continue/reject the request based on the result ? Do I need spring-security, given that the communication channel is already secured using HTTPS ?
Thanks,
SGSI
For a similar situation we did the following a long time back:
Used an HTTP filter to extract a token from HTTP headers for each request.
Stored the extracted header to thread context.
Added an aspect around service method calls to check the thread context for the token.
This strategy worked well for us. For last many years I have been using Spring Security since it has a more tested and comprehensive implementation for such problems.
If you wish to write your own token-passing implementation, you can check the source code for the Spring Security class SecurityContextHolder that provides multiple ways of passing security information on the execution thread.

Resources