spring security AuthenticationManager vs AuthenticationProvider? - spring

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.

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.

Disable #PreAuthorize when using the function in a specific context

I'm migrating an application with custom rest controllers to spring data rest. One problem I'm facing is that I had to add #PreAuthrozie annotations directly to my repositories instead of having them at a controller level. This is fine except some special cases.
The whole user repository is protected by a USER_ACCESS privilege. When the user authenticates, a new token is generated and the user has to be saved. Problem is, at this point there is no authentication in the Security Context so the request returns with 403
I have some code that on startup has all classes implementing PermissionProvider and saves new permissions to the database. Again, at this point there is no authentication in the Security Context so this fails since the repository is protected by PERMISSION_ACCESS privilege
I can manually create a tmp authentication that I set before the call then clear the context but this seems like a hack and can be problematic. Is there a way to disable #PreAuthorize in some context?
The only way you can work around this is to in cases 1. and 2. call another method in the repository that is not annotated with #PreAuthorize. This method would then call the methods annotated with #PreAuthorize. Since they are in the same class, #PreAuthorize has no effect. The reason being the way Spring AOP and CGLIB work. A proxy class is created that extends your class, providing the logic behind the #PreAuthorize behavior. When you call a method within the same class, such a call does not go through the proxy class, and as a consequence #PreAuthorize has no effect.

Spring Boot get Authentication Principal

I'm using Spring Boot Parent version 1.5.16.
I need to use current user information and now I use #AuthenticationPrincipal annotation.
But I have to write this annotation for each method. I think this is not a best practice because I have more than 200+ methods. Is there any other suggestion to inject Authentication Principal globally or class level?

How to manually change the Authentication Provider in Spring Security

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.

spring security quick start

I am trying to follow this to incorporate spring security in the framework
http://java.dzone.com/tips/pathway-acegi-spring-security-
i hope to make a basic form based authentication, so i think this would be a great pointer.
if i am using the spring security 3 libraries, would there be any different?
which file is the authentication-manager xml would suppose to be in?
Some time ago I've done a migration from Acegi Security to Spring Security, and I should say that it went pretty smooth, without any significant issues. So I assume that this libraries (in fact Spring Security is a latter version of Acegi) have not too much differences.
You could include you AuthenticationProvider implementation or any configuration related to a security any context configuration file. However, it's generally preferable to keep in separate Spring XML config file, which name is passed as a parameter along with name of main config file when you are creating ApplicationContext instance.
Suppose you have class MyAuthenticationProvider :
...
import org.springframework.security.providers.AuthenticationProvider;
...
public final class MyAuthenticationProvider implements AuthenticationProvider {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
...
}
}
This class is a regular Spring bean and therefore you can inject there any other bean you need, particularly DAO object which works with 'Users' table. Inside authenticate method you recieve partially initialized Authentication object. It's supposed to contain username and password. Here you could compare user credentials against database records.
also trying this one and succeed. this one is more complete with the included file
http://static.springsource.org/spring-security/site/petclinic-tutorial.html

Resources