最新の安定バージョンについては、Spring Security 6.4.2 を使用してください! |
セキュリティ名前空間の構成
導入
名前空間構成は、Spring Framework のバージョン 2.0 以降で使用できます。これにより、従来の Spring Bean アプリケーションコンテキスト構文を、追加の XML スキーマの要素で補足できます。詳細については、Spring リファレンスドキュメント (英語) を参照してください。名前空間要素は、個々の Bean を構成するより簡潔なメソッドを可能にするために、またはより強力に、問題のドメインにより厳密に一致し、根本的な複雑さをユーザーから隠す代替構成構文を定義するために使用できます。単純な要素は、複数の Bean と処理ステップがアプリケーションコンテキストに追加されているという事実を隠すことができます。例: 次の要素をセキュリティ名前空間からアプリケーションコンテキストに追加すると、アプリケーション内での使用をテストするために組み込み LDAP サーバーが起動します。
<security:ldap-server />
これは、同等の Apache Directory サーバー Bean を接続するよりもはるかに簡単です。最も一般的な代替構成要件は、ldap-server
要素の属性によってサポートされており、ユーザーは、どの Bean を作成する必要があるか、Bean プロパティ名は何であるかについて心配する必要がありません。[ 1 ]。]。アプリケーションコンテキストファイルを編集する際に適切な XML エディターを使用すると、使用可能な属性と要素に関する情報が提供されます。Pleiades All in One (JDK, STS, Lombok 付属) または Spring Tools を備えた Eclipse IDE (英語) には、標準の Spring 名前空間を操作するための特別な機能があるため、試してみることをお勧めします。
アプリケーションコンテキストでセキュリティ名前空間の使用を開始するには、クラスパスに spring-security-config
jar が必要です。あとは、アプリケーションコンテキストファイルにスキーマ宣言を追加するだけです。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd">
...
</beans>
表示される多くの例(およびサンプルアプリケーション)では、デフォルトのネームスペースとして "beans" ではなく "security" を使用することがよくあります。つまり、すべてのセキュリティネームスペース要素のプレフィックスを省略して、読みやすい。また、アプリケーションコンテキストを別々のファイルに分割し、それらの 1 つにほとんどのセキュリティ構成がある場合にも、これを行うことができます。セキュリティアプリケーションコンテキストファイルは、このように起動します
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd">
...
</beans:beans>
この章では、この構文が今後使用されると想定します。
名前空間の設計
ネームスペースは、フレームワークの最も一般的な使用をキャプチャーし、アプリケーション内で有効にするための単純化された簡潔な構文を提供するように設計されています。この設計は、フレームワーク内の大規模な依存関係に基づいており、次の領域に分割できます。
Web/HTTP セキュリティ - 最も複雑な部分。フレームワーク認証メカニズムの適用、URL の保護、ログインページとエラーページのレンダリングなどに使用されるフィルターと関連サービス Bean を設定します。
ビジネスオブジェクト(メソッド)セキュリティ - サービス層を保護するためのオプション。
AuthenticationManager- フレームワークの他の部分からの認証リクエストを処理します。
AccessDecisionManager -Web およびメソッドセキュリティのアクセス決定を提供します。デフォルトのものが登録されますが、通常の Spring Bean 構文を使用して宣言されたカスタムのものを使用することもできます。
AuthenticationProvider - 認証マネージャーがユーザーを認証するメカニズム。名前空間は、いくつかの標準オプションをサポートし、従来の構文を使用して宣言されたカスタム Bean を追加する手段も提供します。
UserDetailsService- 認証プロバイダーに密接に関連していますが、多くの場合、他の Bean にも必要です。
これらの設定方法については、次のセクションで説明します。
セキュリティ名前空間の構成の開始
このセクションでは、フレームワークの主な機能のいくつかを使用するために名前空間の構成を構築する方法を見ていきます。最初に、できるだけ早く起動して実行し、いくつかのテストログインで認証サポートとアクセス制御を既存の Web アプリケーションに追加したいとします。次に、データベースまたは他のセキュリティリポジトリに対する認証に切り替える方法を見ていきます。後のセクションで、より高度な名前空間設定オプションを紹介します。
web.xml の構成
最初に行う必要があるのは、web.xml
ファイルに次のフィルター宣言を追加することです。
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
これは、Spring Security Web インフラストラクチャへのフックを提供します。DelegatingFilterProxy
は、アプリケーションコンテキストで Spring Bean として定義されているフィルター実装に委譲する Spring Framework クラスです。この場合、Bean の名前は "springSecurityFilterChain" で、Web セキュリティを処理するために名前空間によって作成された内部インフラストラクチャ Bean です。この Bean の名前を自分で使用しないでください。これを web.xml
に追加したら、アプリケーションコンテキストファイルの編集を開始できます。Web セキュリティサービスは、<http>
要素を使用して構成されます。
最小限の <http> 構成
最初に Web セキュリティを有効にするために必要なのは
<http>
<intercept-url pattern="/**" access="hasRole('USER')" />
<form-login />
<logout />
</http>
これは、アプリケーション内のすべての URL を保護し、それらにアクセスするには ROLE_USER
のロールが必要であり、ユーザー名とパスワードを使用してフォームを使用してアプリケーションにログインし、ログアウト URL を登録する必要があることを示しています。アプリケーションからログアウトします。<http>
要素は、すべての Web 関連の名前空間機能の親です。<intercept-url>
要素は、ant パススタイル構文 [ 2 ] を使用して受信リクエストの URL と照合される pattern
を定義し、照合が実際に実行される方法の詳細を示します。] 代わりに正規表現マッチングを使用することもできます(詳細については、名前空間の付録を参照してください)。access
属性は、指定されたパターンに一致するリクエストのアクセス要件を定義します。デフォルトの構成では、これは通常、コンマで区切られたロールのリストであり、そのうちの 1 つはユーザーがリクエストを行うことを許可されている必要があります。接頭辞 "ROLE_" は、ユーザーの権限との単純な比較を行う必要があることを示すマーカーです。つまり、通常のロールベースのチェックを使用する必要があります。Spring Security のアクセス制御は、単純なロールの使用に限定されません(したがって、異なる型のセキュリティ属性を区別するためにプレフィックスを使用します)。解釈がどのように変化するかについては後で説明します [3 ]。Spring Security 3.0 では、属性に EL 式を設定することもできます。
複数の |
ユーザーを追加するには、名前空間で一連のテストデータを直接定義できます。
<authentication-manager>
<authentication-provider>
<user-service>
<!-- Password is prefixed with {noop} to indicate to DelegatingPasswordEncoder that
NoOpPasswordEncoder should be used. This is not safe for production, but makes reading
in samples easier. Normally passwords should be hashed using BCrypt -->
<user name="jimi" password="{noop}jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="{noop}bobspassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
これは、同じパスワードを安全に保存する方法の例です。パスワードには {bcrypt}
が先頭に付き、DelegatingPasswordEncoder
に指示します。DelegatingPasswordEncoder
は、マッチングのために構成された PasswordEncoder
をサポートし、パスワードは BCrypt を使用してハッシュされます。
<authentication-manager>
<authentication-provider>
<user-service>
<user name="jimi" password="{bcrypt}$2a$10$ddEWZUl8aU0GdZPPpy7wbu82dvEw/pBpbRvDQRqA41y6mK1CoH00m"
authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="{bcrypt}$2a$10$/elFpMBnAYYig6KRR5bvOOYeZr1ie1hSogJryg9qDlhza4oCw1Qka"
authorities="ROLE_USER" />
<user name="jimi" password="{noop}jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="{noop}bobspassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
上記の構成では、2 人のユーザー、パスワードとアプリケーション内でのロール(アクセス制御に使用されます)を定義します。user-service
の properties
属性を使用して、標準のプロパティファイルからユーザー情報をロードすることもできます。ファイル形式の詳細については、メモリ内認証のセクションを参照してください。<authentication-provider>
要素を使用するということは、ユーザー情報が認証リクエストを処理するために認証マネージャーによって使用されることを意味します。複数の <authentication-provider>
要素を使用して、さまざまな認証ソースを定義することができ、それぞれが順番に参照されます。
この時点で、アプリケーションを起動できるようになり、続行するにはログインする必要があります。試してみるか、プロジェクトに付属している「チュートリアル」サンプルアプリケーションを試してみてください。
デフォルトのログイン後の宛先の設定
保護されたリソースにアクセスしようとしてフォームのログインが要求されない場合、default-target-url
オプションが有効になります。これは、ユーザーが正常にログインした後に表示される URL であり、デフォルトは "/" です。また、always-use-default-target
属性を "true" に設定することにより、ユーザーが常にこのページで終了するように設定することもできます(ログインが「オンデマンド」であるか、明示的にログインすることを選択したかは関係ありません)。これは、アプリケーションが常にユーザーが「ホーム」ページから開始することを要求する場合に役立ちます。例:
<http pattern="/login.htm*" security="none"/>
<http use-expressions="false">
<intercept-url pattern='/**' access='ROLE_USER' />
<form-login login-page='/login.htm' default-target-url='/home.htm'
always-use-default-target='true' />
</http>
宛先をさらに制御するには、authentication-success-handler-ref
属性を default-target-url
の代替として使用できます。参照される Bean は AuthenticationSuccessHandler
のインスタンスでなければなりません。
高度な Web 機能
独自のフィルターを追加する
以前に Spring Security を使用したことがある場合、フレームワークはサービスを適用するためにチェーンのフィルターを保持していることがわかります。特定の場所でスタックに独自のフィルターを追加するか、現在ネームスペース構成オプション(CAS など)がない Spring Security フィルターを使用することができます。または、<form-login>
要素によって作成される UsernamePasswordAuthenticationFilter
など、標準の名前空間フィルターのカスタマイズされたバージョンを使用し、Bean を明示的に使用することで利用できる追加の構成オプションのいくつかを利用することもできます。フィルターチェーンは直接公開されていないため、名前空間の構成でこれを行うにはどうすればよいですか?
ネームスペースを使用する場合、フィルターの順序は常に厳密に適用されます。アプリケーションコンテキストが作成されると、フィルター Bean はネームスペース処理コードによってソートされ、標準の Spring Security フィルターはそれぞれ、ネームスペース内のエイリアスと既知の位置を持ちます。
以前のバージョンでは、フィルターインスタンスが作成された後、アプリケーションコンテキストの後処理中に並べ替えが行われました。バージョン 3.0 + では、クラスがインスタンス化される前に、Bean メタデータレベルでソートが行われるようになりました。これは、 |
フィルターを作成するフィルター、エイリアス、ネームスペース要素 / 属性は標準のフィルターエイリアスと順序に示されています。フィルターは、フィルターチェーンで発生する順序でリストされています。
エイリアス | フィルタークラス | 名前空間要素または属性 |
---|---|---|
DISABLE_ENCODE_URL_FILTER |
|
|
FORCE_EAGER_SESSION_FILTER |
|
|
CHANNEL_FILTER |
|
|
SECURITY_CONTEXT_FILTER |
|
|
CONCURRENT_SESSION_FILTER |
|
|
HEADERS_FILTER |
|
|
CSRF_FILTER |
|
|
LOGOUT_FILTER |
|
|
X509_FILTER |
|
|
PRE_AUTH_FILTER |
|
N/A |
CAS_FILTER |
| なし |
FORM_LOGIN_FILTER |
|
|
BASIC_AUTH_FILTER |
|
|
SERVLET_API_SUPPORT_FILTER |
|
|
JAAS_API_SUPPORT_FILTER |
|
|
REMEMBER_ME_FILTER |
|
|
ANONYMOUS_FILTER |
|
|
SESSION_MANAGEMENT_FILTER |
|
|
EXCEPTION_TRANSLATION_FILTER |
|
|
FILTER_SECURITY_INTERCEPTOR |
|
|
SWITCH_USER_FILTER |
| なし |
custom-filter
要素とこれらの名前のいずれかを使用して独自のフィルターをスタックに追加し、フィルターが表示される位置を指定できます。
<http>
<custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
</http>
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>
スタック内の別のフィルターの前または後にフィルターを挿入する場合は、after
または before
属性を使用することもできます。"FIRST" および "LAST" という名前を position
属性とともに使用して、フィルターをスタック全体の前または後に表示することをそれぞれ示すことができます。
フィルター位置の競合の回避 名前空間によって作成された標準フィルターの 1 つと同じ位置を占める可能性のあるカスタムフィルターを挿入する場合、名前空間バージョンを誤って含めないことが重要です。機能を置き換えるフィルターを作成する要素を削除します。
|
認証エントリポイントを必要とする名前空間フィルターを置き換える場合(つまり、認証されていないユーザーがセキュリティで保護されたリソースにアクセスしようとすると認証プロセスがトリガーされる場合)、カスタムエントリポイント Bean も追加する必要があります。
メソッドのセキュリティ
バージョン 2.0 以降、Spring Security は、サービスレイヤーメソッドにセキュリティを追加するためのサポートを大幅に改善しました。JSR-250 アノテーションセキュリティとフレームワークの元の @Secured
アノテーションのサポートを提供します。3.0 から、新しい式ベースのアノテーションを利用することもできます。intercept-methods
要素を使用して Bean 宣言を装飾することにより、単一の Bean にセキュリティを適用するか、AspectJ スタイルのポイントカットを使用してサービス層全体にわたって複数の Bean を保護することができます。
デフォルトの AccessDecisionManager
このセクションでは、Spring Security 内のアクセス制御の基礎となるアーキテクチャに関する知識があることを前提としています。このセクションは、単純なロールベースのセキュリティ以上のものを使用するためにカスタマイズを行う必要のある人にのみ関連するため、スキップして後で戻ることができます。
ネームスペース構成を使用すると、AccessDecisionManager
のデフォルトインスタンスが自動的に登録され、intercept-url
および protect-pointcut
宣言(およびアノテーション)で指定したアクセス属性に基づいて、メソッド呼び出しおよび Web URL アクセスのアクセス決定に使用されます。アノテーションで protected メソッドを使用している場合)。
デフォルトの戦略は、AffirmativeBased
AccessDecisionManager
を RoleVoter
および AuthenticatedVoter
とともに使用することです。これらの詳細については、認可の章を参照してください。
AccessDecisionManager のカスタマイズ
より複雑なアクセス制御戦略を使用する必要がある場合は、メソッドと Web セキュリティの両方の代替手段を簡単に設定できます。
メソッドのセキュリティを確保するには、アプリケーションコンテキストで global-method-security
の access-decision-manager-ref
属性を適切な AccessDecisionManager
Bean の id
に設定します。
<global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">
...
</global-method-security>
Web セキュリティの構文は同じですが、http
要素にあります:
<http access-decision-manager-ref="myAccessDecisionManagerBean">
...
</http>