【问题标题】:spring security custom AuthenticationSuccessHandler春季安全自定义AuthenticationSuccessHandler
【发布时间】:2015-07-30 02:05:12
【问题描述】:

我正在将 Spring Security 用于电子商务项目。我们需要维护登录历史记录。 由于 j_spring_security_check 在内部处理身份验证和授权。我能找到的唯一方法是使用自定义 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="/users/login"
                default-target-url="/products/list"
                authentication-failure-url="/users/login?error"
                username-parameter="username"
                password-parameter="password"
                authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
        <security:logout invalidate-session="true" logout-success-url="/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);
    }
    }

如果用户需要受保护的页面,我现在能够维护历史记录并且一切正常。 但是,当用户显式进入登录页面并输入凭据时,他会再次重定向到同一个登录页面,而根据我的配置,他应该被重定向到默认的登录后页面。

请帮我解决这个问题并提出可能的解决方案

谢谢, 罗希特·米什拉

【问题讨论】:

    标签: java authentication spring-security


    【解决方案1】:

    您的配置未设置默认登录后页面。您已将useReferer 设置为true,这意味着用户将被重定向到他们来自的页面。如果那是登录页面,他们将在之后被发送回那里。尝试删除它。

    根据您的要求,您可以通过其他方式控制重定向目标,例如通过设置defaultTargetUrl - 有关详细信息,请参阅docs for the class

    【讨论】:

    • 我已经设置了 default-target-url="/products/list"。我想要的行为是维护成功尝试的登录历史记录。所以我要求用户从登录页面登录并登陆到默认页面,同时我还希望如果用户在尝试访问受保护的资源时被拦截,他应该在成功登录时到达那里。如何做到这一点?
    • 好的。问题是命名空间属性不适用,因为您正在使用自定义类覆盖行为。在类本身上设置属性并删除useReferer
    • 嗨,卢克。请指导我如何做到这一点。
    • 找到了一个不知道是否是唯一解决方案的解决方法:
    猜你喜欢
    • 1970-01-01
    • 2017-03-05
    • 2011-03-07
    • 2013-12-22
    • 2013-02-24
    • 2014-02-02
    • 2012-12-13
    相关资源
    最近更新 更多