loadUserByUsername传递空用户名

时间:2014-01-22 18:51:46

标签: spring security customization

我正在尝试通过Scarioni的“Pro Spring Security”实现一个示例,该示例实现了一个自定义内存用户模型(实现UserDetailsS​​ervice接口)和自定义表达式处理程序。当我尝试登录时,我的CustomInMemoryUserDetailsManager的loadUserByUsername()方法将传递一个空白(非空)字符串作为用户名。这导致拒绝访问。如果我强制用户名是预期的(管理员),一切正常,包括自定义表达式处理。

这是我的安全配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<security:http  auto-config="true"  use-expressions="true" >
    <security:expression-handler ref="expressionHandler" />
    <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN') and hasIpAddress('127.0.0.1') and over18"/>
    <security:remember-me key="terror-key" />
    <security:form-login login-page="/custom_login"
        authentication-failure-handler-ref="serverErrorHandler"
        username-parameter="user_param" password-parameter="pass_param" />
</security:http>

<security:authentication-manager>
    <security:authentication-provider user-service-ref="inMemoryUserServiceWithCustomUser" />
</security:authentication-manager>

    <!-- Custom expression handler bean -->
<bean id="expressionHandler" class="com.apress.pss.terrormovies.security.CustomWebSecurityExpressionHandler"/>

<bean id="inMemoryUserServiceWithCustomUser"
       class="com.apress.pss.terrormovies.spring.CustomInMemoryUserDetailsManager">
    <constructor-arg>
       <list>
           <bean class="com.apress.pss.terrormovies.model.User">
               <constructor-arg value="admin"/>
               <constructor-arg value="admin"/>
               <constructor-arg>
                  <list>
                      <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
                         <constructor-arg value="ROLE_ADMIN"/>
                      </bean>
                  </list>
               </constructor-arg>
               <constructor-arg value="Scarioni"/>
               <constructor-arg value="19"/>
           </bean>
       </list>
    </constructor-arg>   
</bean>

<bean id="logoutRedirectToAny"
    class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler">
</bean>

<bean id="serverErrorHandler" class="com.apress.pss.terrormovies.security.ServerErrorFailureHandler"/>

</beans>

这是我的CustomInMemoryUserDetailsManager类:

package com.apress.pss.terrormovies.spring;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.apress.pss.terrormovies.model.User;

public class CustomInMemoryUserDetailsManager implements UserDetailsService {

    private final Log logger = LogFactory.getLog(getClass());

    private Map<String, User> users = new HashMap<String, User>();

    public CustomInMemoryUserDetailsManager(Collection<User> users) {

       for (User user : users) {
          this.users.put(user.getUsername().toLowerCase(), user);
          logger.debug("CustomInMemoryUserDetailsManager()- put username: " +  
          user.getUsername() + " last name: " + user.getLastName() + " authority: " +
                                                                 user.getAuthorities());
       }

    }

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // Test - force user name to that expected
        //username = "admin";

        if (username.equals("")) logger.debug("loadUserByUsername()- username is blank!!!");

        logger.debug("loadUserByUsername()- username: " + username);

        User user = users.get(username.toLowerCase());

        if (user == null) {
            throw new UsernameNotFoundException(username);
        }

        logger.debug("loadUserByUsername()- found " + user.getUsername());

        User userNew = new User(user.getUsername(), user.getPassword(), 
                        user.getAuthorities(), user.getLastName(), user.getAge());

        return userNew;

    }

}

我打开了Spring调试并获得了一个非常大的日志,这是我认为从登录到j_spring_security_check的相关部分:

:28,785 DEBUG main DispatcherServlet:130 - Servlet 'terrormovies' configured successfully
08:29:48,058 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
08:29:48,072 DEBUG qtp1624348237-15 HttpSessionSecurityContextRepository:127 - No HttpSession currently exists
08:29:48,085 DEBUG qtp1624348237-15 HttpSessionSecurityContextRepository:85 - No SecurityContext was available from the HttpSession: null. A new one will be created.
08:29:48,120 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 2 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
08:29:48,120 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 3 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
08:29:48,120 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 4 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
08:29:48,121 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 5 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
08:29:48,121 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 6 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
08:29:48,122 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 7 of 11 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
08:29:48,123 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
08:29:48,124 DEBUG qtp1624348237-15 AnonymousAuthenticationFilter:102 - Populated  SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
08:29:48,125 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
08:29:48,125 DEBUG qtp1624348237-15 SessionManagementFilter:92 - Requested session ID ncic677387xfiq2ciohmau1 is invalid.
08:29:48,126 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
08:29:48,126 DEBUG qtp1624348237-15 FilterChainProxy:337 - /admin/movies at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
08:29:48,126 DEBUG qtp1624348237-15 AntPathRequestMatcher:103 - Checking match of request : '/admin/movies'; against '/admin/*'
08:29:48,127 DEBUG qtp1624348237-15 FilterSecurityInterceptor:194 - Secure object: FilterInvocation: URL: /admin/movies; Attributes: [hasRole('ROLE_ADMIN') and hasIpAddress('127.0.0.1') and over18]
08:29:48,127 DEBUG qtp1624348237-15 FilterSecurityInterceptor:310 - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
08:29:48,129 DEBUG qtp1624348237-15 CustomWebSecurityExpressionRoot:22 - CustomWebSecurityExpressionRoot()- call
08:29:48,154 DEBUG qtp1624348237-15 AffirmativeBased:65 - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@35333295, returned: -1
08:29:48,157 DEBUG qtp1624348237-15 ExceptionTranslationFilter:165 - Access is denied(user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
...

在初始化时,您可以看到用户正确地在日志中输入用户HashMap:

08:29:25,912 DEBUG main CustomInMemoryUserDetailsManager:26 - CustomInMemoryUserDetailsManager()- put username: admin last name: Scarioni authority: [ROLE_ADMIN]

我注意到用户是匿名进来的,我不知道为什么。任何帮助将不胜感激。

由于 麦克

0 个答案:

没有答案