Spring Security(4):パーソナライズされたユーザー認証プロセス

第3章では、さまざまな検証のためにデータベースからパスワードをすでに見つけることができますが、さまざまなログイン認証プロセスでは、それでも単調であり、エンタープライズレベルの開発ニーズを満たすことができません。この記事では、パーソナライズされたユーザー認証プロセスについて説明します。カスタムログインを含みます。ページ、カスタムログイン成功処理、カスタムログイン失敗処理。

カスタムログインページ

カスタマイズされたログインページ: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>

カスタムログインページを構成する

  • 前の章の.loginPage()構成項目で説明したBrowserSecurityConfigクラスで次の構成を構成します
	@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()/authentication/formデフォルトではなく、ログイン要求の形式に対処するためのコミットメント/login
  • なお、.anyRequestすべての要求が認証される必要があること、そして私達のログインページでは/meicloud-signIn.html、我々が設定する必要があるので、また、認証される必要があり.antMatchers("/meicloud-signIn.html").permitAll()、ログインページが傍受して認証される必要がないように。

カスタムログインの正常な処理

AuthenticationSuccessHandlerインターフェイスを実装し、onAuthenticationSuccess()メソッドを実装します

  • ただし、通常の状況では、このインターフェースを直接実装することはありません。通常、次のようにこのインターフェースの実装クラスを継承できるため、JSONや別のパスへのジャンプなど、フロントエンドへのリクエストの選択肢が増えます。
@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);
		}
	}
}
  • 次にBrowserSecurityConfig、構成クラスと回線.successHandler()構成で構成する必要があります
	@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();
	}

カスタムログイン失敗の処理

ログインの正常な処理と同様に、AuthenticationFailHandlerインターフェイスを実装し、onAuthenticationFailure()メソッドを実装します

  • 同様に、インターフェイスは直接実装されず、その実装クラスを継承できます 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);
        }

    }
}
  • またBrowserSecurityConfig.failureHandler()構成追加する必要があります
	@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();
	}

総括する

要求する 成し遂げる
カスタムログインページ http.formLogin()。loginPage( "/ meicloud-signIn.html")
カスタムログインの正常な処理 AuthenticationSuccessHandler
カスタムログイン失敗の処理 AuthenticationFailureHandler

おすすめ

転載: blog.csdn.net/qq_36221788/article/details/105478847