Spring Security request.getUserPrincipal() always null - java

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!

Related

Spring security client PKCE with Keycloak

I have a Java application using Spring Security 5.2.1 and secured by Keycloak.
The client in Keycloak is a public openid-connect client.
It works fine.
I have now a requirement to use PKCE (Proof Key for Code Exchange).
As Client Support for PKCE has been added to Spring Security 5.2.0.M2 and as I use Spring Security 5.2.1, I can use Spring Security to implement it.
That's the good news.
The 'bad' news is that I found nearly nothing on the Web or in the Spring Security documentation on how I must implement it, practically.
Adding "enable-pkce": true in keycloak.json doesn't work, and I don't find any clear example of what to do.
Is there some documentation, website or whatever else, describing what to do to implementsthis ?
Thank you very much !
From the Spring Security reference documentation https://docs.spring.io/spring-security/site/docs/5.3.1.RELEASE/reference/html5/#initiating-the-authorization-request
PKCE will automatically be used when the following conditions are true:
client-secret is omitted (or empty)
client-authentication-method is set to "none" (ClientAuthenticationMethod.NONE)

Spring Boot Actuator Endpoint Override

I have been prototyping with Spring boot where I added dependency on spring-boot-starter-actuator and spring-boot-starter-data-rest and named my testing REST endpoint to /info. Application ran without any errors however my endpoint couldn't be called and app returned 404 all the time.
After some time I found out that actuator project contains SAME endpoint /info and basically overrides my custom RESTful endpoint since I didn't name it.
My question is: Is there any way how I can prevent such behavior in general (meaning bean clashing by mistake)? Or at least get WARN message when this is happening.
Thanks in advance for your answers
You can disable /info actuator endpoint by using the following property;
management.endpoint.info.enabled=false
Actually all can be disabled, or you can enable only certain ones, if you check the source link I've provided below;
By default, all endpoints except for shutdown are enabled. If you prefer to specifically “opt-in” endpoint enablement you can use the endpoints.enabled property.
source
For logging of this behaviour, while deploying you can see the endpoints and corresponding beans, you can deduce from this log I guess. But better not to use same endpoint with actuator while they are enabled.
Yes, there is a chance to disable particular classes by #EnableAutoconfiguration with a parameter exclude= where you can specify classname or whole package by using {} brackets
Example:
#EnableAutoConfiguration(exclude = {MyClassName.class}
#EnableAutoConfiguration(exclude = {MyClassName.class, MyClassName2.class})

How to test if Spring Security is actually enabled?

I'm having trouble getting Spring Security to work in my Spring MVC app. It is configured correctly (I think) and I am fully expecting it to use the configured security filter on all requests. It isn't. My question isn't to make sure I'm configured correctly so I'm not going to post any code, I am only asking if there is a method or something I can call in one of my controllers that will return true or false signifying if Spring Security is actually enabled or not so I can know how to proceed debugging. Thanks!
In your case, you could use spring actuator.
This is module used for application monitoring. You can read more about it, in this blog post: http://www.baeldung.com/spring-boot-actuators

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

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

Spring security #PreAuthorize("hasAnyRole('....')")

I am using spring security #PreAuthorise to check who and who cannot access methods in my service layer. It works really well. Usually my service methods are annotated with
#PreAuthorize("hasAnyRole('MY_USER_ROLE')")
My problem is that I have a war file made up of several jar files. Each of these jar files is responsible for a segment of business logic. I now want one of the services in one jar file to access another service in another jar file. This gets rejected because of the permissions. If I comment out the permission then everything works.
Is there anyway I can authenticate via spring before calling this service? (Perhaps with a dummy user?) Or perhaps turn off the security for jars within the same application? Or is my design wrong?
Anyone else has this sort of problem? What design should I use instead?
You need to give the thread that invokes the service (in the other jar) the permissions that are required by #PreAuthorize (for the invoked service).
If the thread is triggered in an web application by an user request, then this are normally the users permissions.
But if the thread is triggered by some timer service then you need to give them the right authentication
Authentication authentication = new UsernamePasswordAuthenticationToken("dummy", "password");
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
I believe this is a good example where you should use Spring security #Secured annotation
What is #Secured annotation?
From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. It
provides support for JSR-250 annotation security as well as the
framework's original #Secured annotation.
Source: Spring Security 3.1 Reference 2.4 Method Security
#Secured annotation allows you to put restrictions in your methods. For example, you can authorize a get() method to be accessible by all
registered users. But for the edit() method, you can mark it be
accessible by admins only.
Check out some tutorials at:
http://burtbeckwith.com/blog/?p=1398
http://krams915.blogspot.in/2010/12/spring-security-3-mvc-using-secured.html

Categories