Spring SecurityでのRESTサービスのための基本認証とダイジェスト認証

目次

セッション数] 3. ** ダイジェスト認証の設定

  • link:#both[ 4. 両方の認証プロトコルを同じ形式でサポートする

RESTfulサービス] 4.1。** 匿名リクエスト

1概要

この記事では、REST APIの同じURI構造に基本認証とダイジェスト認証の両方を設定する方法について説明します。前回の記事で、RESTサービスを安全にするもう1つの方法、 フォームベース認証 を使用したので、基本認証とダイジェスト認証は当然の選択肢ですよりRESTfulなものと同様に。

2基本認証の設定

フォームベースの認証がRESTfulサービスには理想的ではない主な理由は、Spring Securityが セッション を利用することです - これはもちろんサーバー上の状態です。

基本認証を設定することから始めます - 最初に古いカスタムエントリポイントを削除し、メインの <http> セキュリティ要素からフィルタします。

<http create-session="stateless">
   <intercept-url pattern="/api/admin/** ** " access="ROLE__ADMIN"/>

   <http-basic/>
</http>

BasicAuthenticationFilter BasicAuthenticationEntryPoint の両方の作成と配線を処理する単一の設定行 <http-basic/> __ - によって、基本認証のサポートがどのように追加されたかに注意してください。

2.1. ステートレス制約を満たす - セッションを取り除く

RESTfulなアーキテクチャースタイルの主な制約の1つは、クライアントとサーバー間の通信が完全に ステートレス であることです。]読み取り:

  • 5.1.3ステートレス**

次に、クライアントとサーバーの対話に制約を追加します。セクション3.4.3のクライアントステートレスサーバー(CSS)スタイル(図5-3)のように、通信は本質的にステートレスである必要があります。サーバーには、要求を理解するために必要なすべての情報が含まれている必要があり、サーバーに格納されているコンテキストを利用することはできません。したがってセッション状態は完全にクライアント上で保持されます。

サーバー上の Session の概念はSpring Securityの長い歴史のある概念であり、それを完全に削除することは今まで、特に構成が名前空間を使用して行われたときは困難でした。

しかし、Spring Security augments セッション作成のための 新しい stateless オプション を持つ名前空間設定、これは事実上Springによってセッションが作成または使用されないことを保証する。この新しいオプションが完了すると、セキュリティフィルタチェーンからすべてのセッション関連フィルタが削除され、各要求に対して認証が確実に実行されます。

=== 3ダイジェスト認証の設定

前の設定から始めて、ダイジェスト認証を設定するために必要なフィルタとエントリポイントはBeanとして定義されます。

そして、 ダイジェストエントリポイント は、舞台裏で <http-basic> によって作成されたものを上書きします。最後に、カスタムの ダイジェストフィルタ がセキュリティネームスペースの after セマンティクスを使用してセキュリティフィルタチェーンに導入され、基本認証フィルタの直後に配置されます。

<http create-session="stateless" entry-point-ref="digestEntryPoint">
   <intercept-url pattern="/api/admin/** ** " access="ROLE__ADMIN"/>

   <http-basic/>
   <custom-filter ref="digestFilter" after="BASIC__AUTH__FILTER"/>
</http>

<beans:bean id="digestFilter" class=
 "org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
   <beans:property name="userDetailsService" ref="userService"/>
   <beans:property name="authenticationEntryPoint" ref="digestEntryPoint"/>
</beans:bean>

<beans:bean id="digestEntryPoint" class=
 "org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
   <beans:property name="realmName" value="Contacts Realm via Digest Authentication"/>
   <beans:property name="key" value="acegi"/>
</beans:bean>

<authentication-manager>
   <authentication-provider>
      <user-service id="userService">
         <user name="eparaschiv" password="eparaschiv" authorities="ROLE__ADMIN"/>
         <user name="user" password="user" authorities="ROLE__USER"/>
      </user-service>
   </authentication-provider>
</authentication-manager>

残念ながら、セキュリティ認証名前空間には、基本認証を <http-basic> で設定する方法で自動的にダイジェスト認証を設定するhttps://jira.springsource.org/browse/SEC-1860[support]がありません。そのため、必要なBeanを手動で定義し、セキュリティ設定に配線する必要がありました。

=== 4同じRESTfulサービスで両方の認証プロトコルをサポート

基本認証またはダイジェスト認証のみをSpring Securityに簡単に実装できます。サービスの設定とテストに新たなレベルの複雑さをもたらす、同じURIマッピング上で、同じRESTful Webサービスをサポートしています。

==== 4.1. 匿名リクエスト

セキュリティチェーンの基本フィルタとダイジェストフィルタの両方で、 anonymous request - 認証資格情報( Authorization HTTPヘッダー)を含まない要求 - がSpring Securityによって処理される方法は - 2つの認証フィルタは no credentials を見つけるでしょうフィルタチェーンの実行を継続します。次に、リクエストがどのように認証されなかったかを確認すると、 AccessDeniedException がスローされて ExceptionTranslationFilter に捕捉され、ダイジェストエントリポイントが開始され、クライアントに資格情報の入力を求めます。

基本フィルタとダイジェストフィルタの役割は非常に狭く、要求内の認証資格情報の種類を識別できない場合、セキュリティフィルタチェーンを実行し続けます。これが原因で、Spring Securityは同じURIで複数の認証プロトコルをサポートするように柔軟に設定できるようになりました。

正しい認証資格情報(基本またはダイジェスト)を含む要求が行われると、そのプロトコルが正しく使用されます。ただし、匿名要求の場合、クライアントはダイジェスト認証資格情報の入力のみを求められます。これは、ダイジェストエントリポイントがSpring Securityチェーンのメインエントリポイントおよび単一エントリポイントとして構成されているためです。そのため、ダイジェスト認証はデフォルトと見なすことができます。

==== 4.2. 認証資格情報を使用した要求

基本認証のための資格情報を持つ** 要求は、接頭辞 "Basic" で始まる Authorization ヘッダーによって識別されます。そのような要求を処理するとき、信任状は基本認証フィルターでデコードされ、要求は許可されます。同様に、ダイジェスト認証用の認証情報を含むリクエストは、 Authorization ヘッダーに接頭辞 「Digest」 を使用します。

=== 5両方のシナリオをテストする

テストでは、基本認証またはダイジェスト認証の後に新しいリソースを作成してRESTサービスを消費します。

@Test
public void givenAuthenticatedByBasicAuth__whenAResourceIsCreated__then201IsReceived(){
  //Given
  //When
   Response response = given()
    .auth().preemptive().basic( ADMIN__USERNAME, ADMIN__PASSWORD )
    .contentType( HttpConstants.MIME__JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
    .post( paths.getFooURL() );

  //Then
   assertThat( response.getStatusCode(), is( 201 ) );
}
@Test
public void givenAuthenticatedByDigestAuth__whenAResourceIsCreated__then201IsReceived(){
  //Given
  //When
   Response response = given()
    .auth().digest( ADMIN__USERNAME, ADMIN__PASSWORD )
    .contentType( HttpConstants.MIME__JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
    .post( paths.getFooURL() );

  //Then
   assertThat( response.getStatusCode(), is( 201 ) );
}

基本認証を使用したテストでは、サーバーが認証を要求されているかどうかにかかわらず、 プリエンプティブに 要求に資格情報を追加します。これは、サーバーがクライアントに認証情報を要求する必要がないようにするためです。要求された場合、チャレンジがダイジェスト認証情報になるためです。これがデフォルトです。

=== 6. 結論

この記事では、主にSpring Security名前空間サポートとフレームワークのいくつかの新機能を使用して、RESTfulサービス用の基本認証とダイジェスト認証の両方の構成と実装について説明しました。

前の投稿:Spring Bootのコマンドライン引数
次の投稿:Java Weekly、Issue 250