2016-09-23 69 views
1

我在web应用使用以下工作:阿帕奇四郎LDAP配置(2步验证)

  • 阿帕奇四郎1.2.4
  • Tomcat的8
  • 的Java 8

我正在尝试通过LDAP域来验证用户身份。

我测试的登录用JXplorer使用以下值:

  • BaseND:OU =学生,OU =用户,O =数据
  • 用户DN /指定binddn:CN = {我的专有名称},OU =学生,OU =用户,O =数据
  • JXplorer也有我进口

现在我的问题证书:

我必须验证不是基于cn而是uid的用户。 但是这不会工作。

工作流在我的公司通过LDAP的管理建议:

我有(据我了解)应该连接到LDAP服务器系统的用户,搜索基于给定uid和用户为该用户返回cn

在第二步中,应该可以通过他的cn就像在JXplorer中完成(成功)那样验证用户。


我shiro.ini配置看起来像这样为我的测试LDAP(而不是一个我想对现在进行身份验证)

ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm 
ldapRealm.userDnTemplate = cn={0},ou=People,dc=maxcrc,dc=com 
ldapRealm.contextFactory.url = ldap://localhost:389 

我面对现在的问题是,我找不到有关如何配置我的shiro.ini文件以从上面计算建议的工作流程的信息。

问题#1

我可以使用标准的org.apache.shiro.realm.ldap.JndiLdapRealm(我怎么配置它)?特别是对于证书的集成,我无法找到任何合适的东西。

问题2

我需要为此创造“两步验证”怎么会这样的境界看起来像一个自定义JndiLdapRealm?

回答

1

我发现了一个solutiuon,那就是从JndiLdapRealm

现在看起来是这样的过载getUserDN()方法:

/** 
* Addition to standard shiro code 
* User logs in with his {@link principal} (username) but login needs to be performed with his cn instead 
* The addition is an ldap query to get the users cn from the ldap server and store it (instead of the given principal) in the return String 
* @return UserDN with user uid (cn) instead of principal (username) 
*/ 
@Override 
protected String getUserDn(final String principal) throws IllegalArgumentException, IllegalStateException { 

    if (!StringUtils.hasText(principal)) { 
     throw new IllegalArgumentException("User principal cannot be null or empty for User DN construction."); 
    } 
    String prefix = getUserDnPrefix(); 
    String suffix = getUserDnSuffix(); 
    if (prefix == null && suffix == null) { 
     log.debug("userDnTemplate property has not been configured, indicating the submitted " + 
        "AuthenticationToken's principal is the same as the User DN. Returning the method argument " + 
        "as is."); 
     return principal; 
    } 

    int prefixLength = prefix != null ? prefix.length() : 0; 
    int suffixLength = suffix != null ? suffix.length() : 0; 
    StringBuilder sb = new StringBuilder(prefixLength + principal.length() + suffixLength); 
    if (prefixLength > 0) { 
     sb.append(prefix); 
    } 

    /*############################################################################################ 
    * ADDITION TO STANDARD SHIRO CODE 
    * User logs in with his {@link principal} (username) but login needs to be performed with his cn instead 
    * => translate username to cn 
    */ 
    AppSettings_Controler settings = Startup.getAppSettingsControler(); 
    LDAP_Manager ldap_manager = new LDAP_Manager(); 
    LdapContext ctx = ldap_manager.getLdapConnection(); 
    String user_uid = ""; 

    SearchControls constraints = new SearchControls(); 
    constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); 
    String[] attrIDs = {"cn"}; 
    constraints.setReturningAttributes(attrIDs); 
    NamingEnumeration answer = null; 

    try{ 
     answer = ctx.search(settings.get_ldap_search_dn_1(), settings.get_ldap_uname_field_name_1() + "=" + principal, constraints); 
     if (answer.hasMore()) { 
      Attributes attrs = ((SearchResult) answer.next()).getAttributes(); 
      user_uid = attrs.get("cn").toString().substring(attrIDs[0].length() + 2); 
     } else { 
      throw new Exception("Invalid User"); 
     } 
    } catch (Exception ex) { 
     // Error Handling & Fallback to my second LDAP-Server 
     try{ 
      answer = ctx.search(settings.get_ldap_search_dn_2(), settings.get_ldap_uname_field_name_2() + "=" + principal, constraints); 
      if (answer.hasMore()) { 
       Attributes attrs = ((SearchResult) answer.next()).getAttributes(); 
       user_uid = attrs.get("cn").toString().substring(attrIDs[0].length() + 2); 
      } else { 
       throw new Exception("Invalid User"); 
      } 
     }catch (Exception exe) { 
      // Error Handling 
     } 
    } 
    try { 
     ctx.close(); 
    } catch (NamingException ex) { 
     JndiLdapRealm_custom_error_logger.error("getUserDn(); Fehler beim schließen: ", ex); 
    } 
    //############################################################################################ 

    //############################################################################################ 
    // Shiro Standard Code -> add principal to String 
    //sb.append(principal); 
    /*############################################################################################ 

    /*############################################################################################ 
    * ALTERED CODE 
    * Instead -> Add user's cn to String 
    */ 
    sb.append(user_uid); 
    //############################################################################################ 

    if (suffixLength > 0) { 
     sb.append(suffix); 
    } 
    return sb.toString(); 
} 

这除了做一个LDAP查询,以获得用户的UID(CN)基于所提供的用户名。这样,登录与用户只需输入他的LDAP用户名和我的应用程序一起工作,并遵循上述工作流程。

如果您有任何建议或意见,请不要犹豫,在此发布;)