Is there a way to have ConcurrentSessionControlStrategy.alwaysCreateSession in Spring Security 4? - java

We are migrating our application from SpringSecurity 3 to 4. We have our ConcurrentSessionControlStrategy bean configured to always create session (Grails notation to define beans)
sessionRegistry(SessionRegistryImpl)
sessionAuthenticationStrategy(ConcurrentSessionControlStrategy, sessionRegistry) {
alwaysCreateSession = true
}
because we are using HTTP requests with basic authentication from Excel and other apps to interact with application and without that option, session is not created and authentication has to be done for every action instead of once for first action.
In Spring Security 4 ConcurrentSessionControlStrategy was migrated to ConcurrentSessionControlStrategy (according to migration guide - http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-xml.html ) which should be used inside of CompositeSessionAuthenticationStrategy but we cannot find a way to setup session strategy.
The workaround we currently have is to call non-basic authenticated page before authentication, what causes session to be created and following requests will be executed against this session

Comment from M. Deinum pointed me into another direction and I have found that in spring-security-core plugin of Grails securityContextPersistenceFilter is defined with forceEagerSessionCreation = false. Overriding this bean to force eager session creation did the trick
securityContextPersistenceFilter(SecurityContextPersistenceFilter, ref('securityContextRepository')) {
forceEagerSessionCreation = true
}
This probably can also be done using configuration of Grails Spring Security Core
Source code is available here:
https://github.com/grails-plugins/grails-spring-security-core/blob/master/src/main/groovy/grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.groovy

Related

Is required SecurityContextHolder in JWT Authentication App?

I'm developing application in Spring Boot and I need jwt authentication there. I decide to use that github project, but when I'm looking at code I don't understand sense of SecurityContextHolder.
Here are 2 classes which are using it:
AuthenticationRestController.java
JwtAuthenticationTokenFilter.java
Can you tell me what is purpose of SecurityContextHolder? I want stateless authentication without session. So I just need generate jwt and next check it before requests.
This git project also has disable session:
...
httpSeccurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
...
I've tried delete code with SecurityContextHolder and applicatin still works fine.
Thanks for answers.
Here is a quote from Learning Spring 5.0:
One major aspect of security is storing the information of the principal currently used by the application. It is held by the security context of the application. SecurityContextHolder is the most important object of the framework as it stores the details about security context in ThreadLocal. It means the security context will be available to the methods that are executed in the same thread. However, in a few circumstances, all the threads in the application may need to use other strategies for using the security context. The framework provides two ways to change the default nature of using ThreadLocal. The developers can either set the system property or they can invoke the static method on SecurityContextHolder.
The reason your application still works after deleting code with SecurityContextHolder is that by using the SessionCreationPolicy.STATELESS creation policy you request Spring Security to not create an HTTP session and not store logged in user’s SecurityContext in the session.
When to use SessionCreationPolicy.STATELESS
to stop creating sessions during the entire lifespan of the application
to stop using sessions during the entire lifespan of the application

Spring Security request.getUserPrincipal() always null

A really strange situation is observed in our application (Spring Boot 1.5.6 with all-default BOM dependencies): you can perfectly log in (with AbstractPreAuthenticatedProcessingFilter), but this still leaves Principal in request null! I.e. request.getUserPrincipal() is null while SecurityContextHolder.getContext().getAuthentication() is not!
This in turn affects the ability of our health endpoint to be sensitive: it uses Principal (see HealthMvcEndpoint.exposeHealthDetails(HttpServletRequest, Principal)) which is injected by ServletRequestMethodArgumentResolver, which in turn takes it from the request...
Looks like I'm missing something simple, but still can't find it :(
So, after creating a new Spring Boot application and debugging it to its guts, I've found out that nobody actually sets Principal into the request. It's Spring who wraps it into another one that uses Spring's SecurityContext for the above (and some other methods). And this wrapping is done by the SecurityContextHolderAwareRequestFilter, which is there by default (see HttpSecurity.servletApi())...
But somebody has disabled the default Spring Security configuration for our project, so the filter was not there!

Hibernate+Spring - configure session before use

I have a Spring Boot application with JPA/Hibernate. I would like to have an extra operation executed each and every time the session is created - namely Session.setCacheMode.
I do not want to do it on all public entry points to my app, so a new annotation with AOP interceptor doesn't seem like a good idea. Just do it once for the entire application and forget.
With this stack, how can I get access to the Session and do something with it before it's handed to the application? Does Spring or Hibernate expose a hook where I could add my callback/interceptor/listener?

Why and when use dynamic servlet registration?

I'm investigating a Spring Boot project generated by JHipster and found out that its request mappings aren't done via web.xml nor via Spring's #RequestMapping but like so:
ServletRegistration.Dynamic someServlet =
servletContext.addServlet("someServlet", new SomeServlet());
someServlet.addMapping("/someUrl");
someServlet.setAsyncSupported(true);
My questions are:
Are there any reasonable advantages of dynamic registration instead of classic mapping?
Is it spring-boot's standard of registering mappings or it's just a will of jhipster's owner?
Is someServlet.setAsyncSupported(true) just another way of making response.setHeader("Access-Control-Allow-Origin", "*")?
Is there any reasonable advantages of dynamic registration instead of classic mapping?
Dynamic servlet registration Servlet 3+ way of registering servlets. In Servlets 3 you can avoid creating web.xml and configure application in pure Java. It gives you some advantages like compile time check if everything is fine there and what's more important since you do it in Java code, you can do some additional checks or conditions - for example register particular servlet only if environment property is set or class is available on the classpath.
It's not a replacement for #RequestMapping. In case of Spring Boot you will use it most probably when you want to register some 3rd party servlet - like Dropwizard Metrics servlet in case of JHipster.
Is it spring-boot's standard of registering mappings or it's just a will of jhipster's owner?
There are at least 2 ways of registering additional servlets in Spring Boot. See answers here: How can I register a secondary servlet with Spring Boot?.
Your own controllers you map as usual with #RequestMapping.
Is someServlet.setAsyncSupported(true) just another way of making response.setHeader("Access-Control-Allow-Origin", "*")?
Nope. For setting this header you use usually CORSFilter (read more: Enabling Cross Origin Requests for a RESTful Web Service). asyncSupported flag is used to make servlet able to process request asynchronously.

What's the scope of Spring Controllers? It's possible to configure it?

While experiencing weird behavior in a web application, I've found that its sessions was being invalidated and recreated everytime HttpSession session = request.getSession(); was being executed. It was occouring specially while application calls a Spring controller built in another servlet.
As shown in the HttpSession javadoc, sessions are ServletContext. So, I ask: Spring controllers are implemented in different servlet scopes? Or just when a controller is implemented in a different servlet? Can we set Spring to maintain a single scope? Thanks!
Edit:
Adding information: I have a tip that the issue is due to I'm importing header and footer into the page. It's 90% certain that are those elements which are being processed in a different session by Spring, but I don't know how to correct this behaviour (yet).
session, request and response objects are not created by spring. Only the Controllers are created by spring and they are singletons by default (spring application context singletons, not JVM singletons).
So I would guess that your problem of session invalidation is happening outside of spring.

Categories