我的应用程序有一个安全配置,可通过验证用户身份LDAP。效果很好,但现在我想添加另一个AuthenticationProvider,对尝试进行身份验证的用户进行更多检查。因此,我尝试添加一个DbAuthenticationProvider(出于测试目的)始终拒绝访问。因此,当我尝试使用我的域帐户(适用于activeDirectoryLdapAuthenticationProvider)登录时,由于第二个提供程序的身份验证失败,因此无法访问该页面。
LDAP
AuthenticationProvider
DbAuthenticationProvider
activeDirectoryLdapAuthenticationProvider
为了实现此目标,我使用了以下代码:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Value("${ad.domain}") private String AD_DOMAIN; @Value("${ad.url}") private String AD_URL; @Autowired UserRoleComponent userRoleComponent; @Autowired DbAuthenticationProvider dbAuthenticationProvider; private final Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class); @Override protected void configure(HttpSecurity http) throws Exception { this.logger.info("Verify logging level"); http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin() .successHandler(new CustomAuthenticationSuccessHandler()).and().httpBasic().and().logout() .logoutUrl("/logout").invalidateHttpSession(true).deleteCookies("JSESSIONID"); http.formLogin().defaultSuccessUrl("/", true); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()); auth.authenticationProvider(dbAuthenticationProvider); } @Bean public AuthenticationManager authenticationManager() { return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider(), dbAuthenticationProvider)); } @Bean public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() { ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(AD_DOMAIN, AD_URL); provider.setConvertSubErrorCodesToExceptions(true); provider.setUseAuthenticationRequestCredentials(true); return provider; } }
这是我的DbAuthenticationProvider:
@Component public class DbAuthenticationProvider implements AuthenticationProvider { Logger logger = LoggerFactory.getLogger(DbAuthenticationProvider.class); @Override public Authentication authenticate(Authentication auth) throws AuthenticationException { auth.setAuthenticated(false); this.logger.info("Got initialized"); return auth; } @Override public boolean supports(Class<?> authentication) { return true; } }
可悲的是,我能够登录(访问没有像我预期的那样被拒绝)。我错过了什么吗?
Spring不会使用多个AuthenticationProvider身份验证请求,因此第一个(支持中的ArrayList)AuthenticationProvider支持Authentication对象并成功身份验证请求的将是唯一使用的对象。在你的情况是activeDirectoryLdapAuthenticationProvider。
ArrayList
Authentication
ActiveDirectoryLdapAuthenticationProvider可以使用自定义AuthenticationProvider委托给LDAP并进行其他检查,而不是使用:
ActiveDirectoryLdapAuthenticationProvider
CustomerAuthenticationProvider implements AuthenticationProvider{ privtae ActiveDirectoryLdapAuthenticationProvider delegate; // add additional methods to initialize delegate during your configuration @Override public Authentication authenticate(Authentication auth) throws AuthenticationException { Authentication authentication= delegate.authenticate(auth); additionalChecks(authentication); return auth; } @Override public boolean supports(Class<?> authentication) { return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); } public void additionalCheck(Authentication authentication){ // throw AuthenticationException when it's not allowed } }