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