How to manually change the Authentication Provider in Spring Security - spring-boot

The authentication provider is set in
#Override
public void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider);
}
Is it possible to change the Authentication Provider during runtime in SpringBoot?

Instance of configured AuthenticationManager eventually will be passed to one of the implementations of org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter. This base filter class has setter for AuthenticationManager so yes, essentially you can replace AuthenticationManager in runtime provided that you have access to the configured authentication filter.
But I doubt that it would be a good idea because you can have several authentication filters where AuthenticationManager should be replaced too. Also Spring does not expect this behavior so finally it can lead to inconsistency in the configuration.
Depending on your needs I would suggest to provide custom implementation of AuthenticationManager that changes its logic accordingly to some conditions.

Related

Spring reactive not in all application

I saw a lot of example of application who use spring reactive. In all of the example, application is never full reactive.
Like this one
https://github.com/venugopr/Misc/tree/master/Spring/Spring-Session
Ui use spring-web-flux, when user need to authenciate, it call gateway.
Login controller look like
#Autowired
AuthenticationManager authenticationManager;
#PostMapping("/authenticate")
public ResponseEntity<LoginResponse> authenticateUser(#Valid #RequestBody LoginRequest loginRequest) {
....
}
AuthenticationManager is not wrote in a reactive way.
Is there any advantage to do this way?
It's surely not full reactive
Not really. To take full advantage of the reactive stack it should be used throughout the complete application, from the REST API down to the database access.
Regarding AuthenticationManager there is the reactive counterpart ReactiveAuthenticationManager (https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/authentication/ReactiveAuthenticationManager.html) which is the one that you should use in a Spring-WebFlux application.

How to handle security.enable-csrf in Spring Boot 2?

I'm migrating an application from Spring Boot 1.5 to 2.0.5.
I have a property set as security.enable-csrf=true in 1.5 version which is not available in 2.0 version of Spring Boot.
I read the documents and it is said that in Spring Boot 2.0:
CSRF protection is enabled by default in the Java configuration.
So by default it is enabled ok fine, but there is also one class created which extends WebSecurityConfigurerAdapter this means Spring Boot default security configuration has been turned off. Is this also means security.enable-csrf is disabled now?
If yes how do I enable it like I had it in the application for 1.5 version.
I didn't get any document which gives a clear confirmation on how to handle security.enable-csrf property in Spring Boot 2.0 and while declaring the WebSecurityConfigurerAdapter.
Does anyone know about it? Also any document link which I have missed to read about this would be great help.
In order to have backward compatibility with the property already been set in you application, security.enable-csrf=true, you can use the following code:
#EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
#Value("${security.enable-csrf}")
private boolean csrfEnabled;
#Override
protected void configure(HttpSecurity http) throws Exception {
if (!csrfEnabled) {
http.csrf().disable();
}
}
}
As you might guess the magic comes from http.csrf().disable(); that
in the above code you can control enabling/disabling it by the
property you have set in you application.properties file.
More Info:
For more details you can also refer to the spring documents:
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf
WebSecurityConfigurerAdapter is an abstract class, when you create a class which extends WebSecurityConfigurerAdapter, you will override void configure(HttpSecurity http) method.
You can disable csrf in this method, like that;
http.csrf().disable();
You can read this comment on top of the csrf() method (in HttpSecurity class).
Adds CSRF support. This is activated by default when using
WebSecurityConfigurerAdapter's default constructor. You can disable it ...."
This comment says that, when you extends this class, default constructor of WebSecurityConfigurerAdapter works and csrf is activated.

Spring Boot 2 http.httpBasic().disable(); not working

I recently upgraded from Spring Boot 1.x to Spring Boot 2.0.3 and I am trying to disable basic auth with no success.
#Configuration
#EnableWebSecurity(debug=true)
#EnableGlobalMethodSecurity(securedEnabled = true)
public class CustomSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.httpBasic().disable();
// the rest of my config
}
}
What hidden gem am I missing to just simply turn off basic auth?
Why does turning things off in Spring need to be so difficult now?
I was reading this:
https://github.com/spring-projects/spring-boot/issues/10306
and I have to agree that it should be much easier and a clearer explanation should be provided on how to turn this off.
EDIT
This link https://spring.io/blog/2017/09/15/security-changes-in-spring-boot-2-0-m4 talks about how the property was removed but doesn't say anything about how to continue to use the configuration as it exists in current application that utilize it.

Spring/Springboot OAuth2 - Integrate custom ClientDetailsUserDetailsService

I have successfully configured my application to support both Basic, form-based and OAuth2 authentication, but ran into a bit of a snag trying to customize the ClientDetailsUserDetailsService in OAuth. The behavior I'm noticing is that the Spring OAuth ClientDetailsUserDetailsService is always being used despite my attempts to inject a new custom implementation.
The reason I want to customize this class is to return a custom User Details object similar to what I use for the Basic Auth and Form authentication.
I've read multiple posts on the site related to this same topic, but was not able to resolve the issue with the suggested approaches (ie: Previous post)
Spring's AuthorizationServerSecurityConfigurer class seems to always use the ClientDetailsUserDetailsService regardless of what you inject.
Thing(s) I've tried:
Create an #Bean referencing my custom user details impl and set the custom user details in the AuthorizationServerEndpointsConfigurer.userDetailsService.
Set the user details in the GlobalAuthenticationConfigurerAdapter
#Configuration
#Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthenticationManagerConfiguration
extends GlobalAuthenticationConfigurerAdapter {
#Autowired
private UserDetailsService userService;
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(clientDetailsUserDetailsService());// Inject custom
}
}
Created a custom WebSecurityConfigurerAdapter and set the user details service in the HttpSecurity object ie:
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/oauth/**")
.requestMatchers().antMatchers("/api-token/**")
.authorizeRequests()
.anyRequest().authenticated();
http.userDetailsService(clientDetailsUserService());
http.authenticationProvider(oauthDaoAuthenticationProvider(encryptionService));
}
Create a new DaoAuthenticationProvider Bean and manually set my custom user details service for oauth requests.
Any advice or help is greatly appreciated and again, I do have OAuth working, but would like to tweak the implementation a bit without having to hack into the Spring classes to achieve it. Thanks!

spring security AuthenticationManager vs AuthenticationProvider?

Can someone tell me the difference between an AuthenticationManager and an AuthenticationProvider in Spring Security?
How are they used and how are they called. It is my understanding that a SecurityFilter will call the AuthenticationManager to authenticate an Authentication object? But then where does the AuthenticationProvider come into play?
Thanks!
I think the AuthenticationManager delegates the fetching of persistent user information to one or more AuthenticationProviders. The authentication-providers (DaoAuthenticationProvider, JaasAuthenticationProvider, LdapAuthenticationProvider, OpenIDAuthenticationProvider for example) specialize in accessing specific user-info repositories.
Something else is mentioned in this part of the reference manual. It says:
You may want to register additional AuthenticationProvider beans with the ProviderManager and you can do this using the element with the ref attribute, where the value of the attribute is the name of the provider bean you want to add.
In other words, you can specify multiple AuthenticationProviders, for example one that looks for users in an LDAP database and another that looks in an SQL database.
Both AuthenticationManager and AuthenticationProvider are interfaces. They have different functionalities in the Spring Security Flow.
Ref-
Spring Boot + Spring Security Architecture
AuthenticationManager - When user tries to access an application, the http request is intercepted by filter/filter chain. Using the Authentication Object created the filter will then call the authenticate method of the Authentication Manager. The Authentication Manager is only a interface and actual implementation of the authenticate method is provided by the ProviderManager.The ProviderManager has a list of AuthenticationProviders. From it's authenticate method it calls the authenticate method of the appropriate AuthenticateProvider. In response it gets the Principal Authentication Object if the authentication is successful.
AuthenticationProvider - The AuthenicationProvider is an interface with an authenticate and a supports method. It has various implementations like CasAuthenticationProvider or DaoAuthenticationProvider. Depending on the implementation an appropriate AuthenicationProvider implementation is used. It is in the AuthenticationProvider implementation authenticate method where all the actual authentication takes place.
From spring reference
The AuthenticationManager is just an interface, so the implementation can be anything we choose
The default implementation in Spring Security is called ProviderManager and rather than handling the authentication request itself, it delegates to a list of configured AuthenticationProvider s, each of which is queried in turn to see if it can perform the authentication. Each provider will either throw an exception or return a fully populated Authentication object.
Also if you check the source code for AuthenticationManager, ProviderManager and AuthenticationProvider you can see this clearly.
ProviderManager implements the AuthenticationManager interface and it has list of AuthenticationProviders. So if you want to have custom authentication mechanism, you'll need to implement new AuthenticationProvider.

Resources