1.ユーザ認証プロセスフロー原理
1.1 AuthenticationFilter
- インターセプト・チェーン・モデルによれば、別のログインが異なるAuthenticationFilterを持っています
- アカウントのパスワードがログインするために使用した場合、となります
UsernamePasswordAuthenticationFilter
インターセプトに
- メソッドを作成オブジェクトを
UsernamePasswordAuthenticationFilter
attemptAuthentication()
UsernamePasswordAuthenticationToken
- UsernamePasswordAuthenticationFilter.java、アカウントのパスワードフィルタ
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);
return this.getAuthenticationManager().authenticate(authRequest);
}
- UsernamePasswordAuthenticationToken.java、オブジェクトを作成します
public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}
1.2 AuthenticationManager
AuthenticationManager
多くの管理を担当するAuthenticationProvider
これらのプロバイダは、異なるランディングアプローチの異なる較正手順を提供することができます
- 取得することにより
ProvicerManager
、その呼び出しauthenticate()
のすべてを通じてメソッドをチェックモードプロバイダーを検証するために、現在のログインモードをサポートするためのバリデータを取得します
- あなたはプロバイダーによって対応するログインを見つけるでしょう
provider.authenticate(authentication);
、プロバイダの提供を呼び出して検証チェックサムの道を
1.3 AuthenticationProvider
- ここでは一例として、アカウントのパスワードは、それを達成するために使用される
AbstractUserDetailsAuthenticationProvider
特定の実装クラスをDaoAuthenticationProvider
チェックサムを実行します。
- 検証プロセスが呼び出すメソッドを
AbstractUserDetailsAuthenticationProvider
authenticate
- 検証プロセスは3つの段階に分かれています。
preAuthenticationChecks.check(user);
アカウントがために事前チェックは、4つの方法UserDetailsインタフェースに応じて、有効になっているアカウントロックアウトの場合、アカウントは、期限が切れている状態チェック
additionalAuthenticationChecks();
,密码校验,该方法在是DaoAuthenticationProvider
中进行了实现,通过我们配置的PasswordEncoder进行密码校验
postAuthenticationChecks.check(user);
,后校验,检验密码是否过期;
- 用户认证成功后,就会根据我们提供的UserDetails信息,执行
createSuccessAuthentication(principalToReturn, authentication, user);
方法;
- 创建了一个新的
UsernamePasswordAuthenticationToken
对象,并以Authentication
的形式返回
- UsernamePasswordAuthenticationToken.java
public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
1.4 返回AuthenticationFilter处理登录结果
Authentication
保存最终认证成功的用户认证对象,该对象将返回到最开始的拦截器当中
- 最终返回拦截器链中的
AbstractAuthenticationProcessingFilter
,执行该过滤器的doFilter
方法
- 在doFilter中,执行
successfulAuthentication(request, response, chain, authResult);
来执行登录成功的处理器,
successHandler.onAuthenticationSuccess(request, response, authResult);
登录成功处理器执行登陆成功的业务逻辑;
- 如果在这个认证过程中出现失败都会抛出异常并被过滤器捕获,执行登录失败处理器
2.在多个请求中共享认证结果原理
- 在用户认证流程过程中,若认证成功的认证信息最后会传回到认证拦截器链当中,并在doFilter中执行
successfulAuthentication(request, response, chain, authResult);
,去调用我们自定义的认证成功处理器,在调用认证成功处理器之前有一句代码是将用户信息传入SecurityContext
的
SecurityContextHolder.getContext().setAuthentication(authResult);
- SecurityContext是用来包装Authentication对象而已
- SecurityContextHodler来获取容器保存用户认证信息,这里的SercurityContextHolder可以视为一个线程级别的变量对象,可被多个线程所共享;、
- 在拦截器链的最开始,有一个拦截器叫
SecurityContextPersistenceFilter
,它的作用有两个
- 要求が入ってきた場合:セッションのチェック、それはアウトになる場合は、要求スレッドを入れ、SecurityContextがセッションが(すなわち、ユーザ認証情報がない)かどうかを判断します。
- リクエストが完了**戻り値のとき:そこたSecurityContextは**セッションにスレッド、認証情報を確認しています
ユーザー認証情報を入手3.
- この方法の一つ:
SecurityContextHolder.getContext().getAuthentication()
- 方法2:コントローラのパラメータで、自動的に注入ユーザ認証情報に型宣言認証、SPRINGMVC米国。
@GetMapping("/authentication")
public Authentication getUser(Authentication authentication){
return authentication;
}
@GetMapping("/userDetail")
public UserDetails getUser(@AuthenticationPrincipal UserDetails userDetails){
return userDetails;
}