2015-10-01 188 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()); 
    } 
}