Spring Security (four): personalized user authentication process

Chapter 3 can already find out the password from the database for various verifications, but for various login authentication processes, it is still monotonous and cannot meet our enterprise-level development needs. This article will deal with a personalized user authentication process. Including custom login page, custom login success processing, custom login failure processing.

Custom login page

Customized login page: meicloud-signIn.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
	<h2>标准登录页面</h2>
	<h3>表单登录</h3>
	<form action="/authentication/form" method="post">
		<table>
			<tr>
				<td>用户名:</td> 
				<td><input type="text" name="username"></td>
			</tr>
			<tr>
				<td>密码:</td>
				<td><input type="password" name="password"></td>
			</tr>
			<tr>
				<td colspan="2"><button type="submit">登录</button></td>
			</tr>
		</table>
	</form>
</body>
</html>

Configure a custom login page

  • Configure the following configuration in BrowserSecurityConfig class we talked about in the previous chapter .loginPage()configuration items
	@Override
	protected void configure(HttpSecurity http) throws Exception {
    
    
		http.formLogin()
				// 使用自定义的表单登录页面
				.loginPage("/meicloud-signIn.html")
				// 以下这行 UsernamePasswordAuthenticationFilter 会知道要处理表单的 /authentication/form 请求,而不是默认的 /login
				.loginProcessingUrl("/authentication/form")
				.and()
				.authorizeRequests()
				// 排除对 "/meicloud-signIn.html" 的身份验证
				.antMatchers("/meicloud-signIn.html").permitAll()
				// 表示所有请求都需要身份验证
				.anyRequest()
				.authenticated()
				.and()
				.csrf().disable();// 暂时把跨站请求伪造的功能关闭掉
	}
  • .loginProcessingUr()Commitment to address the form of /authentication/formlogin requests, instead of the default/login
  • It should be noted that it .anyRequestmeans that all requests need to be authenticated, and our login page /meicloud-signIn.htmlalso needs to be authenticated, so we need to configure .antMatchers("/meicloud-signIn.html").permitAll()so that the login page does not need to be intercepted and authenticated.

Custom login successful processing

Implement AuthenticationSuccessHandlerinterface, implement onAuthenticationSuccess()method

  • But under normal circumstances, you will not directly implement this interface. Generally, you can inherit the implementation class of this interface, as follows, so that there are more choices for requests to the front end, such as JSON or jumping to another path.
@Component("meicloudAuthenticationSuccessHandler")
public class MeicloudAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    
    

	private Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private ObjectMapper objectMapper;
	@Autowired
	private SecurityProperties securityProperties;
	private RequestCache requestCache = new HttpSessionRequestCache();

	/**
	 * 登录成功处理
	 * @param authentication 封装认证信息,包括认证请求信息,ip、session信息等,还包括认证通过以后,自定义的UserDetailService返回的UserDetails信息
	 */
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
    
    
		logger.info("登录成功");

		if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getSignInResponseType())) {
    
    
			response.setContentType("application/json;charset=UTF-8");
			String type = authentication.getClass().getSimpleName();
			response.getWriter().write(objectMapper.writeValueAsString(new SimpleResponse(type)));
		} else {
    
    
			// 如果设置了meicloud.security.browser.singInSuccessUrl,总是跳到设置的地址上
			// 如果没设置,则尝试跳转到登录之前访问的地址上,如果登录前访问地址为空,则跳到网站根路径上
			if (StringUtils.isNotBlank(securityProperties.getBrowser().getSingInSuccessUrl())) {
    
    
				requestCache.removeRequest(request, response);
				setAlwaysUseDefaultTargetUrl(true);
				setDefaultTargetUrl(securityProperties.getBrowser().getSingInSuccessUrl());
			}
			super.onAuthenticationSuccess(request, response, authentication);
		}
	}
}
  • Then you need to BrowserSecurityConfigbe configured in the configuration class, plus a line .successHandler()configuration
	@Override
	protected void configure(HttpSecurity http) throws Exception {
    
    
		http.formLogin()
				.loginPage("/meicloud-signIn.html")
				.loginProcessingUrl("/authentication/form")
				// 配置成功处理
				.successHandler(meicloudAuthenticationSuccessHandler)
				.and()
				.authorizeRequests()
				.antMatchers("/meicloud-signIn.html").permitAll()
				.anyRequest()
				.authenticated()
				.and()
				.csrf().disable();
	}

Custom login failure handling

Similar to the successful processing of login, implement the AuthenticationFailHandler interface and implement the onAuthenticationFailure()method

  • In the same way, the interface will not be implemented directly, and its implementation class can be inherited SimpleUrlAuthenticationFailureHandler
 @Component("meicloudAuthenctiationFailureHandler")
class MeicloudAuthencationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    
    

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private SecurityProperties securityProperties;

    /**
     * 登录失败处理
     * @param exception 包含了登录错误时的异常,包括用户名没找着、密码不正确等等
     */
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
    
    

        logger.info("登录失败");

        if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getSignInResponseType())) {
    
    
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(new SimpleResponse(exception.getMessage())));
        }else{
    
    
            super.onAuthenticationFailure(request, response, exception);
        }

    }
}
  • Also you need to BrowserSecurityConfigadd the .failureHandler()configuration
	@Override
	protected void configure(HttpSecurity http) throws Exception {
    
    
		http.formLogin()
				.loginPage("/meicloud-signIn.html")
				.loginProcessingUrl("/authentication/form")
				// 配置成功处理
				.successHandler(meicloudAuthenticationSuccessHandler)
				.failureHandler(meicloudAuthenticationFailureHandler)
				.and()
				.authorizeRequests()
				.antMatchers("/meicloud-signIn.html").permitAll()
				.anyRequest()
				.authenticated()
				.and()
				.csrf().disable();
	}

to sum up

demand achieve
Custom login page http.formLogin().loginPage("/meicloud-signIn.html")
Custom login successful processing AuthenticationSuccessHandler
Custom login failure handling AuthenticationFailureHandler

Guess you like

Origin blog.csdn.net/qq_36221788/article/details/105478847