春の公式文書では、この論文の翻訳は基本的な概念とSSとの原則の基本的なインタフェースを紹介しています。
春のセキュリティの2つのコアコンセプト:認証(検証)、許可(承認);春のセキュリティのOAuth、OpenIDの間のこのような認証を実現するために使用することができ、LDAP、CAS、JAAS認証システムは以下のようです。我々はOAuthをして春のセキュリティを使用することができた場合は、シングルサインオンを実現します。
認証検証
認証主要的接口是AuthenticationManagerパブリックインターフェースAuthenticationManager {認証の認証(認証認証)が含むAuthenticationExceptionをスロー。}
3つの方法で()メソッドの呼び出しを認証:
- 確認済み、通常の認証インスタンスへの復帰
- 認証は含むAuthenticationExceptionをスローし、失敗しました
- 決めることができない、最も一般的に使用されるAuthenticationManagerはヌルインターフェイスのクラスを返すproviderManagerのある、内部providerManagerの検証AuthenticationProviderのシリーズに委託されます。ビットAuthenticationManagerインターフェイスのようなインターフェイスAuthenticationProvider、彼は余分な方法を有することは、所与の認証サポート認証インスタンス型がメソッドをサポートしているかどうかを決定するために、呼び出し側は、次の方法であることができます。
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
boolean supports(Class<?> authentication);
}
复制代码
providerManagerのは、検証AuthenticationProviderのシリーズに委託され、それが実際にAuthenticationProviderリストであるので、彼は一つのアプリケーションで複数の認証ポリシーをサポートすることができます。検証は、すべてのAuthenticationProviderが一つずつ検証横断するときに、呼び出し元は、認証のタイプかどうかを判断する検証方法をサポートしていますが、実際に検証がそうでない場合はスキップします。すべてAUthenticationProviderがnullを返すように決めることができない場合(親が空でない場合)、その後、親AuthenticationManager検証を呼び出します。時には、アプリケーションロジックの検証パケットに、各パケットは独自のを持ってAuthenticationManager(通常providerManagerの)、親AuthenticationManagerを共有するパケット。
カスタムAuthenticationManager
SpringSecurity構成が最も一般的に使用される、AuthenticationManagerの機能を行くと取得するには、いくつかのヘルパークラスを提供しAuthenticationManagerBuilderあり、それは、インメモリJDBC、LDAPコンフィギュレーションモードのユーザの詳細、またはカスタムUserDetailServiceを追加することができます。例えば。
@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
... // web stuff here
@Override
public configure(AuthenticationManagerBuilder builder) {
builder.jdbcAuthentication().dataSource(dataSource).withUser("dave").password("secret").roles("USER");
}
}
复制代码
???公式のコード例はすべて正しいと春、設定方法は、型を返しません。
認可認可
認可プライマリインターフェイスの承認は、AccessDecisionManagerある三つのカテゴリーを達成するためのフレームワークを提供します:UnanimousBased(すべてを介して)、ConsensusBased(過半数)、AffirmativeBased(スルーには何の毛)、これらのクラスのすべてが委任状にを達成するためにありますシリーズAccessDecisionVoterは、それがAuthenticationProviderに委託検証のビットproviderManagerのようなものです。ここでは、抽象AccessDecisionVoter有権者です。
public interface AccessDecisionVoter<S> {
boolean supports(ConfigAttribute attribute);
boolean supports(Class<?> clazz);
int vote(Authentication authentication, S object, Collection<ConfigAttribute> attributes);
}
复制代码
AccessDecisionVoterは、検証本体認証とセキュリティオブジェクトがConfigAttributesがオブジェクトに変更されて検討していきます。オブジェクトが完全に汎用的であるとAccessDecisionManager AccessDecisionVoterに署名は、オブジェクトの代わりに、すべてのものは、ユーザーが(通常はネットワークリソースまたはJavaクラスのメソッドは、両方のケースで呼び出して)アクセスすることができます。ConfigAttributesは、セキュリティオブジェクト、アクセスセキュリティのアクセス許可レベルを決定するために必要なメタデータオブジェクトの変更を表現するためにいくつかのメタデータでも共通です。ConfigAttributeはインタフェースであり、それはごく一般的な方法であり、文字列を返すので、これらの文字列は、何らかの方法でリソースの所有者の意図をエンコード、セキュリティオブジェクトへのアクセスを許可するユーザーに明示ルール。典型的なConfigAttributeは、(ROLE_ADMINまたはROLE_AUDITなど)、ユーザーの役割名で、彼らは通常、特別なフォーマット(例えばROLE_プレフィックスとして)またはニーズアセスメントを表す式を持っています。ほとんどの人は単にデフォルトの実装クラスAccessDecisionManager AffirmativeBasedを(何の反対を渡すことが許されない)を使用し、任意のカスタム有権者は体にどうなる、または新規追加や既存の作業を変更します。ConfigAttributeは、EL式を使用して非常に一般的で、例えばisFullyAuthenticated() && hasRole('FOO')
、これは表現を処理し、そのAccessDecisionVoterをサポートするためのコンテキストを作成することができます。扱うことができる表現の範囲を拡張するには、達成するためにSecurityExpressionRootをカスタマイズする必要がある、と時々 SecurityExpressionHandlerを必要としています。
Webセキュリティ
春のセキュリティ層の図は、典型的な階層的な単一のHTTPリクエストハンドラを示し、Webベースのサーブレットフィルタで使用されています。
クライアントアプリケーションは、コンテナはURIとサーブレットルート要求に応じてフィルタを見つけるために適用されるアプリケーションに要求を送信した場合。唯一の要求を処理するサーブレットを持っていますが、フィルタのチェーンであることができ、フィルタ処理は、実際には、フィルタを使用して、フィルター・チェーンを切断するための独自の要求に対処したい場合は、オーダーです。フィルタはまた、下流の使用要求と応答フィルタを変更することができます。次のフィルタチェーンが2にメカニズムを提供するために重要な、春ブーツです:最初は、注釈や@Order実現発注インタフェースの使用で、他のFilterRegistrationBeanの一環として、FilterRegistrationBeanのAPI自体は順序です。いくつかは、すぐ定数フィルタによって定義され、互いのシステム(例えば、チェーン内の以前のようにそれを教えてくれる定数DEFAULT_ORDER SessionRepositoryFilter =はInteger.MIN_VALUE + 50への注文を相対的に表現するが、それは他のフィルタを排除するものではありません)その前インチ スプリングセキュリティフィルタチェーンは、以下に示すようなフィルタは、FilterChainProxyあり、入口としてスプリングセキュリティアクセスノードです。 スプリングセキュリティ名でスプリングセキュリティ、以下、安全フィルタの内部にここでの処理を介して内部フィルタに委ねプロキシ・フィルタ・チェーン、(ある、フィルタノードFilterChainProxyにおける要求処理フィルタチェインに挿入しましたデバイス)。実際には、フィルタ内のセキュリティDelegatingFilterProxyのさえ層が、それは通常、標準および安全性の懸念フィルタ間剤であり、FilterChainProxyは、それに委ね、それは必ずしも春豆FilterChainProxyである、のSpring Beanである必要はありません。それは、一般的にSpringコンテナにFilterChainProxyライフサイクル管理です。FilterChainProxyチェーンがチェーンに整合最初のフィルタに要求を分散、フィルタのリストを含む、下の図は、要求に一致する唯一の方法が一般的であるマッチング・パスに基づいて、スケジューリング要求を示しているが、ではありません。スケジューリングプロセスは、その要求を処理するだけチェーンで最も重要な機能です。カスタムフィルタのチェーンを作成します。
デフォルトのフォールバックフィルタチェーン(一致/ **)春ブートアプリケーション所定のシーケンス(SecurityProperties.BASIC_AUTH_ORDER)は、あなたはそれを閉じることが= falseをsecurity.basic.enabledすることができますし、フォールバックとして使用することができますフィルターあなただけの他のルールの下位にマッチするフィルタを定義します。これを行うには、単にWebSecurityConfigurerAdapter(またはWebSecurityConfigurer)@Bean、使用のタイプを追加し、クラス@Orderのコメントを変更します。例えば:
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/foo/**")
...;
}
}
复制代码
そして、認証要求のスケジューリングをマッチング
安全フィルタチェーン(または同等WebSecurityConfigurerAdapter)HTTPリクエストを適用するかどうかを決定するためのマッチング要求があります。特定のフィルタ・チェーンを適用することを決定したら、他のフィルタ・チェーンに適用されることはありません。しかし、フィルタチェインに、あなたは、許可をよりきめ細かく制御にHttpSecurityコンフィギュレータ内の余分な一致を設定することができます。例:
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/foo/**")
.authorizeRequests()
.antMatchers("/foo/bar").hasRole("BAR")
.antMatchers("/foo/spam").hasRole("SPAM")
.anyRequest().isAuthenticated();
}
}
复制代码
誤って設定春のセキュリティは、これらの試合は、異なるプロセスに適していることを忘れコミットする可能性が最も高い、要求がちょうど適用する別のアクセスルールを選択し、マッチャー全体のフィルタ・チェーンです。
安全規則との組み合わせの実施のための規則の適用はスキップされ、当分の間、春ブーツアクチュエータコンテンツを含み
メソッドのセキュリティ
Webアプリケーションのサポートに加えて、春のセキュリティは、実行の方法にJavaアプリケーションのアクセスルールをサポートしています。SPINGセキュリティのためだけの資源保護のタイプに意味がありません。ユーザーのために、これは(例えばロールまたは発現など)が同じフォーマットConfigAttribute列ステートメントアクセスルールを使用して、コード内の異なる位置を意味します。最初のステップは、次のような効果を取るために安全な方法を作ることです。
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SampleSecureApplication {
}
复制代码
その後、我々は、次のようなリソースの変更方法を、指示することができます:
@Service
public class MyService {
@Secured("ROLE_USER")
public String secure() {
return "Hello Security";
}
}
复制代码
この例では、サービスの安全な方法です。春は@Beanのこのタイプを作成する場合は、エージェントになり、呼び出し側は実際の実行方法前に、セキュリティインターセプターを通過しなければなりません。アクセスが拒否された場合、呼び出し側は実際の方法の結果ではなく、AccessDeniedException例外を受け取ります。彼らはあなたがそれぞれのメソッドのパラメータが含まれていると表現参照の値を返す記述することができ、他の注釈方法は、セキュリティ上の制約、特に@PreAuthorizeと@PostAuthorizeを強制するために使用することができますがあります。
スレッドでの作業
下流の消費者の多様な認証された電流を施す必要があるため春のセキュリティは、基本的にスレッド結合である基本的なビルディングブロックはSecurityContextがあり、利用可能であるユーザがログインするとき、それは、(認証が含まれていてもよいですそれは)認証による検証です。あなたはいつもSecurityContextHolder静的な便利な方法でSecurityContextがアクセスして操作することができます。例えば:
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
assert(authentication.isAuthenticated);
复制代码
あなたが現在認証されたネットワークのエンドポイントユーザにアクセスする必要がある場合は、例えば@RequestMappingのパラメータを、使用することができます。
@RequestMapping("/foo")
public String foo(@AuthenticationPrincipal User user) {
... // do stuff with user
}
复制代码
コメントは認証たSecurityContextから引かれ、メソッドのパラメータを生成するために、彼らのgetPrincipal()メソッドを呼び出すされている場合。認証は、認証を検証するために使用される主要なAuthenticationManagerの種類に依存し、これは、ユーザ・データ・セキュリティのタイプに関する有用なヒントを得るための基準であるかもしれません。あなたはHttpServletRequestのから春のセキュリティプリンシパルを使用している場合は、それを直接使用することができますので、それは、認証タイプになります。
@RequestMapping("/foo")
public String foo(Principal principal) {
Authentication authentication = (Authentication) principal;
User = (User) authentication.getPrincipal();
... // do stuff with user
}
复制代码
非同期セキュアなメソッドの処理
SecurityContextがあるので、あなたは、このような@Asyncを使用するなどの任意のコールセキュリティメソッドを処理するバックグラウンドを実行したい場合は、スレッドが結合した、あなたはコンテキストが普及することを確認する必要があります。これは、バックグラウンドで、タスク(Runnableを、呼び出し可能、など)とSecurityContextがパッケージに起因することができます。スプリングセキュリティは、Runnableを、呼び出し可能ラッパーとして、プロセスを簡略化するためにアシスタントの数を提供します。@Async方法にSecurityContextがスプレッドに、あなたは確かに正しい型の執行をAsyncConfigurerを提供する必要があり、かつ:
@Configuration
public class ApplicationConfiguration extends AsyncConfigurerSupport {
@Override
public Executor getAsyncExecutor() {
return new DelegatingSecurityContextExecutorService(Executors.newFixedThreadPool(5));
}
}
复制代码
ます。https://juejin.im/post/5cf09fa46fb9a07eaf2b7709で再現