blueprint

5分でまとめる技術メモ

Kubernetes

Kubernetesとは

複数マシンから構成されるマシン基盤上でのコンテナ管理に用いられるプラットフォームです。 例えばアプリケーションAPIサーバーを起動するコンテナを常にn台に分散してデプロイさせたいとき、定義ファイルにそのようなデプロイ指示を記述すればKubernetesがよしなにデプロイを実施してくれます。

特徴

理想とするコンテナデプロイ状況を宣言的に記述できます。

先程の例のように、コンテナをどのようにデプロイしていくかをYAMLJSON等のファイルに宣言し、それをもとにKubernetesを使用しでデプロイを実施できます。理想とするデプロイ状況がファイル上に定義されているので、定義ファイルがあればデプロイ状況が再現可能になります。またIaCの文脈で、コードとして管理することが可能です。これにより、Kubernetes上の定義をGitで管理したり、CLIの入力に使用するなどが可能になります。

Node

Kubernetesから見た(仮想・物理)マシンの単位です。マシンはオンプレミスにおける一台一台の物理サーバーや、クラウドプラットフォーム上のサーバーインスタンスに該当します。

Pod

Kubernetes上のデプロイ単位です。デプロイする単位なので、複数のコンテナをまとめて起動する場合も1Podとなります。 例えばdocker-composeで複数コンテナを連携してデプロイするような単位を1Podでまとめます。

Pod内ではネットワークインタフェース及びストレージが共有されます。そのため、Podを一つのコンテナホストとみなすこともできます。

Controller

Kubernetesではコンテナクラスタを制御するための仕組みをControllerとして提供します。

Deployment

Deploymentは基本的なResourceの一種で、Podを一定数維持しつつデプロイを実施するのに使用できます。 セルフヒーリング機能を持ち、もしNode障害などで一部のPodが機能しなくなっても、予め宣言しておいたPod数を維持するように生存が確認できるNodeに新たにPodがデプロイされます。

StatefulSet

本来コンテナはステートレス、すなわち状態を持たずコンテナが破棄された場合は内部のファイルシステムも破棄されます。 StatefulSetで管理されたPodは一意の識別子を割り当てられ、明確に区別されます。Node障害などで特定のPodがダウンしても、例えばそのPodに対応したVolumeは復帰後同じ識別子を持つPodに割り当てられます。このように、永続的な状態を持たせるためにStatefulSetを使用することができます。

参考

イラストでわかるDockerとKubernetes (Software Design plus) | 徳永 航平 |本 | 通販 | Amazon

更新履歴

2021/03/28 初版 2021/03/29 Pod,Deployment,StatefulSet 記述追加

【翻訳】Spring Security Architecture




f:id:rennnosukesann:20191012004149p:plain


これは何?

Javaプラットフォーム向けフレームワークSpring FrameworkのドキュメントSpring Security Architectureの翻訳記事です。

Spring Securityの提供する認証・認可等のセキュリティ機能をどのようなアーキテクチャで実現しているのかを概要レベルで説明しています。

意訳の部分も多いと思いますが、何卒ご了承ください。
誤訳・アドバイス等ありましたら、コメント頂けると助かります。
(特に誤訳が心配なので、都度修正していきます)

以下、訳文になります。


Spring Security アーキテクチャ

このガイドはSpring Securityの入門ドキュメントであり、Spring Securityフレームワークの基本的な設計・構成要素について説明します。

ごく基本的なアプリケーションセキュリティのみをカバーしていますが、Spring Securityを使う開発者が経験する諸々の混乱を解消する事ができるでしょう。

説明のため、Webアプリケーションに対してフィルターや一般的なメソッドアノテーションを使用し、セキュリティを担保するやり方を通じて、Spring Securityの概要を見ていきます。

あなたがアプリケーションをどのように高度にセキュア化するのか、どのようにカスタマイズできるのかを理解する必要があるとき、あるいはただ単にアプリケーションのセキュリティについて考えるとき、このドキュメントを活用してください。

このガイドはごく基本的な問題以上のものを解決するためのマニュアルやレシピではありません(そのために必要な資料が他にあります)が、ビギナーにはもちろん、上級者の方にも役に立つことでしょう。Spring Boot はセキュアなアプリケーションとして基本的な振る舞いを提供するので参考になりますし、Spring Securityが Spring Bootアーキテクチャ全体に対してどのように適合しているのかを理解するのにも役に立つでしょう。

アーキテクチャとアクセスコントロール

アプリケーションセキュリティは多かれ少なかれ、2つの独立した問題に集約されます - 認証(あなたは誰か?)と認可(あなたに許される行いは何か?)です。認可(authorization)のことをアクセスコントロール(access controll)と呼ぶ人もおり紛らわしいのですが、認可(authorization)という言葉が他の文脈では別の意味と捉えられる場合があるので、そのようなときには用語を使い分けると便利です。 Spring Securityでは認証を認可から分離するアーキテクチャを取り、認証・認可両者それぞれにおける戦略・拡張ポイントがあります。

認証

認証では AuthenticationManager インタフェースを主に使用した方法を取ります。 AuthenticationManage は下記の一つのメソッドを持ちます:

public interface AuthenticationManager {

  Authentication authenticate(Authentication authentication)
    throws AuthenticationException;

}

AuthenticationManageauthenticate() メソッドの中で、以下の3つの処理を実行します:

  1. 入力が正しい認証情報である場合、 Authentication インスタンスを返す(通常、 authenticated=true となる)。

  2. 入力が誤った認証情報である場合、AuthenticationException をスローする。

  3. 上記認証情報が判別不能の場合、 null を返す。

AuthenticationExceptionRuntimeException です。多くの場合アプリケーションの目的やスタイルに依存した方法でアプリケーションによってハンドルされます。言い換えれば、通常であればユーザのコードはこの例外をキャッチしたりハンドルしたりすることを想定していないということです。例えば、WWW-Authenticate ヘッダーの有無に関わらず、Web UI が認証失敗のページを表示し、バックエンドHTTPサーバが401レスポンスを返します。

AuthenticationManager の最も一般的な実装は ProviderManager です。 ProviderManager は複数の AuthenticationProvider インスタンスチェーンに処理を委譲します。 AuthenticationProviderAuthenticationManager と少し似ていますが、AuthenticationProvider は認証処理で使用できる Authentication 型を呼び出し元が問い合わせられるメソッドを持っています:

public interface AuthenticationProvider {

    Authentication authenticate(Authentication authentication)
            throws AuthenticationException;

    boolean supports(Class authentication);

}

supports()Class<?> 引数は実際には Class<? extends Authentication> 型です( authenticate() に渡される引数型としてサポートするかどうかだけを問い合わせます)。 ProviderManager は複数の AuthenticationProvider チェーンに認証処理を委譲することで、複数の異なる認証メカニズムをサポートすることができます。もし ProviderManager が特定の Authentication インスタンス型を認識していない場合、この処理はスキップされます。

ProviderManager は任意で親クラスを持つことができます。この親クラスは小クラスの全ての AuthenticationProvidernull であるとき参照されます。 親クラスが使用できないとき、 null Authentication となり AuthenticationException 例外が送出されます。

アプリケーションが論理的に保護されたリソースを持つと気(例:全てのWebリソースがパスパターン /api/** にマッチする)、各リソースグループはそれぞれ自身の AuthenticationManager を持ちます。 殆どの場合、それらは ProviderManager であり、それらは親を共有しています。このとき親は"グローバルな"リソースであり、全てのproviderのフォールバックとしての役割を持ちます。

[figure1]

Authentication Managers のカスタマイズ

Spring Securityは標準的なAuthentication Managerの特徴を取得し、アプリケーションにセットアップするための構成ヘルパーを提供します。最も一般的なユーザヘルパーは AuthenticationManagerBuilder で、JDBCLDAP user details、あるいはカスタム UserDetailsService による追加 user details をインメモリでセットアップするのに向いています。

以下は、グローバルな(親の) AuthenticationManager を構成するアプリケーションの例です。

@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

   ... // web stuff here

  @Autowired
  public void initialize(AuthenticationManagerBuilder builder, DataSource dataSource) {
    builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
      .password("secret").roles("USER");
  }

}

この例はWebアプリケーションに関連したものですが、 ここで示した AuthenticationManagerBuilder の使い方はより広い領域に応用できます(以下のWebアプリケーションセキュリティの実装方法の詳細を見てください)。 ApplicationManagerBuilder@Bean のメソッド内で @Autowired されます - このようにしてグローバルな(親の) AuthenticationManager が作成されます。

対象的に、以下のようにした場合:

@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

  @Autowired
  DataSource dataSource;

   ... // web stuff here

  @Override
  public void configure(AuthenticationManagerBuilder builder) {
    builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
      .password("secret").roles("USER");
  }

}

AuthenticationManagerBuilder は "ローカルの" AuthenticationManager を生成するために使われます。この AuthenticationManager はグローバルな AuthenticationManager の子インスタンスです。Spring Bootアプリケーションでは別のBean内でグローバルな AuthenticationManager@Autowired できますが、ローカルな AuthenticationManager は明示的な宣言なしに作成することはできません。

AuthenticationManager Beanを開発者自身で用意しなかった場合、 Spring Boot はデフォルトでグローバルな AuthenticationManager を生成します。

認可、あるいはアクセスコントロール

一度認証に成功すると、 AccessDecisionManager を中心とした認可フェーズに移行します。フレームワークから提供される実装は3種類存在し、それぞれ AccessDecisionVoter チェーンへと処理を移乗します。これは ProviderManagerAuthenticationProviders に処理を委譲するのに少し似ています。

AccessDecisionVoter は(principal に代表される) Authentication と、 ConfigAttributes にデコレートされたセキュア Object を検証します:

boolean supports(ConfigAttribute attribute);

boolean supports(Class clazz);

int vote(Authentication authentication, S object,
        Collection attributes);

ObjectAccessDecisionManagerAccessDecisionVoter シグネチャにおけるジェネリックです。 - これはユーザがアクセスしたい対象すべてを表します(Java クラスのリソースやメソッドが一般的です)。 ConfigAttributes もまたジェネリック上で扱われ、セキュア Object や、アクセスに求められるパーミッションレベルなどのメタデータに対するデコレーションであることを表しています。 ConfigAttribute は単なるジェネリックであり String を返すメソッドを一つ持つインタフェース型です。この String はリソースのオーナーの意図する方法でエンコードされます。 典型的な ConfigAttribute はユーザーロールで( ROLE_ADMINROLE_AUDIT など )、判別のため( ROLE_ 接頭辞のような)特別なフォーマットや表現を持つ場合があります。

殆どの人は AffirmativeBased ベースのデフォルトの AccessDecisionManager を使用します(どの voter も affirmatively を返した場合、アクセス件が付与される形式)。 どのような カスタマイズでも投票形式の処理を実装することがほとんどか、あるいは既存の朱織に新規の処理を追加したり、変更をシたりするものがほとんどです。

ConfigAttributes では Spring Expression Language(SpEL)表現を使うのが普通です。例えば isFullyAuthenticated() && hasRole('FOO') などです。これは AccessDecisionVoter でサポートされており、SpEL 表現のサポートに加えてコンテキストの生成も行えます。サポートされる SpQL を拡張する場合、 SecurityExpressionRoot に加えて必要であれば SecurityExpressionHandler のカスタム実装が必要になります。

Web Security

Webレイヤ(UIやHTTPバックエンド)における Spring Security はサーブレットFilters をベースにしています。なので、まずは Filters の役割から見ていくと良いでしょう。以下の図は単一HTTPリクエストハンドラの典型的なレイヤ分けです。

[picure]

クライアントがアプリケーションにリクエストを送ると、コントローラはリクエストURLに基づきどのフィルタ/サーブレットを適用するかを決めます。最大で一つのサーブレットが単一のリクエストをハンドルできますが、フィルターは順序をもつチェーンを構成するため、ある一つのフィルターがリクエスト自体を処理したい場合には、残りのフィルター処理を拒否することができます。また、フィルターはリクエストと、サーブレットからフィルター、そしてユーザまでに流れるレスポンスに対して変更をかけることができます。フィルターチェーンの順序はとても重要で、2つのメカニズムによってSpring Bootで管理されます: - 1つ目は Filter 型の @Bean@Order または Ordered 実装を持つことです。 - 2つ目は Filter 型の @Bean が 自身のAPIとして順序情報を持つ FilterRegistrationBean の派生クラスであることです。既存のフィルターは、お互いの相対的な順序関係を示すのに役立つ定数を定義しています。 (例えば、Spring Sessionの SessionRepositoryFilterInteger.MIN_VALUE + 50DEFAULT_ORDER を持っています。これはチェーンの前段に位置することを示しているものの、それよりも早い位置にフィルターを配置できないわけではないことを示しています)

Spring Security は FilterChainProxy 具象型 Filter としてチェーン内に導入されていますが、理由はすぐに分かります。Spring Bootアプリケーションにおいてセキュリティフィルターは ApplicationContext 内の @Bean であり、デフォルトでインストールされます。そのため、全てのリクエストに適用されます。このフィルターはチェーン内の SecurityProperties.DEFAULT_FILTER_ORDER の位置に挿入され、 FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER によって固定されます(Spring Bootアプリケーションがリクエストをラップし、動作を変更した場合に、フィルターが持つと予想される最大の順序)。 それだけではありません:コンテナの観点から、Spring Security はシングルフィルターですが、内部では追加のフィルターが存在し、各々が特別な振る舞いをします。以下がそれを表した図です:

[picture]

実際、Securityのフィルターは一つ以上の間接的な層からなります。:殆どの場合、 DelegationFilterProxy をコンテナーとし、その内部にインストールされます。このコンテナは @Bean であり、springSecurityFilterChain と名称を修正されます。これは フィルターチェーンとして全てのセキュリティロジックを内包した FilterChainProxy です。これら全てのフィルターは同様のAPIを持ち(それらは全てServletFilter インターフェースを実装します)、残りのフィルターチェーンの処理を拒否する機会を持ちます。

Spring Security では共通のトップレベルに位置する FilterChainProxy に管理される、コンテナーに認識されない複数のフィルターチェーンが存在する場合があります。Spring Security フィルターはフィルターチェーンのリストを含み、リクエストにマッチする最初のフィルターチェーンをディスパッチします。下図はリクエストパスマッチングに基づいたディスパッチを示しています( /foo/**/** の前にマッチします)。これは極めて一般的な例ですが、リクエストマッチングの方法はこれだけではありません。ほとんどのディスパッチプロセスの重要な特徴は、一つのチェーンだけがリクエストをハンドリングするということです。

[picture]

セキュリティ構成がカスタムされていない、デフォルトのSpring Boot アプリケーションはいくつかの(この数をnとします)フィルターチェーンを持ちますが、その数は大抵はn=6です。最初(n=1)のチェーンは /css/**/images/**/error エラービューのような静的なリソースパターンを無視するためだけにあります( SecurityProperties 構成Beanの security.ignored でユーザがこれらのパスを制御できます)。最後のチェーンは全てのパスにマッチし、 認証、認可、例外ハンドリング、セッションハンドリング、ヘッダー書き込みなど、よりアクティブなフィルターです。デフォルトでは11のフィルターがkのフィルターチェーンには存在しますが、どのフィルターをいつ使用すべきかをユーザが気にする必要はありません。

Note:
実際には、コンテナーがSpring Security内の全てのフィルターを知らない状態がSpring Securityアプリケーションにおいては重要であり、全ての `Filter` 型 `@Bean` はデフォルトでコンテナーに自動的に登録されます。そのため、もしカスタムフィルターをセキュリティーチェーンに追加したい場合、 `@Bean` にしないか、コンテナー登録を明示的に無効にした `FilterRegistrationBean` でラップする必要があります。

フィルターチェーンの生成とカスタマイズ

Spring Bootアプリケーションのデフォルトのフォールバックフィルターチェーンは SecurityProperties.BASIC_AUTH_ORDER の順番で定義されています。この設定は security.basic.enabled=false を設定するか、フォールバックのより下位層で別のルールを定義することで完全に無効にできます。 WebSecurityConfigurerAdapter 型の @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/**")
     ...;
  }
}

このbeanによって、Spring Securityはフォールバックの前に新しいフィルターチェーンを追加し順序付けます。

多くのアプリケーションがリソースの集合ごとにまったく異なるアクセスルールを設けています。 例えば、UIとバックエンドAPIをホストするアプリケーションでは、UIにおけるログインページへのリダイレクトと、APIにおける認証されていないリクエストに対しての401レスポンスによるトークンベースの認証を使った、クッキーベースの認証をサポートします。各リソース集合はそれぞれ自身の WebSecurityConfigurerAdapter を持ち、それらは一意の順番とリクエストマッチャーを持ちます。もしマッチングルールが重複した場合、より早い順番のフィルターチェーンが優先されます。

伝送と認証のリクエストマッチング

セキュリティフィルターチェーン(あるいは同等の 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();
  }
}

Spring Securityの構成に犯しやすい間違いの一つは、これらのリクエストマッチャーが異なるプロセスに適用されることを忘れてしまうことです。一つはフィルターチェーン全体のリクエストマッチャーと、もう一つはアクセスルールを設定するために選択されたフィルターチェーンです。

アプリケーションセキュリティルールとActuatorルールの統合

Spring Boot Actuator を管理エンドポイントに使用している場合、Actuatorをデフォルトの状態でセキュアにしたいと思うでしょう。実際、Actuatorをセキュアなアプリケーションに組み込むと、すぐにActuatorエンドポイントのためだけの追加のフィルターチェーンが適用されます。そのフィルターチェーンはActuatorエンドポイントにのみマッチするリクエストマッチャーを持ち、 デフォルトの SecurityProperties フォールバックフィルターよりも5だけ小さい ManagementServletProperties.BASIC_AUTH_ORDER を順番として持ちます。そのため、フォールバックフィルターよりも早く適用されます。

もしアプリケーションのセキュリティルールをActuatorエンドポイントに適用したい場合は、Actuatorのフィルターチェーンよりも早い位置にフィルターチェーンを追加し、そのフィルターチェーン内でActuatorエンドポイントを指定したリクエストマッチャーを定義することで実現できます。もしデフォルトの設定をActuatorエンドポイントに設定したい場合は、自前のフィルターをActuatorのフィルターチェーンよりもあとに、かつフォールバックよりもあとに追加します(例: ManagementServerProperties.BASIC_AUTH_ORDER + 1 )。

例:

@Configuration
@Order(ManagementServerProperties.BASIC_AUTH_ORDER + 1)
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/foo/**")
     ...;
  }
}
Note
WebレイヤのSpring SecurityはServlet APIと紐付いているので、組み込みやその他サーブレットコンテナ上でアプリが実行される場合にのみ有効です。しかし、Spring MVC あるいはSpring Web スタックの一部に紐づいているわけではないので、例えばJAX-RSなどを使用するアプリケーションでも使用できます。

メソッドのセキュリティ

Webアプリケーションをセキュアにするように、Spring SecurityはJava メソッド実行に対するアクセスルールの適用をサポートします。Spring Securityにとって、この機能は単なる「リソース保護」の類のものです。 ユーザーの場合、アクセスルールが ConfigAttribute 文字列による共通のフォーマットによって、コードとは異なる場所で宣言されることを意味します(ロールまたは式 )。最初のステップは、例えばアプリケーショントップレベルで構成を有効化することです。

@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SampleSecureApplication {
}

このとき直接メソッドリソースをデコレートできます。

@Service
public class MyService {

  @Secured("ROLE_USER")
  public String secure() {
    return "Hello Security";
  }

}

このサンプルはセキュアメソッドを使ったサービスです。もしSpringがこの型の @Bean を作成したら、メソッドが実際に実行される前に、メソッド処理は代替され、呼び元はセキュリティインターセプター(訳注:@Secureによるフィルター処理?)を通り抜けるでしょう。もしアクセスが拒否された場合、呼び元は実際のメソッドの戻り値の代わりに AccessDeniedException を取得するでしょう。

セキュリティ制約を強制するために使用されるアノテーションは他にもあります。特に @PreAuthorize@PostAuthorize などは、メソッドパラメータや返戻値を参照する式を記述することができます。

TIP
メソッドセキュリティとWebセキュリティを一体化するのは普通ではありません。
フィルターチェーンは認証やログインページへのリダイレクトなどユーザー体験機能を提供し、メソッドセキュリティはより詳細なレベルでの保護を提供します。

スレッドとの協業

現在の認証済みプリンシパル下流部のコンシューマー上の広範囲で利用可能にする必要があるため、Spring Security は基本的にスレッドにバインドされます。基本的なコンポーネントとして Authentication (そしてユーザがログインしたとき、おそらく authenticated 状態にある Authentication になります)を含む SecurityContext があります。 SecurityContext には SecurityContextHolder の静的ヘルパーメソッドを経由していつでもアクセス・操作できます。これは簡潔かつ順番に ThreadLocal を操作します:

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
assert(authentication.isAuthenticated);

この方法は便利かもしれませんが、例えばカスタム認証フィルターを記述する必要がある場合などには、ユーザアプリケーションコードが認証済みユーザ情報にアクセスする方法として普通の方法ではありません( ただし、 SecurityContextHolder を使用する必要がない場合に使用できるSpring Securityの基本クラスがもあります)。

Webエンドポイント上で現在の認証済みユーザにアクセスする必要がある場合には、 @RequestMapping 内でメソッドパラメータを使用することができます:

@RequestMapping("/foo")
public String foo(@AuthenticationPrincipal User user) {
  ... // do stuff with user
}

このアノテーションSecurityContext 外の現在の認証情報を取得し、メソッドパラメータを生成するために getPrincipal() メソッドを呼び出します。Authentication 内の Principal 型は認証を検証するために使用される AuthenticationManager に依存するので、独自に定義したユーザデータへの型安全な参照を取得する便利で少しトリッキーな方法となりえます。

もしSpring Securityを使用する場合、 HttpServletRequestPrincipalAuthentication 型となり得るため、下記のように直接使用することもできます:

@RequestMapping("/foo")
public String foo(Principal principal) {
  Authentication authentication = (Authentication) principal;
  User = (User) authentication.getPrincipal();
  ... // do stuff with user
}

Spring Security が使用されていないとき、機能するコードを記述する必要がある場合に便利な場合があります( Authentication クラスのローディングに関してより防御的になる必要があります )。

非同期セキュアメソッドの処理

SecurityContext はスレッドにバインドされているため、 @Async のようにセキュアメソッドをバックグラウンド処理として呼び出したい場合、コンテキストが伝播されることを確認する必要があります。つまり、(RunnableやCallableなどのような)バックグラウンドで実行されるタスクで SecurityContext をラッピングする必要があるということです。Spring SecurigyはRunnableやCallableのラッパーなど、このラッピングをより簡単にするためのヘルパーを提供します。 @Async メソッドに SecurityContext を伝播し、 AsyncConfigurer を用意し Executor が正しい型であることを確認する必要があります:

@Configuration
public class ApplicationConfiguration extends AsyncConfigurerSupport {

  @Override
  public Executor getAsyncExecutor() {
    return new DelegatingSecurityContextExecutorService(Executors.newFixedThreadPool(5));
  }

}