Spring security personalized user authentication process: handling of success / failure of custom login

Keywords: Java JSON Session

1. User defined login processed successfully
What needs to be handled successfully is user-defined login, because there is more than one login behavior, which may be ajax request, and the default is form submit jump behavior, which is not a result we want at this time.

If you want to customize the behavior after successful login? Only the AuthenticationSuccessHandler interface needs to be implemented

@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);
    @Autowired
    private ObjectMapper objectMapper;

    //Will be called after successful login
    //Authentication is used to encapsulate our authentication information, including the authentication information (IP, Session, and implementation class information of UserDetails after authentication) in the authentication request,
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        logger.info("Login successfully");
        //Return authentication to the front desk
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(authentication));
    }

}

Modify the configuration information of BrowserSecurityConfig class again

Access request: http://localhost:8080/sign.html After the login is successful, all the user's information will be returned

{
authorities: [
{
authority: "admin"  //Role information of the user
}
],
details: {
remoteAddress: "0:0:0:0:0:0:0:1",  //IP that initiated the request
sessionId: null
},
authenticated: true,
principal: {   //Principle is the information in the implementation class of UserDetails
username: "admin",
password: "$2a$10$WPv2.mXiAPEaOXjAHP9jYuLNfbGT1Nk99Ix2fn351gZGKeEPiOTQW",
accountNonExpired: true,
accountNonLocked: true,
credentialsNonExpired: true,
enabled: true,
authorities: [
{
authority: "admin"
}
]
},
credentials: null,
name: "admin"
}

1. User defined login error handling
Implement the AuthenticationFailureHandler interface

@Component("myAuthenticationFailHandler")
public class MyAuthenticationFailHandler implements AuthenticationFailureHandler {

    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationFailHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    //AuthenticationException record, user name not found, password does not match all the errors in the process of information authentication
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {
        logger.info("Login failed");
        //Return the exception to the front desk
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(exception));
    }

}

Exception subclass under AuthenticationException

You also need to configure the BrowserSecurityConfig configuration class

Access request: http://localhost:8080/sign.html After the login fails, the exception information will be returned

2. Configurable
It needs to be configurable. Some applications are form submission, which should be more flexible
Define the jump method in BrowserProperties

public enum LoginType {
    REDIRECT, //Jump
    JSON;     //JSON
}

public class BrowserProperties {
    //Standard login page. If other items are not configured, the default login configuration will be used
    private String loginPage = "/sign.html";
    private LoginType loginType = LoginType.JSON;//json returned by default
    //get/set
}

Since you need to jump to the page, you can't just implement the Success/FailHandler interface at this time.

@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{

    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SecurityProperties securityProperties;//Judge the return method of our request data: json/redirect

    //Will be called after successful login
    //Authentication is used to encapsulate our authentication information, including the authentication information (IP, Session, and implementation class information of UserDetails after authentication) in the authentication request,
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        logger.info("Login successfully");
        if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
            //Return authentication to the front desk
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(authentication));
        }else {
            //Jump
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }

}

@Component("myAuthenticationFailHandler")
public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {

    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationFailHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SecurityProperties securityProperties;

    //AuthenticationException record, user name not found, password does not match all the errors in the process of information authentication
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {
        logger.info("Login failed");
        if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {            
            //Return the exception to the front desk
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(exception));
        }else {
            //Jump back to page
            super.onAuthenticationFailure(request, response, exception);
        }
    }

}

Access request: http://localhost:8080/sign.html , login success and failure will return json

When the configuration is changed:

LoginType.REDIRECT;

Access request again: http://localhost:8080/sign.html , both success and failure of login will return to jump mode

Posted by Paghilom on Wed, 04 Dec 2019 11:30:05 -0800