2015-10-01 154 views
0

我们目前正在使用apache shiro来对用户进行身份验证,而不是通过活动目录进行身份验证。Apache shiro Active Directory通过域名登录

目前我们有用户通过LDAP帐户名登录,就像[email protected]

现在我们应该改变制度,使用户可以通过sAMAccountName属性登录。 这个想法是,用户在登录框中输入sAMAccountName名称, ,然后shiro将其与loginname的[email protected]匹配。

的shiro.ini目前看起来是这样的:

activeDirectoryRealm.systemUsername = systemuser 
activeDirectoryRealm.systemPassword = ******* 
activeDirectoryRealm.searchBase = dc=corp,dc=adsdomain,dc=local 
activeDirectoryRealm.url = ldap://<adsserver-ip>:389 
activeDirectoryRealm.principalSuffix = @adsdomain.local 

回答

0

随着this帖子在四郎的邮件列表,我能够实现一个有效的解决方案的帮助。

的基本步骤是:1。 在继承类的ActiveDirectoryRealm 2.实现自己queryForAuthenticationInfo方法指定要使用新的类查询/登录操作

public class AarstockADSRealm extends ActiveDirectoryRealm 
{ 
    final private Logger _log = LoggerFactory.getLogger(AarstockADSRealm.class); 

    public AarstockADSRealm() 
    { 
    } 

    @Override 
    protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException 
    { 
     //final AuthenticationInfo queryForAuthenticationInfo = super.queryForAuthenticationInfo(token, ldapContextFactory); 
     final UsernamePasswordToken upToken = (UsernamePasswordToken) token; 
     LdapContext ctx = null; 
     try 
     { 
      ctx = ldapContextFactory.getSystemLdapContext(); // .getLdapContext(upToken.getUsername(), upToken.getPassword()); 
      final String attribName = "userPrincipalName"; 
      final SearchControls searchCtls = new SearchControls(SearchControls.SUBTREE_SCOPE, 1, 0, new String[] 
      { 
       attribName 
      }, false, false); 
      final NamingEnumeration<SearchResult> search = ctx.search(searchBase, "sAMAccountName={0}", new Object[] 
      { 
       upToken.getPrincipal() 
      }, searchCtls); 
      if (search.hasMore()) 
      { 
       final SearchResult next = search.next(); 
       // upToken.setUsername(next.getAttributes().get(attribName).get().toString()); 
       String loginUser= next.getAttributes().get(attribName).get().toString(); 
       _log.info("Loginuser: "+loginUser); 
       if (search.hasMore()) 
       { 
        _log.error("More than one user matching: "+upToken.getPrincipal()); 
        throw new RuntimeException("More than one user matching: "+upToken.getPrincipal()); 
       } 
       else 
       { 
        try 
        { 
         LdapContext ctx2 = ldapContextFactory.getLdapContext(loginUser, upToken.getPassword()); 
        } 
        catch (Exception ex) 
        { 
         _log.warn("Error in authentication for user "+loginUser, ex); 
         // We have to rethrow the exception, to indicate invalid login 
         throw ex; 
        } 
       } 
      } 
      else 
      { 
       _log.info("No user matching: "+upToken.getPrincipal()); 
       throw new RuntimeException("No user matching: "+upToken.getPrincipal()); 
      } 
     } 
     catch (NamingException ne) 
     { 
      _log.error("Error in ldap name resolving", ne); 
         // We have to rethrow the exception, to indicate invalid login 
      throw ne; 
     } finally 
     { 
      LdapUtils.closeContext(ctx); 
     } 
     return buildAuthenticationInfo(upToken.getUsername(), upToken.getPassword()); 
    } 
}