简体   繁体   中英

spring security custom AuthenticationSuccessHandler

I am using spring security for an e commerce project. We got a requirement to maintain login history. Since j_spring_security_check internally handles the authentication and authorization. The only way that I could find was to have a custom AuthenticationSuccessHandler to save the history of the successful login. I read some posts and got a perfect answer but with a bug. Following is my configuration:

<?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>

following is my implementation of the 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);
    }
    }

I am now able to maintain the history and everything works fine if user demands for a page which is protected. But when user explicitly goes to login page and puts the credentials he is redirected again to the same login page while he should be redirected to default post login page as per my configuration.

Please help me out to figure out this problem and suggest a possible solution

Thanks, Rohit Mishra

Your configuration doesn't set a default post-login page. You have set useReferer to be true , which means the user will be redirected to the page they came from. If that is the login page they will be sent back there afterwards. Try removing this.

Depending on your requirements, you can control the redirect destination by other means such as by setting the defaultTargetUrl - see the docs for the class for more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM