Home > Back-end >  Spring security Expose Multiple Authentication Managers without WebSecurityConfigurerAdapter
Spring security Expose Multiple Authentication Managers without WebSecurityConfigurerAdapter

Time:09-01

Now that WebSecurityConfigurerAdapter has been deprecated I am trying to update my code to use the new ways to set up authentication based off : https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

I currently use ldap authentication as well as in memory authentication. In my app I need to expose the AuthenticationManagers as beans for each. My old code this was done aby creating two separate WebSecurityConfigurerAdapter:

@Configuration
@Order(1)
public class APIWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
            .inMemoryAuthentication()
            .withUser(ApiRolesUsers.API_VIEW_ALL).password("{noop}"   apiKeyStore.getKeyByUserName(ApiRolesUsers.API_VIEW_ALL)).roles(ApiRolesUsers.API_VIEW_ALL)
            .and()
            .withUser(ApiRolesUsers.API_UPDATE_ALL).password("{noop}"   apiKeyStore.getKeyByUserName(ApiRolesUsers.API_UPDATE_ALL)).roles(ApiRolesUsers.API_UPDATE_ALL)
            .and()
            .withUser(ApiRolesUsers.API_EDL_UPDATE).password("{noop}"   apiKeyStore.getKeyByUserName(ApiRolesUsers.API_EDL_UPDATE)).roles(ApiRolesUsers.API_EDL_UPDATE);
        }
...
        @Bean( name = "apiAuthenticationManager")
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
...
}

and

    @Configuration
    @Order(2)
    public class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Autowired
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
            .ldapAuthentication()
            .userSearchBase(ldapUserSearchBase)
            .userSearchFilter(ldapUserSearchFilter)
            .groupSearchBase(ldapGroupSearchBase)
            .contextSource(ldapContextSource);
...
        @Bean( name = "authenticationManager")
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
...
}

From there I could then autowire both "authenticationManager" and "apiAuthenticationManager". I am able to recreate the "authenticationManager" part without WebSecurityConfigurerAdapter in the new format with:

    @Bean(name = "authenticationManager")
    AuthenticationManager ldapAuthenticationManager(
            LdapContextSource contextSource) {
        LdapBindAuthenticationManagerFactory factory = 
                new LdapBindAuthenticationManagerFactory(contextSource);
        factory.setUserSearchBase(ldapUserSearchBase);
        factory.setUserSearchFilter(ldapUserSearchFilter);
        return factory.createAuthenticationManager();
    }

Based off new spring documentation I am able to create the in memory part with:

    //How do I expose AuthenticationManager for this???
    public InMemoryUserDetailsManager inMemoryUserDetailsManager(AuthenticationConfiguration providerManager) {
        
        UserDetails apiViewAll = User.builder()
                .username(ApiRolesUsers.API_VIEW_ALL)
                .password("{noop}"   apiKeyStore.getKeyByUserName(ApiRolesUsers.API_VIEW_ALL))
                .roles(ApiRolesUsers.API_VIEW_ALL)
                .build();

        UserDetails updateAll = User.builder()
                .username(ApiRolesUsers.API_UPDATE_ALL)
                .password("{noop}"   apiKeyStore.getKeyByUserName(ApiRolesUsers.API_UPDATE_ALL))
                .roles(ApiRolesUsers.API_UPDATE_ALL)
                .build();

        UserDetails edlUpdate = User.builder()
                .username(ApiRolesUsers.API_EDL_UPDATE)
                .password("{noop}"   apiKeyStore.getKeyByUserName(ApiRolesUsers.API_EDL_UPDATE))
                .roles(ApiRolesUsers.API_EDL_UPDATE)
                .build();
        
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(apiViewAll, updateAll, edlUpdate);
        
        return manager;
    }

In the above I need to expose the related AuthenticationManager that WebSecurityConfigurerAdapter was able to do before they deprecated it. Doing something like this only returns the ldap authentication...

@Bean(name = "apiAuthenticationManager") {
public AuthenticationManager authenticationManager(AuthenticationConfiguration 
     authenticationConfiguration) throws Exception {
     return authenticationConfiguration.getAuthenticationManager();
}

Does anyone know how I can implement and expose both AuthenticationManagers without the use of WebSecurityConfigurerAdapter

CodePudding user response:

You can construct the AuthenticationManager yourself, for example:

@Bean
AuthenticationManager apiAuthenticationManager(InMemoryUserDetailsManager users) {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(users);
    return new ProviderManager(provider);
}
  • Related