2014-01-27 25 views
1

任何人都可以提出爲什麼Shiro在我的跟蹤日誌中告訴我一個不存在的用戶「任何人」已經通過驗證了嗎?在實際驗證之前,它似乎早些時候在日誌中給自己一個會話。我假設這只是運行身份驗證。Shiro在LDAP中驗證不存在的用戶

它重定向到我的ShiroFilterFactoryBean loginUrl如果我註銷,然後嘗試訪問任何安全的URL。但是,它會驗證任何用戶。

Jan 27 20:25:16 TRACE org.apache.shiro.subject.support.DelegatingSubject - 嘗試獲取會話; create = false; session是null = false; session有id = true Jan 27 20:25:16 TRACE org.apache.shiro.authc.AbstractAuthenticator - 驗證嘗試收到的令牌[org.apache.shiro.authc.UsernamePasswordToken - anybody,rememberMe = false(127.0.0.1) ] Jan 27 20:25:16 DEBUG org.apache.shiro.realm.ldap.JndiLdapRealm - 通過LDAP驗證用戶'任何人' Jan 27 20:25:16 DEBUG org.apache.shiro.realm.ldap.JndiLdapContextFactory - 使用URL [ldap://184.26.3.91:389]和主體[uid = anybody,ou = REMOTE,o = OFFICE]初始化LDAP上下文並禁用池化 Jan 27 20:25:16 DEBUG org.apache.shiro.realm .AuthenticatingRealm - 查看來自doGetAuthenticationInfo的AuthenticationInfo [任何人] Jan 27 20:25:16 DEBUG org.apache.shiro.realm.AuthenticatingRealm - 對info [anybody]禁用了AuthenticationInfo緩存。提交的令牌:[org.apache.shiro.authc.UsernamePasswordToken - anybody,rememberMe = false(127.0.0.1)]。 Jan 27 20:25:16 DEBUG org.apache.shiro.authc.AbstractAuthenticator - 驗證成功爲標記[org.apache.shiro.authc.UsernamePasswordToken - 任何人,rememberMe = false(127.0.0.1)]。返回的帳戶[任何人] Jan 27 20:25:16 DEBUG org.apache.shiro.subject.support.DefaultSubjectContext - 在主題上下文映射中沒有SecurityManager可用。回退到SecurityUtils.getSecurityManager()查找。在線程[http-bio-8080-exec-6] Jan 27 20:25:16 TRACE .util.ThreadContext - 綁定到線程[http-bio-8080-exec-6]的密鑰[org.apache.shiro.util.ThreadContext_SECURITY_MANAGER_KEY]的[org.apache.shiro.web.mgt.DefaultWebSecurityManager]類型的檢索值 Jan 27 20:25:16 TRACE org.apache.shiro.mgt.DefaultSecurityManager - Context已經包含一個SecurityManager實例。返回。 Jan 27 20:25:16 TRACE org.apache.shiro.subject.support.DelegatingSubject - 嘗試獲取會話; create = false; session是null = false; session有id = true Jan 27 20:25:16 DEBUG org.apache.shiro.mgt.DefaultSecurityManager - 上下文已經包含一個會話。返回。

我的LDAP境界是:

public class MyJndiLdapRealm extends JndiLdapRealm { 

private static final Logger logger = LoggerFactory.getLogger(MyJndiLdapRealm.class); 

@Override 
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException { 

    logger.debug("queryForAuthorizationInfo(PrincipalCollection: entering"); 

    String username = (String) getAvailablePrincipal(principals); 

    logger.debug("queryForAuthorizationInfo(PrincipalCollection: user is "+ username); 

    // Perform context search 
    LdapContext ldapContext = ldapContextFactory.getSystemLdapContext(); 

    Set<String> roleNames; 

    try { 
     roleNames = getRoleNamesForUser(username, ldapContext); 
    } finally { 
     LdapUtils.closeContext(ldapContext); 
    } 

    return buildAuthorizationInfo(roleNames); 
} 

protected AuthorizationInfo buildAuthorizationInfo(Set<String> roleNames) { 
    return new SimpleAuthorizationInfo(roleNames); 
} 

protected Set<String> getRoleNamesForUser(String username, LdapContext ldapContext) throws NamingException { 
    Set<String> roleNames; 
    roleNames = new LinkedHashSet<String>(); 

    logger.debug("getRoleNamesForUser : entering"); 

    SearchControls searchCtls = new SearchControls(); 
    searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); 

    //SHIRO-115 - prevent potential code injection: 
    String searchFilter = "(&(objectClass=*)(CN={0}))"; 
    Object[] searchArguments = new Object[]{ username }; 

// Name searchBase; // ? 
    String searchBase = "test"; 
    NamingEnumeration<SearchResult> answer = ldapContext.search(searchBase, searchFilter, searchArguments, searchCtls); 

    while (answer.hasMoreElements()) { 
     SearchResult sr = (SearchResult) answer.next(); 

     logger.debug("Retrieving group names for user [" + sr.getName() + "]"); 


     Attributes attrs = sr.getAttributes(); 

     if (attrs != null) { 
     NamingEnumeration<? extends Attribute> ae = attrs.getAll(); 
     while (ae.hasMore()) { 
      Attribute attr = (Attribute) ae.next(); 

      if (attr.getID().equals("memberOf")) { 

      Collection<String> groupNames = LdapUtils.getAllAttributeValues(attr); 

      logger.debug("Groups found for user [" + username + "]: " + groupNames); 

      Collection<String> rolesForGroups = getRoleNamesForGroups(groupNames); 
      roleNames.addAll(rolesForGroups); 
      } 
     } 
     } 
    } 
    return roleNames; 
} 
    // active dir 
protected Collection<String> getRoleNamesForGroups(Collection<String> groupNames) { 
     Set<String> roleNames = new HashSet<String>(groupNames.size()); 
/* 
      if (groupRolesMap != null) { 
       for (String groupName : groupNames) { 
        String strRoleNames = groupRolesMap.get(groupName); 
        if (strRoleNames != null) { 
         for (String roleName : strRoleNames.split(ROLE_NAMES_DELIMETER)) { 


           log.debug("User is member of group [" + groupName + "] so adding role [" + roleName + "]"); 


          roleNames.add(roleName); 

         } 
        } 
       } 
       } */ 
      return roleNames; 
     } 

}

Spring應用程序上下文:

 <bean id="customAuthFilter" class="security.MyAuthenticationFilter"/> 

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
    <property name="securityManager" ref="securityManager"/> 
    <property name="loginUrl" value="/ldapLogin"/> 
    <property name="successUrl" value="/referral_form"/> 
    <property name="unauthorizedUrl" value="/unauthorized"/> 
    <property name="filterChainDefinitions"> 
     <value> 
      /** = authc, customAuthFilter 
      [main] 
      /logout = logout 
     </value> 
    </property> 
</bean> 

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
    <!-- Single realm app. If you have multiple realms, use the 'realms' property instead. --> 
    <property name="realm" ref="authenticateRealm"/> 
<!-- <property name="sessionManager.globalSessionTimeout ="30000"/> --> 
    <property name="sessionMode" value="native"/> 
</bean> 
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> 

<bean id="authenticateRealm" class="security.MyJndiLdapRealm"> 
    <property name="contextFactory" ref="contextFactory" /> 
    <property name="userDnTemplate" value="uid={0},ou=OFFICE" /> 
</bean> 

<bean id="contextFactory" class="org.apache.shiro.realm.ldap.JndiLdapContextFactory"> 
    <property name="environment"> 
     <map> 
      <entry key="java.naming.provider.url" value="ldap://184.26.3.91:389" /> 
     </map>  
    </property> 

</bean> 

<!-- Enable Shiro Annotations for Spring-configured beans. Only run after --> 
<!-- the lifecycleBeanProcessor has run: --> 
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/> 
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> 
    <property name="securityManager" ref="securityManager"/> 
</bean> 

感謝所有幫助

+0

您使用了什麼密碼? –

+0

因此,對於系統LDAP用戶,它只會默認爲匿名。對於用戶(這裏使用表單認證),我只是把一些垃圾。 – user1069528

+0

奇怪的是,如果我更改爲本地會話,它的行爲完全相反。現在沒有任何東西可以代替所有被認證的東西。 user1069528

回答

0

怪異的行爲...但我認爲這是標準的LDAP而不是Shiro本身(糾正我,如果我猜錯了)。 在創建LDAP初始上下文時,關鍵是URL錯誤,所以顯然它要到localhost,並且沒有找到LDAP服務器,它沒有拋出異常,但愉快地還原爲匿名登錄並且沒有限制訪問到不存在的用戶。我改成:

<bean id="contextFactory" class="org.apache.shiro.realm.ldap.JndiLdapContextFactory"> 
    <property name="url" value="ldap://184.26.3.91:389"/> 
    </bean> 

它工作。

(感謝http://shiro-user.582556.n2.nabble.com/What-is-the-configuration-for-ldap-authentication-with-spring-td6656846.html