02 spring security custom user authentication process

1. Custom login page

(1) First create static login.html in the following directory

       Note: springboot project default access to resources / resources, resources / staic, resources / public static files directory

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form action="/auth/login" method="post">
    用户名:<input type="text" name="username">
    <br/><Code:& emsp;
    Adhesioninput type="password" name="password">
    <br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

 

(2) following configurations spring securiy configuration class

  @Override
     protected  void the configure (HttpSecurity HTTP) throws Exception { 
        http.formLogin () 
                // specify a custom login page 
                .loginPage ( "/ login.html" )
                 // login url 
                .loginProcessingUrl ( "/ auth / the Login" ) 
                .AND () 
                .authorizeRequests () 
                // add a url matcher, if matched to login.html, to authorize 
                .antMatchers ( "/ login.html" ) .permitAll () 
                .anyRequest () 
                .authenticated () 
                .AND () 
                / / close spring security default anti csrf attack
                .csrf().disable();
    }

(3) Testing

slightly

 

(4) problems

 <1> as the login module can be reused, we should provide personalized login page, which means that only the dead can not write Jump to login.html.

    This problem is better solved using the login page to configure the default login.html to use.

 <2> Jump to login.html login page request, seemingly no problem, but as a restful style interface, the general response is json data format, in particular app request.

    Solving ideas: the user initiates a data request -> security needs to determine whether authentication -----> Jump to a custom controller method ------> determine whether the method is in html initiated request, If so, it jumps to the login.html, if not, a response json data format, the error message described.

 

Custom Controller

SLF4J @ 
@RestController 
public  class the LoginController { 

    / ** 
     * request buffer 
     * / 
    Private RequestCache requestCache = new new HttpSessionRequestCache (); 

    / ** 
     * Redirection tools 
     * / 
    Private RedirectStrategy redirectStrategy = new new DefaultRedirectStrategy (); 

    / ** 
     * If the configuration login page to log in using surface configuration, otherwise use the default login page 
     * / 
//     @Value ( "{$ xxxx: defaultLoginPage}")
 //     Private String standardLoginPage; 
    Private String standardLoginPage = "/login.html";   / / login page 

    / ** 
     * user authentication methods 
     * /
    @GetMapping("/user/auth")
    @ResponseStatus(code = HttpStatus.UNAUTHORIZED)  // 返回状态
    public ResponseData login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if (savedRequest != null) {
            String targetUrl = savedRequest.getRedirectUrl();
            log.info("请求是:" + targetUrl);
            // 如果请求是以html结尾
            if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) { 
                RedirectStrategy.sendRedirect (Request, the Response, standardLoginPage); 
            } 
        } 
        return  new new ResponseData ( "need to log in to the request, the response I get after js data, the need to jump to the login page you can figure it out?" ); 
    } 
}

 

spring security login method to the authorization controller

@Override
     protected  void the configure (HttpSecurity HTTP) throws Exception { 
        http.formLogin () 
                // advanced controller to go 
                .loginPage ( "/ the User / auth" )
                 // Specify a custom login page 
                .loginPage ( "/ login.html" )
                 // login url 
                .loginProcessingUrl ( "/ auth / the Login" ) 
                .AND () 
                .authorizeRequests () 
                // the controller requires authorization 
                .antMatchers ( "/ the User / auth" ) .permitAll ()
                 // add a url matcher, If a match to login.html, on authorization
                .antMatchers ( "/ the login.html" ) .permitAll () 
                .anyRequest () 
                .authenticated () 
                .AND () 
                // turn off default spring security attack prevention csrf 
                .csrf () disable ();. 
    }

Like this on the line! ! !

   

2. Customize the login process successfully (return json)

 (1) achieve AuthenticationSuccessHandler.java

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    private ObjectMapper objectMapper;
    /**
     * Called when a user has been successfully authenticated.
     * @param request
     * @param response
     * @param authentication
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        log.info("登录成功!!!");
        // 将登录成功的信息写到前端
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.getWriter().write(objectMapper.writeValueAsString(authentication));

    }
}

 

(2) modify the security configuration class

    @Autowired
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                // 先进controller中去
                .loginPage("/user/auth")
                // 指定自定义登录页面
                .loginPage("/login.html")
                // 登录url
                .loginProcessingUrl("/auth/login")
                .successHandler(myAuthenticationSuccessHandler)
                .and()
                .authorizeRequests()
                // The controller requires authorization 
                .antMatchers ( "/ the User / auth" ) .permitAll ()
                 // add a url matcher, if matched to login.html, to authorize 
                .antMatchers ( "/ login.html" ) .permitAll ( ) 
                .anyRequest () 
                .authenticated () 
                .AND () 
                // turn off default spring security attack prevention csrf 
                .csrf () disable ();. 
    }

 

(3) Testing

 

 Description: authentication information contained in the object will change because of different login occurs

 

3. Customize the login process fails (returns json)

  AuthenticationFailureHandler.java interface can achieve, with logon success or failure of processing the same configuration.

 

4. Custom successful login processing logic

 More login success or failure is returned json, but in some cases, there is a sign in the success or failure for page Jump (spring security default processing mode), then this is not appropriate way to return json a. Therefore, we should do more flexible, made configurable.

 For successful login logically requires only MyAuthenticationSuccessHandler.java modified slightly on the line, the code is as follows:

/**
 * SavedRequestAwareAuthenticationSuccessHandler spring security 默认的成功处理器
 */
@Slf4j
@Component
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 配置的登录方式
     */
//    @Value("${xxx:默认方式}")
    private String loginType = "JSON";
    /**
     * Called when a user has been successfully authenticated.
     */
    @Override
    public voidonAuthenticationSuccess (Request the HttpServletRequest, HttpServletResponse the Response, Authentication authentication) throws IOException, ServletException { 
        log.info ( "Login successful !!!" ); 

        // If the configuration of login is JSON, json data returned 
        IF ( "JSON" .equals (LoginType)) {
             // the success of login information is written to the front 
            response.setContentType (MediaType.APPLICATION_JSON_VALUE); 
            . response.getWriter () the Write (objectMapper.writeValueAsString (authentication)); 
        } the else {   // otherwise, use the default Skip mode 
            Super .onAuthenticationSuccess (Request, Response, authentication); 
        }  
    }
}

 

The custom login failure processing logic

 Login with similar success, specific code as follows:

 

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@Component
public class MySimpleUrlAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 配置的登录方式
     */
//    @Value("${xxx:默认方式}")
    private String loginType = "JSON";
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        log.info ( "Login failed!" ); 

        // If the login configuration is JSON, json data returned 
        IF ( "JSON" .equals (LoginType)) {
             // The login information is written to the front end of a successful 
            response .setStatus (HttpStatus.UNAUTHORIZED.value ()); 
            the response.setContentType (MediaType.APPLICATION_JSON_VALUE); 
            response.getWriter () Write (objectMapper.writeValueAsString (Exception));. 
        } the else {   // otherwise, use the default jump method to jump to an error page 
            Super .onAuthenticationFailure (Request, Response, Exception); 
        } 
    } 
}

 

 @Autowired
    private MySimpleUrlAuthenticationFailureHandler mySimpleUrlAuthenticationFailureHandler;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                // 先进controller中去
                .loginPage("/user/auth")
                // 指定自定义登录页面
                .loginPage("/login.html")
                // 登录url
                .loginProcessingUrl("/auth/login")
                .successHandler(myAuthenticationSuccessHandler)
                .failureHandler(mySimpleUrlAuthenticationFailureHandler)
                .AND () 
                .authorizeRequests () 
                // The controller requires authorization 
                .antMatchers ( "/ the User / auth" ) .permitAll ()
                 // add a url matcher, if matched to login.html, to authorize 
                .antMatchers ( "/ the login.html " ) .permitAll () 
                .anyRequest () 
                .authenticated () 
                .AND () 
                // turn off default spring security attack prevention csrf 
                .csrf () disable ();. 
    }

 

Guess you like

Origin www.cnblogs.com/z-qinfeng/p/11780022.html