Spring Security:如何将Active Directory用户映射到应用程序用户?

时间:2014-12-15 08:54:50

标签: java spring spring-security active-directory

我在现有的Spring网络应用中集成了Active Directory身份验证。

目前用户详细信息存储在数据库表中,我实现了自定义UserDetailsService来验证用户。

在几个教程之后,我在我的应用程序中通过ActiveDirectoryLdapAuthenticationProvider实现了Active Directory支持,它基本上可以工作,但我需要更具体的东西。

不是将AD组映射到应用程序角色,而是我需要将AD用户映射到我的Web应用程序中的现有用户。换句话说,我想只为我的Users表中的用户启用AD身份验证。 用户可以通过AD凭证访问仅在已在应用程序DB中注册。

每个用户的授权信息都存储在DB中。这样,每个用户都可以通过DB用户+密码或通过AD进行身份验证。

使用Spring Security可以实现这一目标吗?如何?

注意我使用的是Spring v 3.2.9和Spring Security v 3.2.3

2 个答案:

答案 0 :(得分:2)

作为一种解决方法,我实施了自定义AuthenticationProvider和自定义UserDetailsContextMapper

Becouse ActiveDirectoryLdapAuthenticationProvider是一个final课,我通过这种方式实现ADCustomAuthenticationProvider合成:

public class ADCustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private ActiveDirectoryLdapAuthenticationProvider adAuthProvider;
    @Autowired
    private UserDao uDao;

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        String principal = authentication.getPrincipal().toString();
        String username = principal.split("@")[0];
        User utente = uDao.findByUsername(username);
        if (utente == null) {
            throw new ADUnregisteredUserAuthenticationException("user ["
                    + principal + "] is not registered");
        }
        return adAuthProvider.authenticate(authentication);
    }

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

}

在映射器中,我扩展了LdapUserDetailsMapper仅实现mapUserFromContext方法。

public class ADCustomUserDetailsContextMapper extends LdapUserDetailsMapper {

    @Autowired
    private UserDetailsService userDetailsService; // ... the service used for DB authentication

    @Override
    public UserDetails mapUserFromContext(DirContextOperations ctx,
            String username, Collection<? extends GrantedAuthority> authorities) {
        return userDetailsService.loadUserByUsername(username);
    }
}

(我可能需要实现mapUserToContext方法,因为我正在使用不扩展LdapUserDetails的自定义UserDetails实现,因此反向转换过程可能会抛出异常...)

注意这样我两次重复相同的查询(到Users表)...我想找到一种方法来进行单个查询并分享AuthenticationProvider和UserDetailsContextMapper之间的结果。在AuthenticationProvider和UserDetailsContextMapper之间的结果。

答案 1 :(得分:0)

如果用户不是用户数据库,则应在授权过程中为其分配“无访问权限”。因此,无论他是否经过身份验证都无关紧要,应用程序将不允许他访问,因为他未获得该应用程序的授权。