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.
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.
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 = true Jan 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 LDAP Jan 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 disabled Jan 27 20:25:16 DEBUG org.apache.shiro.realm.AuthenticatingRealm - Looked up AuthenticationInfo [anybody] from doGetAuthenticationInfo Jan 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 = true Jan 27 20:25:16 DEBUG org.apache.shiro.mgt.DefaultSecurityManager - Context already contains a session. Returning.
My LDAP realm is :
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 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>
Thanks for any help