OAuth2 - @EnableResourceServerと@ EnableOAuth2Sso

OAuth2 – @EnableResourceServer vs @ EnableOAuth2Sso

1. 概要

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

まず、differences between an OAuth2 Client and an OAuth2 Resource Serverについて説明します。 その後、これらのアノテーションで何ができるかについて少し説明し、Zuulと単純なAPIを使用した例を使用してそれらの使用法を示します。

この記事の目的上、ZuulOAuth2の既存の経験を前提としています。

何も持っていないか、どちらかのレビューが役立つと思われる場合は、quick overview on Zuulguide to OAuth2を参照してください。

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

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

  • Resource Owner —保護されたリソースへのアクセスを許可できるエンティティ

  • Authorization ServerResourceOwnersの認証に成功し、承認を取得した後、Clientsにアクセストークンを付与します

  • Resource Server-リソースへのアクセスを許可する、または少なくとも検討するためにアクセストークンを必要とするコンポーネント

  • Client —認証サーバーからアクセストークンを取得できるエンティティ

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

OAuth2AuthenticationProcessingFilterおよびその他の同様に重要なコンポーネントを構成することによるThe @EnableResourceServer annotation enables our application to behave as a Resource Server.

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

逆に、the @EnableOAuth2Sso annotation transforms our application into an OAuth2 client。 これは、アプリケーションが承認サーバーからアクセストークンを取得できる必要がある他のコンポーネントとともに、OAuth2ClientAuthenticationProcessingFilterを構成するようにSpringに指示します。

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

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

  • 最初のアプリケーションはエッジノードになります。これは、@EnableOAuth2Ssoアノテーションを使用する単純なZuulアプリケーションです。 (AuthorizationServerの助けを借りて)ユーザーを認証し、受信したリクエストを他のアプリケーションに委任する責任があります

  • 2番目のアプリケーションは@EnableResourceServerアノテーションを使用し、着信リクエストに有効なOAuth2アクセストークンが含まれている場合、保護されたリソースへのアクセスを許可します

3. Zuul –@EnableOAuth2Sso

エッジノードとして機能し、OAuth2AuthorizationServerを使用してユーザーの認証を担当する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クラスによって作成されたものよりも優先されます。 これは、@EnableResourceServerによってトリガーされる構成クラスであるResouceServerConfigurationがデフォルトのorderを3に指定しているのに対し、WebSecurityConfigureAdapterのデフォルトのorderは100であるために発生します。

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

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ルートを構成し、リクエストをダウンストリームに送信する前に、どのヘッダーを追加/削除する必要があるかを指定します。

  • アプリケーションがAuthorizationServerと通信できるように、いくつかのOAuth2プロパティを設定し、symmetric暗号化を使用してJWTを構成します。

4. API –@EnableResourceServer

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

@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();
    }
}

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

最後に、いくつかのプロパティを構成してみましょう。

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

we need a valid access token(エッジノードのユーザーのHTTPセッションに格納されている)to access the endpoint of our Resource Serverであることに注意してください。

5. 結論

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

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

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