セキュリティ名前空間の構成
名前空間構成は、Spring Framework のバージョン 2.0 以降で使用可能になっています。これにより、従来の Spring Bean アプリケーションコンテキスト構文を、追加の XML スキーマの要素で補足できます。詳細については、Spring リファレンスドキュメント (英語) を参照してください。名前空間要素を使用して、個々の Bean をより簡潔に構成したり、より強力に、問題のドメインにより厳密に一致し、根本的な複雑さをユーザーから隠す代替構成構文を定義したりできます。単純な要素は、複数の Bean と処理ステップがアプリケーションコンテキストに追加されているという事実を隠すことができます。例: security
名前空間からアプリケーションコンテキストに次の要素を追加すると、アプリケーション内での使用をテストするための組み込み LDAP サーバーが起動します。
<security:ldap-server />
これは、同等の Apache Directory サーバー Bean を接続するよりもはるかに簡単です。最も一般的な代替構成要件は、ldap-server
要素の属性によってサポートされており、ユーザーは、どの Bean を作成する必要があるか、および Bean プロパティ名が何であるかを心配する必要がありません。ldap-server
要素の使用の詳細については、LDAP 認証の章を参照してください。優れた XML エディターは、アプリケーションコンテキストファイルを編集する際に、使用可能な属性と要素に関する情報を提供する必要があります。標準の Spring 名前空間を操作するための特別な機能を備えているため、Pleiades All in One (JDK, STS, Lombok 付属) または Eclipse Spring Tool Suite (英語) を試すことをお勧めします。
アプリケーションコンテキストで security
名前空間の使用を開始するには、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>
DelegatingFilterProxy
は、アプリケーションコンテキストで Spring Bean として定義されているフィルター実装に委譲する Spring Framework クラスです。この場合、Bean は springSecurityFilterChain
という名前で、Web セキュリティを処理するために名前空間によって作成された内部インフラストラクチャ Bean です。この場合、Bean は "springSecurityFilterChain" という名前で、Web セキュリティを処理するために名前空間によって作成された内部インフラストラクチャ Bean です。この 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>
要素は pattern
を定義します。これは、Ant パス構文を使用して受信リクエストの URL と照合されます。一致が実際に実行される方法の詳細については、HttpFirewall
のセクションを参照してください。代わりに正規表現マッチングを使用することもできます(詳細については、名前空間の付録を参照してください)。access
属性は、指定されたパターンに一致するリクエストのアクセス要件を定義します。デフォルトの構成では、これは通常、コンマで区切られたロールのリストであり、そのうちの 1 つはユーザーがリクエストを行うことを許可されている必要があります。ROLE_
プレフィックスは、ユーザーの権限との単純な比較を行う必要があることを示すマーカーです。つまり、通常のロールベースのチェックを使用する必要があります。Spring Security のアクセス制御は、単純なロールの使用に限定されません(したがって、異なる型のセキュリティ属性を区別するためにプレフィックスを使用します)。解釈がどのように変化するかは後でわかります。access
属性のコンマ区切り値の解釈は、使用されている AccessDecisionManager
の実装によって異なります。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
に、パスワードが BCrypt を使用してハッシュされるように構成された PasswordEncoder
をサポートするように指示します。
<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 を使用したことがある場合は、フレームワークがサービスの適用に使用するフィルターのチェーンを維持していることをご存知でしょう。スタックの特定の場所に独自のフィルターを追加するか、現在名前空間構成オプションがない Spring Security フィルター(CAS など)を使用することができます。または、UsernamePasswordAuthenticationFilter
(<form-login>
要素によって作成される)などの標準の名前空間フィルターのカスタマイズされたバージョンを使用して、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
要素とこれらの名前の 1 つを使用して、フィルターを表示する位置を指定することにより、独自のフィルターをスタックに追加できます。
<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 以降、式ベースのアノテーションを利用することもできます。単一の Bean にセキュリティを適用するか(intercept-methods
要素を使用して Bean 宣言を装飾することにより)、または AspectJ スタイルのポイントカットを使用してサービスレイヤー全体にわたって複数の Bean を保護することができます。
デフォルトの AccessDecisionManager
このセクションは、Spring Security 内のアクセス制御の基礎となるアーキテクチャーについてある程度の知識があることを前提としています。そうでない場合は、スキップして後で戻ることができます。このセクションは、単純なロールベースのセキュリティ以上のものを使用するためにカスタマイズを行う必要がある人にのみ関連するためです。
名前空間構成を使用すると、AccessDecisionManager
のデフォルトインスタンスが自動的に登録され、intercept-url
および protect-pointcut
宣言(およびアノテーション、メソッドを保護するためにアノテーションを使用する場合)。
デフォルトの戦略は、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>