本文介绍了Shiro验证LDAP中不存在的用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以建议Shiro为什么在下面的跟踪日志中告诉我不存在的用户"anybody"已通过身份验证吗?在实际进行身份验证之前,它似乎在日志中更早地为其提供了会话.我假设这只是为了运行身份验证.

Can anyone suggest why Shiro tells me in my trace logs below that a non existent user "anybody" is authenticated ok? It seems to give itself a session earlier on in the log prior to actually authenticating. I assume that this is just to run the authentication.

如果我注销然后将其尝试访问任何安全的URL,它将ok重定向到我的ShiroFilterFactoryBean loginUrl.但随后它将对任何用户进行身份验证.

It redirects ok to my ShiroFilterFactoryBean loginUrl if I logout and then try to access any secured url. But then it will authenticate any user.

1月27日20:25:16 TRACE org.apache.shiro.subject.support.DelegatingSubject-尝试获取会话;创建=假;会话为空=假;会话的ID为true1月27日20:25:16跟踪org.apache.shiro.authc.AbstractAuthenticator-收到令牌的身份验证尝试[org.apache.shiro.authc.UsernamePasswordToken-任何人,记住我=假(127.0.0.1)]1月27日20:25:16调试org.apache.shiro.realm.ldap.JndiLdapRealm-通过LDAP验证用户任何人"1月27日20:25:16调试org.apache.shiro.realm.ldap.JndiLdapContextFactory-使用URL [ldap://184.26.3.91:389]和主体[uid = anybody,ou = REMOTE,o = OFFICE]初始化LDAP上下文禁用池化的]1月27日20:25:16调试org.apache.shiro.realm.AuthenticatingRealm-从doGetAuthenticationInfo查找AuthenticationInfo [任何人]1月27日20:25:16调试org.apache.shiro.realm.AuthenticatingRealm-信息[anybody]的AuthenticationInfo缓存已禁用.提交的令牌:[org.apache.shiro.authc.UsernamePasswordToken-任何人,RememberMe = false(127.0.0.1)].1月27日20:25:16调试org.apache.shiro.authc.AbstractAuthenticator-令牌的身份验证成功[org.apache.shiro.authc.UsernamePasswordToken-任何人,记住我=假(127.0.0.1)].退回的帐户[任何人]1月27日20:25:16调试org.apache.shiro.subject.support.DefaultSubjectContext-主题上下文映射中没有SecurityManager.回退到SecurityUtils.getSecurityManager()查找.1月27日20:25:16在线程中跟踪org.apache.shiro.util.ThreadContext-get()-[http-bio-8080-exec-6]1月27日20:25:16跟踪org.apache.shiro.util.ThreadContext-绑定到键[org.apache.shiro.util.ThreadContext_SECURITY_MANAGER_KEY]的类型[org.apache.shiro.web.mgt.DefaultWebSecurityManager]的值线程[http-bio-8080-exec-6]1月27日20:25:16跟踪org.apache.shiro.mgt.DefaultSecurityManager-上下文已经包含一个SecurityManager实例.回来了.Jan 27 20:25:16 TRACE org.apache.shiro.subject.support.DelegatingSubject-尝试获取会话;创建=假;会话为空=假;会话的ID为true1月27日20:25:16调试org.apache.shiro.mgt.DefaultSecurityManager-上下文已经包含一个会话.返回.

Jan 27 20:25:16 TRACE org.apache.shiro.subject.support.DelegatingSubject - attempting to get session; create = false; session is null = false; session has id = trueJan 27 20:25:16 TRACE org.apache.shiro.authc.AbstractAuthenticator - Authentication attempt received for token [org.apache.shiro.authc.UsernamePasswordToken - anybody, rememberMe=false (127.0.0.1)]Jan 27 20:25:16 DEBUG org.apache.shiro.realm.ldap.JndiLdapRealm - Authenticating user 'anybody' through LDAPJan 27 20:25:16 DEBUG org.apache.shiro.realm.ldap.JndiLdapContextFactory - Initializing LDAP context using URL [ldap://184.26.3.91:389] and principal [uid=anybody,ou=REMOTE,o=OFFICE] with pooling disabledJan 27 20:25:16 DEBUG org.apache.shiro.realm.AuthenticatingRealm - Looked up AuthenticationInfo [anybody] from doGetAuthenticationInfoJan 27 20:25:16 DEBUG org.apache.shiro.realm.AuthenticatingRealm - AuthenticationInfo caching is disabled for info [anybody]. Submitted token: [org.apache.shiro.authc.UsernamePasswordToken - anybody, rememberMe=false (127.0.0.1)].Jan 27 20:25:16 DEBUG org.apache.shiro.authc.AbstractAuthenticator - Authentication successful for token [org.apache.shiro.authc.UsernamePasswordToken - anybody, rememberMe=false (127.0.0.1)]. Returned account [anybody]Jan 27 20:25:16 DEBUG org.apache.shiro.subject.support.DefaultSubjectContext - No SecurityManager available in subject context map. Falling back to SecurityUtils.getSecurityManager() lookup.Jan 27 20:25:16 TRACE org.apache.shiro.util.ThreadContext - get() - in thread [http-bio-8080-exec-6]Jan 27 20:25:16 TRACE org.apache.shiro.util.ThreadContext - Retrieved value of type [org.apache.shiro.web.mgt.DefaultWebSecurityManager] for key [org.apache.shiro.util.ThreadContext_SECURITY_MANAGER_KEY] bound to thread [http-bio-8080-exec-6]Jan 27 20:25:16 TRACE org.apache.shiro.mgt.DefaultSecurityManager - Context already contains a SecurityManager instance. Returning.Jan 27 20:25:16 TRACE org.apache.shiro.subject.support.DelegatingSubject - attempting to get session; create = false; session is null = false; session has id = trueJan 27 20:25:16 DEBUG org.apache.shiro.mgt.DefaultSecurityManager - Context already contains a session. Returning.

我的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应用程序上下文:

spring application context :

     <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>

感谢您的帮助

推荐答案

奇怪的行为...但是我认为这是标准LDAP而不是Shiro本身(如果我猜错了,请纠正我).在LDAP初始上下文的创建过程中,URL的密钥错误,因此显然它要进入localhost并没有找到LDAP服务器,因此它没有引发异常,但是很高兴地恢复为匿名登录,并且不限制对不存在的用户.我将其更改为:

Weird behaviour ... but I think this is standard LDAP rather than Shiro per se (correct me if I'm guessing wrong).In the creation of the LDAP initial context the key was wrong for the url so apparently it was going to localhost and not finding an LDAP server it didn't throw an exception but merrily reverted back to the anonymous login and didn't restrict access to the non-existent user. I changed it to:

    <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 )

这篇关于Shiro验证LDAP中不存在的用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 14:00