OAuth2 – @EnableResourceServer vs @ EnableOAuth2Sso
1. 概要
このチュートリアルでは、Spring Securityの@EnableResourceServerおよび@EnableOAuth2Ssoアノテーションについて説明します。
まず、differences between an OAuth2 Client and an OAuth2 Resource Serverについて説明します。 その後、これらのアノテーションで何ができるかについて少し説明し、Zuulと単純なAPIを使用した例を使用してそれらの使用法を示します。
この記事の目的上、ZuulとOAuth2の既存の経験を前提としています。
何も持っていないか、どちらかのレビューが役立つと思われる場合は、quick overview on Zuulとguide to OAuth2を参照してください。
2. OAuth2クライアントとリソースサーバー
OAuth2内には4つの異なるrolesを考慮する必要があります。
-
Resource Owner —保護されたリソースへのアクセスを許可できるエンティティ
-
Authorization Server —ResourceOwnersの認証に成功し、承認を取得した後、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();
}
}
これは、リクエストを開始したPrincipalのnameを返すために、単一のエンドポイントを公開するシンプルなアプリケーションです。
最後に、いくつかのプロパティを構成してみましょう。
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でアプリケーションを実行してテストできます。