フィルター・チェーンの一連の、認証と承認を行うために、主にセキュリティを1.spring。
次のように認定プロセスは次のとおりです。
デフォルトのセキュリティ認証プロセスのフィルタを行うUsernamePasswordAuthenticationFilter、AbstractAuthenticationProcessingFilter、ファーストクラスの実行AbstractAuthenticationProcessingFilter継承クラス
そのようなソースコードdofiterとしてのdoFilter方法。
IOException {ServletExceptionがスローのdoFilter公開(のServletRequestのREQ、たServletResponse RESをれるFilterChainカテナalberghiera)無効
; HttpServletRequestのリクエスト=(HttpServletRequestの)REQ
HttpServletResponseの応答=(HttpServletResponseの)RESを;
// 1は、現在のフィルタは、現在の要求ではなく処理することができるか否かを判断します。もし次のフィルタへ処理
IF {(this.requiresAuthentication(リクエスト、レスポンス)!)
chain.doFilter(リクエスト、レスポンス);
} {他
IF(this.logger.isDebugEnabled()){
this.logger.debug( )「要求処理の認証には」;
}
認証authResult;
試み{
実UsernamePasswordAuthenticationFilterから抽象メソッドの/ **サブクラス
AttemptAuthenticationは現在、主にそれらのクラス継承UsernamePasswordAuthenticationFilter実際のニーズに応じて、メソッドのオーバーライドattemptAuthentication認証情報を取得
** /
; authResult = this.attemptAuthentication(リクエスト、レスポンス)
IF(authResult == NULL){
リターン;
}
//認証をセッションに関連付けられているいくつかの方法の成功した治療後
this.sessionStrategy.onAuthentication(authResult、要求、応答);
}キャッチ(InternalAuthenticationServiceExceptionがvar8){
this.logger.error(「ユーザをしようとしたときにアン内部エラーは、認証に発生しました。」がvar8);
//認証に失敗した後、いくつかの操作
this.unsuccessfulAuthentication(要求、応答、がvar8);
リターン;
}キャッチ(含むAuthenticationExceptionのvar9){
this.unsuccessfulAuthentication(要求、応答、var9);
リターン;
}
IF(this.continueChainBeforeSuccessfulAuthentication){
chain.doFilter(リクエスト、レスポンス)。
}
SecurityContextHolderに現在の認証に主に関連する成功した認証方法の後//コールバック
this.successfulAuthentication(要求、応答、カテナalberghiera、authResult);
}
}
AbstractAuthenticationProcessingFilterクラスのdoFilterは主に行わUsernamePasswordAuthenticationFilterクラスattemptAuthenticationの方法のソースコード:
パブリッククラスUsernamePasswordAuthenticationFilterはAbstractAuthenticationProcessingFilterを拡張{
パブリック静的最終列SPRING_SECURITY_FORM_USERNAME_KEY =「ユーザ名」。
public static final文字列SPRING_SECURITY_FORM_PASSWORD_KEY = "パスワード";
プライベート文字列usernameParameterは、「ユーザー名」=;
プライベート文字列passwordParameterは、「パスワード」を=。
プライベートブールpostOnly =はtrue。
公共UsernamePasswordAuthenticationFilter(){
スーパー(新AntPathRequestMatcher( "/ログイン"、 "POST"));
}
公共認証attemptAuthentication(HttpServletRequestのリクエスト、HttpServletResponseの応答)を含むAuthenticationException {スロー
場合(this.postOnlyは&&!
スローは新しい新AuthenticationServiceException(「認証方法がサポートされていません:」+ request.getMethod());
}他{
//リクエストからユーザー名要求の値を取得
文字列名= this.obtainUsername(要求);
リクエストから//パスワード取得要求を値
文字列のパスワード= this.obtainPassword(要求);
IF(ユーザ名== NULL){
ユーザー名= "";
}
IF(パスワード== NULL){
パスワード= ";"
}
名= username.trim();
// UsernamePasswordAuthenticationTokenオブジェクトへのパッケージの利用者が要求したユーザー名とパスワード、(など、ユーザー名、パスワード、セッション、)ロール情報によりオブジェクトを構築
UsernamePasswordAuthenticationTokenてauthrequest =新しいUsernamePasswordAuthenticationToken(ユーザ名、パスワード);
this.setDetails(要求てauthrequest)。
リターンthis.getAuthenticationManager()認証(てauthrequest)。
}
}
重要であることに留意すべきであるスーパー((コレクション)NULL);コレクションには始まりと認証がないので、それにnullを渡された権限のリストを表し、ユーザーはこの時点ですべての権限を持っている、と設定されていないので、認証情報がされていないsetAuthenticated (偽);
UsernamePassworkAuthenticationFilter attemptAuthentication()メソッドに戻るには、あなたは()メソッドgetAuthenticationManagerと呼ばれる最後のメソッドを参照してください、その後、実装クラスproviderManagerのAuthenticationManagerインターフェイスを入力することができます。
補足:AuthenticationManagerは、ユーザー名とパスワードの認証が含まれていませんが、AuthenticationProviderを管理するために、すべての検証ルールがでAuthenticationProviderで書かれています。
然后执行ProciderManager中authenticate方法,该方法中主要执行AuthenticationProvider类中authenticate方法,用户的信息权限的验证就在该类中校验,可根据实际需要实现AuthenticationProvider接口,重写authenticate方法
进入 ProviderManager 类后会调用 authenticate(Authentication authentication) 方法,它通过 AuthenticationProvider 实现类获取用户的登录的方式,然后会有一个 while 迭代器模式的循环遍历,检查它是否支持这种登录方式,具体的登录方式有表单登录,qq登录,微信登录等。如果最终都不支持会抛出相应的异常信息,如果支持则会进入AuthenticationProvider 接口的抽象实现类 AbstractUserDetailsAuthenticationProvider 中。
AbstractUserDetailsAuthenticationProvider 类后会调用 authenticate(Authentication authentication) 方法源码如下:
进入 AbstractUserDetailsAuthenticationProvider 类后会调用 authenticate(Authentication authentication) 方法对用户的身份进行校验,首先是判断用户是否为空,这个 user 是 UserDetail 的对象,如果为空,表示还没有认证,就需要调用 retrieveUser 方法去获取用户的信息,这个方法是抽象类 AbstractUserDetailsAuthenticationProvider 的扩展类DaoAuthenticationProvider 的一个方法。
DaoAuthenticationProvider中retrieveUser源码如下:
在该扩展类中,retrieveUser调用UserDetailsService接口实现类中的loadUserByUsername方法去获取用户信息,所以本地可以实现UserDetailsService接口,在这个实现类中,编写自己的逻辑