2015-05-18 225 views
0

我正在使用彈簧安全的電子商務項目。我們需要維護登錄歷史記錄。 由於j_spring_security_check在內部處理認證和授權。我能找到的唯一方法是擁有一個自定義的AuthenticationSuccessHandler來保存成功登錄的歷史記錄。 我看了一些帖子,得到了一個完美的答案,但有一個錯誤。 以下是我的配置:彈簧安全定製AuthenticationSuccessHandler

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

    <bean id="encoder" class="com.web.auth.CustomPasswordEncoder"> 
     <constructor-arg value="512"/> 
    </bean> 

    <security:http auto-config="true" use-expressions="true"> 
     <security:intercept-url pattern="/products/**" access="hasRole('ROLE_USER')" /> 
     <security:intercept-url pattern="/orders/**" access="hasRole('ROLE_USER')" /> 
     <security:access-denied-handler error-page="/403" /> 
     <security:form-login 
       login-page="https://stackoverflow.com/users/login" 
       default-target-url="/products/list" 
       authentication-failure-url="https://stackoverflow.com/users/login?error" 
       username-parameter="username" 
       password-parameter="password" 
       authentication-success-handler-ref="myAuthenticationSuccessHandler"/> 
     <security:logout invalidate-session="true" logout-success-url="https://stackoverflow.com/users/login?logout" /> 
     <!-- enable csrf protection --> 
     <security:csrf/> 
    </security:http> 

    <bean id ="customUserDetailsService" class="com.web.auth.UserDetailService"></bean> 


    <security:authentication-manager> 
     <security:authentication-provider user-service-ref="customUserDetailsService"> 
     <security:password-encoder ref="encoder"> 
      <security:salt-source user-property="salt"/> 
       </security:password-encoder> 
     </security:authentication-provider> 
    </security:authentication-manager> 

    <bean id="myAuthenticationSuccessHandler" class="com.web.auth.AuthenticationSuccessHandler"> 
     <property name="useReferer" value="true" /> 
    </bean> 


</beans> 

以下是如果一個網頁的用戶需求,這是保護我的執行customauthenticationfilter

package com.web.auth; 

import com.aws.sns.mobilepush.model.Platform; 
import com.loginhistory.UserLoginHistoryService; 
import com.loginhistory.model.UserLoginHistory; 
import com.user.UserService; 
import com.user.model.User; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; 
import org.springframework.security.web.savedrequest.HttpSessionRequestCache; 
import org.springframework.security.web.savedrequest.RequestCache; 
import org.springframework.security.web.savedrequest.SavedRequest; 
import org.springframework.util.StringUtils; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 
import java.util.Optional; 

/** 
* Created by root on 18/5/15. 
*/ 
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { 
    @Autowired 
    UserLoginHistoryService userLoginHistoryService; 
    @Autowired 
    UserService userService; 
    @Override 
    public void onAuthenticationSuccess(HttpServletRequest request, 
             HttpServletResponse response, 
             Authentication authentication) throws IOException,ServletException { 
     CustomUserDetails customUserDetails = (CustomUserDetails)authentication.getPrincipal(); 
     Optional<User> user = userService.findUserById(customUserDetails.getUserID()); 
     if (!user.isPresent()) { 
      return; 
     } 
     UserLoginHistory userLoginHistory = new UserLoginHistory(); 
     userLoginHistory.setPlatform(Platform.WEB); 
     userLoginHistory.setUser(user.get()); 
     userLoginHistory.setArnEndPoint("na"); 
     userLoginHistory.setTokenId("na"); 
     userLoginHistoryService.saveLoginHistoryForWeb(userLoginHistory); 

     super.onAuthenticationSuccess(request,response,authentication); 
    } 
    } 

我現在能夠保持歷史和一切工作正常。 但是,當用戶明確去登錄頁面,並將憑據,他被重定向到同一登錄頁面,而他應該被重定向到默認的後登錄頁面按我的配置。

請幫我找出這個問題,並提出可能的解決方案

感謝, 羅希特·米什拉

回答

0

您的配置不設置默認的後登錄頁面。您已將useReferer設置爲true,這意味着用戶將被重定向到他們來自的頁面。如果這是登錄頁面,他們將在那之後發回。嘗試刪除此。

根據您的要求,您可以通過其他方式控制重定向目的地,例如設置defaultTargetUrl - 有關更多詳細信息,請參閱docs for the class

+0

我已經設置了default-target-url =「/ products/list」。我想要的行爲是維護成功嘗試的登錄歷史記錄。所以我需要用戶從登錄頁面登錄並登錄到默認頁面,同時我也希望如果用戶在嘗試訪問受保護資源時被攔截,他應該在成功登錄時到達那裏。如何實現這一目標? –

+0

好的。問題是命名空間屬性不適用,因爲您正在使用自定義類覆蓋該行爲。設置類本身的屬性並刪除'useReferer'。 –

+0

嗨盧克。請指導我如何去做。 –