将多个 spring 安全身份验证提供程序组合成一个自定义的单一身份验证提供程序

Combining multiple spring security authentication providers into custom single one

我的目标是使用凭据进行两步验证。第一步是检查具有主体的用户是否在特殊数据库 table 中具有角色。其次是执行标准的 ldap 身份验证。

我需要的是一起执行 both 检查,但身份验证提供者的常见方法是在 any[=30 首次成功后声明身份验证成功=] 身份验证提供程序。所以我决定创建一个自定义的 AuthenticationProvider 实现,它调用 LdapAuthenticationProvider 然后执行数据库检查逻辑,但它不起作用,因为没有任何东西可以与 AbstractLdapAuthenticationProvider 自动装配。

请告诉我是否

  1. 解决此类问题的方法是理性的
  2. 如果是合理的,我该如何注入AbstractLdapAuthenticationProvider?

安全配置代码是

@Autowired
private DBRoleAuthenticationProvider dbRoleAuthenticationProvider;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.ldapAuthentication()
            .contextSource()
            .url("...")
            .managerDn("...")
            .managerPassword("...")
            .and()
            .userSearchFilter("uid={0}");
    auth.authenticationProvider(dbRoleAuthenticationProvider);
}

自定义身份验证提供程序是

@Component
public class DBRoleAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserHasRoleInDBService userHasRoleInDBService;

    @Autowired
    private AbstractLdapAuthenticationProvider ldapAuthenticationProvider;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        authentication = ldapAuthenticationProvider.authenticate(authentication);
        if (!authentication.isAuthenticated()) {
            return authentication;
        }
        try {
            String loginToSearch = (String) authentication.getPrincipal();
            if (!userHasRoleInDBService.userHasRole(loginToSearch)) {
                authentication.setAuthenticated(false);
            }
        } catch (Exception e) {
            authentication.setAuthenticated(false);
        }
        return authentication;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

提前致谢!

看起来像auth.authenticationProvider(dbRoleAuthenticationProvider); 正在击败 auth.ldapAuthentication()

您应该通过查看文档自定义为经过身份验证的用户检索权限的方式 userDetailsContextMapper(UserDetailsContextMapper userDetailsContextMapper) and ldapAuthoritiesPopulator(LdapAuthoritiesPopulator ldapAuthoritiesPopulator) LdapAuthenticationProviderConfigurer 的