1. 概要

このチュートリアルでは、SpringSecurityの@EnableResourceServerおよび@EnableOAuth2Ssoアノテーションについて説明します。

まず、OAuth2クライアントとOAuth2リソースサーバーの違いについて説明します。 その後、これらのアノテーションで何ができるかについて少し説明し、Zuulと単純なAPIを使用した例を使用してそれらの使用法を示します。

この記事では、ZuulおよびOAuth2の既存の経験を前提としています。

どちらかがない場合、またはどちらかのレビューが役立つと思われる場合は、Zuulクイック概要およびOAuth2ガイドを参照してください。

2. OAuth2クライアントとリソースサーバー

OAuth2内には4つの異なるロールを考慮する必要があります。

  • リソース所有者—保護されたリソースへのアクセスを許可できるエンティティ
  • 認証サーバーリソース所有者を正常に認証して認証を取得した後、クライアントにアクセストークンを付与します
  • リソースサーバー—リソースへのアクセスを許可する、または少なくとも検討するためにアクセストークンを必要とするコンポーネント
  • Client —認証サーバーからアクセストークンを取得できるエンティティ

構成クラスに@EnableResourceServerまたは@EnableOAuth2Sso のアノテーションを付けると、アプリケーションを上記の2つの役割のいずれかに変換するコンポーネントを構成するようにSpringに指示します。

@EnableResourceServerアノテーションを使用すると、 OAuth2AuthenticationProcessingFilter およびその他の同様に重要なコンポーネントを構成することにより、アプリケーションをリソースサーバーとして動作させることができます。

ResourceServerSecurityConfigurer クラスをチェックして、舞台裏で何が構成されているかをよりよく理解してください。

逆に、 @ EnableOAuth2Ssoアノテーションは、アプリケーションをOAuth2クライアントに変換します。 これは、 OAuth2ClientAuthenticationProcessingFilter と、アプリケーションが認証サーバーからアクセストークンを取得できる必要がある他のコンポーネントを構成するようにSpringに指示します。

Springが構成する内容の詳細については、SsoSecurityConfigurerクラスを参照してください。

これらのアノテーションをいくつかのプロパティと組み合わせると、物事をすばやく立ち上げて実行することができます。 2つの異なるアプリケーションを作成して、それらの動作と、それらが互いに補完する方法を確認しましょう。

  • 最初のアプリケーションは、 @EnableOAuth2Ssoアノテーションを使用する単純なZuulアプリケーションであるエッジノードになります。 ユーザーの認証(承認 サーバーの助けを借りて)を担当し、着信要求を他のアプリケーションに委任します
  • 2番目のアプリケーションは@EnableResourceServerアノテーションを使用し、着信リクエストに有効なOAuth2アクセストークンが含まれている場合、保護されたリソースへのアクセスを許可します

3. ズール– @ EnableOAuth2Sso

エッジノードとして機能し、OAuth2 Authorization Serverを使用してユーザーの認証を担当するZuulアプリケーションを作成することから始めましょう。

@Configuration
@EnableZuulProxy
@EnableOAuth2Sso
@Order(value = 0)
public class AppConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private ResourceServerTokenServices 
      resourceServerTokenServices;

    @Override
    public void configure(HttpSecurity http) throws Exception { 
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/authorization-server-1/**",
              "/login").permitAll()
            .anyRequest().authenticated().and()
            .logout().permitAll().logoutSuccessUrl("/");
    }
}

Zuulアプリケーションに@EnableOAuth2Sso の注釈を付けると、SpringにOAuth2TokenRelayFilterフィルターを構成するように通知されます。 このフィルターは、ユーザーのHTTPセッションから以前に取得したアクセストークンを取得し、それらをダウンストリームに伝播します。

AppConfiguration構成クラスでも@Orderアノテーションを使用していることに注意してください。 これは、WebSecurityConfigurerAdapterによって作成されたFiltersが、他のWebSecurityConfigurerAdaptersによって作成されたFiltersよりも優先されるようにするためです。

たとえば、Zuulアプリケーションに@EnableResourceServerで注釈を付けて、HTTPセッション識別子とOAuth2アクセストークンの両方をサポートできます。 ただし、これを行うと、新しい Filters が作成され、デフォルトでは、AppConfigurationクラスによって作成されたものよりも優先されます。 これは、 ResouceServerConfiguration @EnableResourceServerによってトリガーされる構成クラスがデフォルトのorder を3に指定し、WebSecurityConfigureAdapterがデフォルトのを指定するために発生します。 ]100の注文

Resource Server、に移動する前に、いくつかのプロパティを構成する必要があります。

zuul:
  routes:
    resource-server-mvc-1: /resource-server-mvc-1/**
    authorization-server-1:
      sensitiveHeaders: Authorization
      path: /authorization-server-1/**
      stripPrefix: false
  add-proxy-headers: true

security:
  basic:
    enabled: false
  oauth2:
    sso:
      loginPath: /login
    client:
      accessTokenUri: http://localhost:8769/authorization-server-1/oauth/token
      userAuthorizationUri: /authorization-server-1/oauth/authorize
      clientId: fooClient
      clientSecret: fooSecret
    resource:
      jwt:
        keyValue: "abc"
      id: fooScope
      serviceId: ${PREFIX:}resource

この構成を使用して、あまり詳細に立ち入ることなく、次のようになります。

  • Zuul ルートを構成し、リクエストをダウンストリームに送信する前に、どのヘッダーを追加/削除する必要があるかを指定します。
  • Authorization Server と通信できるようにアプリケーションのいくつかのOAuth2プロパティを設定し、symmetric暗号化を使用してJWTを構成します。

4. API – @EnableResourceServer

Zuul アプリケーションが配置されたので、 Resource Serverを作成しましょう。

@SpringBootApplication
@EnableResourceServer
@Controller
@RequestMapping("/")
class ResourceServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ResourceServerApplication.class, args);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public String helloWorld(Principal principal) {
        return "Hello " + principal.getName();
    }
}

これは、単一のエンドポイントを公開して、リクエストを開始したプリンシパル名前を返すシンプルなアプリケーションです。

いくつかのプロパティを構成してまとめましょう。

security:
  basic:
    enabled: false
  oauth2:
    resource:
      jwt:
        keyValue: "abc"
      id: fooScope
      service-id: ${PREFIX:}resource

リソースサーバーのエンドポイントにアクセスするには、有効なアクセストークン(エッジノードのユーザーのHTTPセッションに保存されている)が必要であることに注意してください。

5. 結論

この記事では、 @EnableOAuth2Ssoアノテーションと@EnableResourceServerアノテーションの違いについて説明しました。 また、Zuulと簡単なAPIを使用した実際の例でそれらを使用する方法を示しました。

この例の完全な実装は、Githubにあります。

ローカルで実行する場合は、http://192.168.1.67:8765/resource-server-mvc-1でアプリケーションを実行してテストできます。