2011-10-13 406 views
2

我使用弹簧安全3 当我输入错误的数据用户被重定向到登录失败链接 但弹簧安全不会调用loadUserByUsername方法? 那么认证如何发生,Spring知道凭证是错误的? 或者我的配置有问题,请指导。loadUserByUsername未被调用

登录页:

<form action="/myapp/j_spring_security_check"> 
         <h:graphicImage id="graphicImage1" style="height: 322px; left: 0px; top: 0px; position: absolute" url="/resources/images/LoginImage.jpg" width="560"/> 
         <h:outputLabel for="j_username" id="outputLabel1" style="left: 48px; top: 120px; position: absolute" value="Username:"/> 
         <h:outputLabel for="j_password" id="outputLabel2" style="left: 48px; top: 168px; position: absolute" value="Password:"/> 
         <h:inputText binding="#{login.username}" id="j_username" required="true" 
          style="left: 142px; top: 118px; position: absolute; width: 237px" /> 
         <h:inputSecret binding="#{login.password}" id="j_password" required="true" style="left: 142px; top: 166px; position: absolute; width: 237px"/> 
         <h:commandButton id="loginBtn" style="left: 144px; top: 240px; position: absolute" value="Login"/> 
         <h:commandButton action="#{login.reset}" id="resetBtn" style="position: absolute; left: 360px; top: 240px" value="Reset"/> 
         <h:outputText id="errorMessage" style="left:0px;top:300px;position:absolute"/> 
         <h:message errorClass="errorMessage" for="j_username" fatalClass="fatalMessage" id="messages1" infoClass="infoMessage" showSummary="false" 
          style="height: 43px; left: 24px; top: 288px; position: absolute; width: 523px;color:red;" warnClass="warnMessage"/> 
         </form> 

的security.xml:

<beans:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:beans="http://www.springframework.org/schema/beans" 
    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.0.4.xsd"> 


     <global-method-security pre-post-annotations="enabled" /> 

     <!-- key configuration here is an entry point to be used by security intercepts --> 
     <http use-expressions="true" auto-config="false"> 

     <session-management session-fixation-protection="none"/> 

     <remember-me token-validity-seconds="1209600"/> 

     <!-- Exclude the login page from the security check --> 
     <intercept-url pattern="/faces/login.xhtml" access="permitAll"/> 

     <!-- All pages requires authentication (not anonymous user) --> 
     <intercept-url pattern="/faces/**" access="isAuthenticated()" /> 

     <intercept-url pattern="/faces/javax.faces.resource/**" filters="none" /> 
     <intercept-url pattern="/faces/xmlhttp/**" filters="none" /> 
     <intercept-url pattern="/faces/resources/**" filters="none" /> 
     <intercept-url pattern="/faces/j_spring_security_check/**" filters="none" /> 
     <intercept-url pattern="/scripts/**" filters="none" /> 
     <intercept-url pattern="/images/**" filters="none" /> 
     <intercept-url pattern="/css/**" filters="none" /> 

     <!-- Returns true if the user is not anonymous --> 


     <access-denied-handler error-page="/error"/> 

     <form-login default-target-url="/users" 
     always-use-default-target="true"    
      login-processing-url="/j_spring_security_check"   
      login-page="/faces/login.xhtml" 
      authentication-failure-url="/faces/login.xhtml?login_error=1"                
     /> 

     <logout logout-url="/logout" logout-success-url="/login" />  
    </http> 

    <authentication-manager alias="authenticationManager">   
    <authentication-provider user-service-ref="userDetailsServiceImpl"> 
    </authentication-provider> 
    </authentication-manager> 


    </beans:beans> 

3-的UserDetailsS​​ervice:

@Service("userDetailsServiceImpl") 
public class UserDetailsServiceImpl implements UserDetailsService { 

    @Autowired 
    private UserDao userDao; 

    @Override 
    public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException, DataAccessException { 
     System.out.println("########## LOADING USER ##################"); 
     User user = userDao.findUserByEmail(username); 
     return new org.springframework.security.core.userdetails.User(
       user.getEmail(), user.getPassword(), true, true, true, true, 
       setUserAuthorities(user.getAuthorities())); 
    } 

    public Collection<GrantedAuthority> setUserAuthorities(List<Authority> auths) { 

     List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(); 
     for (Authority auth : auths) 
      grantedAuthorities.add(new GrantedAuthorityImpl(auth.getName())); 
     return grantedAuthorities; 
    } 
} 
+0

你的意思是:''########## LOADING USER ##################“'没有出现在输出中? – Ralph

+0

是的,这就是我的意思。 –

回答

3

You remember that I told that spring security adds a lot of filters?其中一个过滤器负责检查是否向认证管理器请求j_spring_security_check

但你没有那个过滤器。

如果对这种没有任何理由,然后再启用自动配置:

<http use-expressions="true" auto-config="true"> 

并添加拦截器/j_spring_security_check

<intercept-url pattern="/j_spring_security_check" access="permitAll"/> 
+0

非常感谢你的提示,我想知道auto-config = true和false之间的区别,你能否给我提供文档链接或其他有用的链接。 –

+0

http://static.springsource.org/spring-security/site/docs/3.0.x/reference/springsecurity-single.html#ns-minimal - 并查看源代码以获取更多详细信息 – Ralph

+0

@Mika :它有效吗? – Ralph

1

由于我有这个

loadUserByUsername是未被调用

将弹簧安全性从3.2.8升级到4.0.2后出现的其他一些问题 即使已经有 接受了正确的答案,我仍将描述我的情况。

所以昨天我决定提出安全升级。 首先,在安全4.0.2 CSRF保护是默认启用的, 我需要将其关闭矿井安全的context.xml:

​​

在了项目CSRF保护ISN的现阶段”并入角度用户界面。 这一刻导致上下文初始化错误。

之后,我看到我无法登录到应用程序。 我正在POST POST默认j_spring_security_check URL的。 但春季安全4.0.2使用另一个问题: Spring Security Reference

登录处理的URL映射到 UsernamePasswordAuthenticationFilter的filterProcessesUrl财产。默认值是“/ login”。

另外默认注销-URL已变更: Spring Security Reference

注销-URL这会导致一个注销的URL(即,其将通过过滤器处理)。默认为“/注销”。

因此,我对security security-context.xml和login/logout进行了更改,以返回适当的行为。

之后,我注意到我的@PreAuthorize注释不起作用。 我使用他们定义为常量角色名:

@PreAuthorize("hasRole(T(org...UserService).ADMIN_ROLE_NAME)" 
     + " or hasRole(T(org...UserService).OWNER_ROLE_NAME)") 

和角色的名字是:

public final static String ADMIN_ROLE_NAME = "admin"; 
public final static String USER_ROLE_NAME = "plain_user"; 
public final static String OWNER_ROLE_NAME = "company_owner"; 

正如你看到的,他们没有包含“ROLE_”前缀。 据我了解,安全4.0.2不能使用这样的名字。 可能是因为: Spring Security Reference

现在,您可以选择忽略ROLE_前缀。我们这样做是为了删除 重复。具体而言,由于表达式hasRole已经将 定义为角色,所以它自动添加前缀(如果它不是 )。

我改变角色名:

public final static String ADMIN_ROLE_NAME = "ROLE_ADMIN"; 
public final static String USER_ROLE_NAME = "ROLE_USER"; 
public final static String OWNER_ROLE_NAME = "ROLE_OWNER"; 

和安全回到了正确的行为。

P.S. (在拉尔夫的答案)

并添加/ j_spring_security_check

我没有为3.2.8默认登录处理的URL拦截器的拦截。 而我没有4.0.2默认登录处理url的拦截器。 有拦截器登录页面本身在我安全的context.xml:

<intercept-url pattern="/authorize" access="permitAll" /> 

刚刚返回的login.html。