有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring Security可以为同一用户接受多个密码吗?

我在我的应用程序中使用Spring安全机制,用一个密码对用户进行身份验证。我试图满足一个要求,即覆盖密码也将对同一用户进行身份验证

如何使用Spring Security实现这一点


共 (3) 个答案

  1. # 1 楼答案

    通过提供多个带有“UserDetailsService”的“AuthenticationProvider”,很容易做到这一点

    private DaoAuthenticationProvider userAuthProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setHideUserNotFoundExceptions(false);    
        provider.setPasswordEncoder(passwordEncoder);
        provider.setUserDetailsService(userDetailsService);
        return provider;
    }
    
    private DaoAuthenticationProvider superVisorAuthProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setHideUserNotFoundExceptions(false);
        provider.setUserDetailsService(supervisorDetailService);
        return provider;
    }
    

    然后

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(userAuthProvider());
        auth.authenticationProvider(superVisorAuthProvider());
    }
    
  2. # 2 楼答案

    如前所述,您可以覆盖“additionalAuthenticationChecks” 希望这能帮助别人

    @Slf4j
    @Service
    class FlexibleAuthenticationProvider extends DaoAuthenticationProvider implements AuthenticationProvider {
    
        @Autowired
        UserDetailsService userDetailsService
    
        @Autowired
        PasswordEncoder passwordEncoder
    
        @PostConstruct
        def init() {
            super.setPasswordEncoder(passwordEncoder)
            super.setUserDetailsService(userDetailsService)
        }
    
        @Override
        protected void additionalAuthenticationChecks(
                UserDetails userDetails,
                UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
            try {
                super.additionalAuthenticationChecks(userDetails, authentication)
            } catch (AuthenticationException e) {
                log.error('Unable to authenticate with regular credentials')
               
                try {
                    def mutableUserDetails = new MutableUser(userDetails)
                    mutableUserDetails.password = 'alternatepassword'
                    return super.additionalAuthenticationChecks(mutableUserDetails, authentication)
                } catch (AuthenticationException err) {
                    log.error('Token based authentication failed')
                }
                
                throw e
            }
        }
        
        static class MutableUser implements UserDetails {
    
            private String password
            private final UserDetails delegate
    
            MutableUser(UserDetails user) {
                this.delegate = user
                this.password = user.password
            }
    
            String getPassword() {
                return password
            }
    
            void setPassword(String password) {
                this.password = password
            }
    
            ....
    
        }
    
    
    }
    
    
    
    
    
    
    
    @Configuration
    class AuthWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        FlexibleAuthenticationProvider flexibleAuthenticationProvider
    
        ....
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(flexibleAuthenticationProvider)
        }
    
        ....
    
    }
    
  3. # 3 楼答案

    您可能需要通过扩展现有的DaoAuthenticationProvider来实现自己的AuthenticationProvider(请参见其中的additionalAuthenticationChecks()
    此外,默认情况下,用户只与一个密码关联(UserDetails.getPassword()),因此您需要该类的一个包含多个密码的扩展,以及UserDetailsService的相应实现,该实现知道如何加载用户及其密码