2016-01-13 240 views
1

我試圖使用spring安全性實現身份驗證。春季安全用戶身份驗證不起作用

我無法弄清楚我做錯了什麼。

web.xml中具有安全性濾波器:

<!-- Spring Security --> 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

彈簧security.xml文件具有定義的URL攔截並認證管理器:

<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-4.1.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-4.0.xsd"> 

    <!-- enable use-expressions --> 
    <http auto-config="true" use-expressions="true"> 
     <intercept-url pattern="/" access="permitAll" /> 
     <intercept-url pattern="/logout**" access="permitAll" /> 

     <!-- Incoming Product --> 
     <intercept-url pattern="/incomingProduct**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 

     <!-- Maintanence pages --> 
     <intercept-url pattern="/depotUser**" access="hasRole('Administrator') and hasRole('Local_Administrator')" /> 
     <intercept-url pattern="/product**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 
     <intercept-url pattern="/productOwner**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 
     <intercept-url pattern="/storageTank**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 

     <intercept-url pattern="/admin**" access="hasRole('Administrator')" /> 

     <!-- access denied page --> 
     <access-denied-handler error-page="/error/403" /> 
     <form-login 
      login-page="/" 
      default-target-url="/" 
      authentication-failure-url="/Access_Denied" 
      username-parameter="username" 
      password-parameter="password" /> 
     <logout logout-success-url="/logout" /> 
     <!-- enable csrf protection --> 
     <csrf /> 
    </http> 

    <authentication-manager> 
     <authentication-provider user-service-ref="userSecurityService" /> 
    </authentication-manager> 

    <beans:bean id="userSecurityService" class="com.tms.securityServices.UserSecurityService" > 
     <beans:property name="depotUserDao" ref="depotUserDao" /> 
    </beans:bean> 

</beans:beans> 

UserSecurityService實現的UserDetailsS​​ervice。根據spring-security.xml中的配置,應該調用該命令來驗證登錄請求並將用戶注入會話。 (!請糾正我,如果我錯了)

@Transactional 
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
{ 
    DepotUser user = depotUserDao.findByUserName(username); 
    System.out.println("User : " + user); 
    if (user == null) 
    { 
     System.out.println("User not found"); 
     throw new UsernameNotFoundException("Username not found"); 
    } 
    return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.isActive(), true, true, true, 
      getGrantedAuthorities(user)); 
} 

private List<GrantedAuthority> getGrantedAuthorities(DepotUser user) 
{ 
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 

    for (DepotUserRole userProfile : user.getUserRole()) 
    { 
     System.out.println("UserProfile : " + userProfile); 
     authorities.add(new SimpleGrantedAuthority("ROLE_" + userProfile.getRole())); 
    } 

    System.out.print("authorities :" + authorities); 
    return authorities; 
} 

登錄控制器處理請求:

@RequestMapping(value = { "/loginRequest" }, method = RequestMethod.POST) 
public String loginRequest(@RequestParam String username, @RequestParam String password, HttpServletRequest request, HttpServletResponse response) 
     { 
      DepotUser user = depotUserManager.getUserByUsernamePassword(username, password); 

      if (user != null) 
      { 
       request.setAttribute("firstName", user.getFirstName()); 
       request.setAttribute("lastName", user.getLastName()); 
       request.setAttribute("username", user.getUsername()); 
       request.setAttribute("userRoles", user.getUserRole()); 
       return "homePage"; 
      } 

當我登錄用戶獲取與匿名用戶登錄會發生什麼事。

身份驗證不會被觸發,因爲我沒有得到UserSecurityService中的中斷點。在處理請求的彈簧控制器中也是如此。

任何人都可以幫我嗎?

任何幫助表示讚賞。

謝謝,

回答

1

多於一個細節似乎有不是右

在配置上,在登錄部:

<form-login 
     login-page="/" 
     default-target-url="/" 
     authentication-failure-url="/Access_Denied" 
     username-parameter="username" 
     password-parameter="password" /> 

通過指定login-page="/",這意味着帶有表單數據的POST請求執行身份驗證必須爲"/" url,但您嘗試在控制器中處理"/loginRequest"處的身份驗證。

其次,處理身份驗證不是您必須在控制器中自行管理的,Spring安全會自動爲您執行此操作,只需將該POST表單發送到配置中指定的URL即可。

更新

至於登錄表單,你應該做以下幾件事肯定:

  • 形式的動作URL在配置中,login-page參數匹配其在這種情況下爲"/"
  • 用戶名爲的輸入字段的名稱屬性應該與匹配在配置"username"你的情況
  • 輸入字段輸入密碼應該與你的情況下,在配置的password-parameter"password"name屬性。

你也應該刪除modelAttribute="loginUser"

+0

由於@saljuama我試圖按照你建議,改變<表單登錄的登錄頁= 「/ loginRequest」。還是一樣的行爲。 –

+0

控制器中的部件僅用於測試目的。 –

+0

是的,測試可能會阻止春天的安全來做什麼:)。此外,@JacekWcislo在他的回答中說,你的登錄表單是怎樣的?你可以將代碼添加到你的問題嗎? – saljuama

0

請問你的登錄表單是什麼樣子?你有

(thymeleaf)

<form th:action="@{/j_spring_security_check}" method="post"> 

(JSP)

<form action="<c:url value='j_spring_security_check' />" method='POST'> 

其中之一?你能表達你的觀點嗎?

+0

我的登錄窗體'

'按照要求@saljuama @JacekWcislo –

+0

你可以詳細說明什麼是j_spring_security_check? –

+0

這是錯誤的;你不會觸發彈簧安全過濾器。閱讀:https://docs.spring.io/spring-security/site/docs/3.0.x/reference/core-web-filters.html。改變你的行動對應於我的文章,它應該是好的。 – wcislo

0

@JacekWcislo,@saljuama我有一個login-page="/"因爲我的默認登錄頁面是登錄頁面。 我正在添加一個答案,因爲我想顯示更新的代碼。

通過我提供以下已經更新了我的安全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-4.1.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-4.0.xsd"> 

    <!-- enable use-expressions --> 
    <http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint"> 
     <intercept-url pattern="/" access="permitAll" /> 
     <intercept-url pattern="/logout**" access="permitAll" /> 

     <!-- Incoming Product --> 
     <intercept-url pattern="/incomingProduct**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 

     <!-- Maintanence pages --> 
     <intercept-url pattern="/depotUser**" access="hasRole('Administrator') and hasRole('Local_Administrator')" /> 
     <intercept-url pattern="/product**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 
     <intercept-url pattern="/productOwner**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 
     <intercept-url pattern="/storageTank**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 

     <intercept-url pattern="/admin**" access="hasRole('Administrator')" /> 

     <!-- access denied page --> 
     <access-denied-handler error-page="/error/403" /> 
     <form-login 
      login-page="/" 
      default-target-url="/homePage" 
      authentication-failure-url="/loginPage?invalidLogin=Yes" 
      username-parameter="username" 
      password-parameter="password" 

      /> 
     <logout logout-success-url="/logout" /> 
     <!-- enable csrf protection --> 
     <csrf /> 

     <custom-filter before="FORM_LOGIN_FILTER" ref="authenticationFilter"/> 
    </http> 

    <beans:bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
     <beans:property name="authenticationManager" ref="authenticationManager" /> 
    </beans:bean> 

    <beans:bean id="authenticationEntryPoint" class= "org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> 
     <beans:constructor-arg value="/j_spring_security_check"/> 
    </beans:bean> 

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

    <beans:bean id="userSecurityService" class="com.tms.securityServices.UserSecurityService" > 
     <beans:property name="depotUserDao" ref="depotUserDao" /> 
    </beans:bean> 

</beans:beans> 

我的任何登錄JSP是

<form id="loginForm" method="post" modelAttribute="loginUser" action="<c:url value='j_spring_security_check' />"> 

它給了我一個404錯誤。我假設我將不得不映射春季安全網址。

我有它在我的

的AuthenticationEntryPoint

是還有其它地方我將不得不地圖呢?

+0

在未來,而不是添加一個新的答案,最好是編輯您的原始帖子,幷包括那裏的新信息,它使每個人更容易:) – saljuama

0

我能夠通過添加適當的過濾器,入口點和處理程序來解決此問題。

代碼:

<!-- enable use-expressions --> 
<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint"> 

    <!-- Dashboard & resources --> 
    <intercept-url pattern="/" access="permitAll" /> 
    <intercept-url pattern="/loginRequest**" access="permitAll" /> 
    <intercept-url pattern="/logout**" access="permitAll" /> 
    <intercept-url pattern="/dashboard**" access="permitAll" /> 
    <intercept-url pattern="/**/resources**" access="permitAll" /> 

    <!-- Incoming Product --> 
    <intercept-url pattern="/incomingProduct**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 

    <!-- Maintanence pages --> 
    <intercept-url pattern="/depotUser**" access="hasRole('Administrator') and hasRole('Local_Administrator')" /> 
    <intercept-url pattern="/product**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 
    <intercept-url pattern="/productOwner**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 
    <intercept-url pattern="/storageTank**" access="hasRole('Administrator') and hasRole('Local_Administrator') and hasRole('Supervisor') and hasRole('Manager')" /> 

    <intercept-url pattern="/admin**" access="hasRole('Administrator')" /> 

    <!-- access denied page --> 
    <access-denied-handler error-page="/error/403" /> 
    <form-login 
     login-page="/" 
     login-processing-url="/loginRequest" 
     default-target-url="/dashboard/home" 
     authentication-failure-url="/loginPage?invalidLogin=Yes" 
     username-parameter="username" 
     password-parameter="password" 
     /> 
    <logout logout-success-url="/logout" /> 
    <!-- enable csrf protection --> 
    <csrf /> 

    <custom-filter before="FORM_LOGIN_FILTER" ref="authenticationFilter"/> 
</http> 

<beans:bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
    <beans:property name="authenticationManager" ref="authenticationManager" /> 
    <beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" /> 
</beans:bean> 

<beans:bean id="authenticationEntryPoint" class= "org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> 
    <beans:constructor-arg value="/loginRequest"/> 
</beans:bean> 

<beans:bean id="authenticationSuccessHandler" 
    class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> 
    <beans:property name="defaultTargetUrl" value="/dashboard/home" /> 
</beans:bean> 

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