1. 概要

Spring Cloud Securityモジュールは、SpringBootアプリケーションのトークンベースのセキュリティに関連する機能を提供します。

具体的には、OAuth2ベースのSSOを容易にし、リソースサーバー間でのトークンの中継をサポートし、組み込みのZuulプロキシを使用してダウンストリーム認証を構成します。

このクイック記事では、Spring Bootクライアントアプリケーション、承認サーバー、およびリソースサーバーとして機能するRESTAPIを使用してこれらの機能を構成する方法について説明します。

この例では、クラウドセキュリティ機能を実証するためにSSOを使用するクライアントアプリケーションが1つしかないことに注意してください。ただし、通常のシナリオでは、シングルサインオンの必要性を正当化するために少なくとも2つのクライアントアプリケーションがあります。

2. クラウドセキュリティアプリのクイックスタート

Spring BootアプリケーションでSSOを構成することから始めましょう。

まず、spring-cloud-starter-oauth2依存関係を追加する必要があります。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

これにより、spring-cloud-starter-security依存関係も発生します。

任意のソーシャルサイトをサイトの認証サーバーとして構成することも、独自のサーバーを使用することもできます。 この例では、後者のオプションを選択し、承認サーバーとして機能するアプリケーションを構成しました。 でローカルに展開 http:// localhost:7070/authserver。

承認サーバーはJWTトークンを使用します。

さらに、クライアントがユーザーの資格情報を取得できるようにするには、これらの資格情報を提供できるエンドポイントを使用して、ポート9000で実行されるリソースサーバーを構成する必要があります。

ここでは、 http:// localhost:9000/user。で利用可能な/userエンドポイントを構成しました。

承認サーバーとリソースサーバーの設定方法の詳細については、以前の記事をご覧ください。

これで、クライアントアプリケーションの構成クラスにアノテーションを追加できます。

@Configuration
@EnableOAuth2Sso
public class SiteSecurityConfigurer
  extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // ...    
    }
}

認証が必要なリクエストはすべて承認サーバーにリダイレクトされます。これを機能させるには、サーバーのプロパティも定義する必要があります。

security:
  oauth2:
    client:
      accessTokenUri: http://localhost:7070/authserver/oauth/token
      userAuthorizationUri: http://localhost:7070/authserver/oauth/authorize
      clientId: authserver
      clientSecret: passwordforauthserver
    resource:
      userInfoUri: http://localhost:9000/user

上記の構成が機能していることを確認するには、クラスパスにspring-boot-starter-securityが必要であることに注意してください。

3. アクセストークンの中継

トークンを中継している間、OAuth2クライアントは受信したOAuth2トークンを送信リソースリクエストに転送します。

@ EnableOauth2Sso アノテーションを宣言したので、Spring Bootはリクエストスコープに OAuth2ClientContextbeanを追加します。 これに基づいて、クライアントアプリケーションで独自のOAuth2RestTemplateを作成できます。

@Bean
public OAuth2RestOperations restOperations(
  OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) {
    return new OAuth2RestTemplate(resource, context);
}

bean を構成すると、コンテキストは、アクセストークンを要求されたサービスに転送し、有効期限が切れるとトークンを更新します。

4. RestTemplateを使用したOAuthトークンの中継

以前、クライアントアプリケーションでタイプOAuth2RestTemplaterestOperationsBeanを定義しました。 その結果、 OAuth2RestTemplateのgetForObject()メソッドを使用して、必要なトークンを含むリクエストをクライアントから保護されたリソースサーバーに送信できます。

まず、リソースサーバーで認証を必要とするエンドポイントを定義しましょう。

@GetMapping("/person")
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public @ResponseBody Person personInfo(){        
    return new Person("abir", "Dhaka", "Bangladesh", 29, "Male");       
 }    

これは、PersonオブジェクトのJSON表現を返す単純なRESTエンドポイントです。

これで、 getForObject()メソッドを使用してクライアントアプリケーションからリクエストを送信できます。このメソッドは、トークンをリソースサーバーに中継します。

@Autowired
private RestOperations restOperations;

@GetMapping("/personInfo")
public ModelAndView person() { 
    ModelAndView mav = new ModelAndView("personinfo");
    String personResourceUrl = "http://localhost:9000/person";
    mav.addObject("person", 
      restOperations.getForObject(personResourceUrl, String.class));       
    
    return mav;
}

5. トークンリレー用のZuulの構成

トークンをダウンストリームでプロキシサービスに中継する場合は、Spring Cloud Zuul EmbeddedReverseProxyを使用できます。

まず、Zuulを操作するためのMaven依存関係を追加する必要があります。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

次に、@ EnableZuulProxyアノテーションをクライアントアプリケーションの構成クラスに追加する必要があります。

@Configuration
@EnableOAuth2Sso
@EnableZuulProxy
public class SiteSecurityConfigurer
  extends WebSecurityConfigurerAdapter {
    //...
}

あとは、Zuul構成プロパティをapplication.ymlファイルに追加するだけです。

zuul:
  sensitiveHeaders: Cookie,Set-Cookie  
  routes:
    resource:
      path: /api/**
      url: http://localhost:9000
    user: 
      path: /user/**
      url: http://localhost:9000/user

クライアントアプリケーションの/api エンドポイントに着信するすべてのリクエストは、リソースサーバーのURLにリダイレクトされます。 また、ユーザー資格情報エンドポイントのURLを提供する必要があります。

6. 結論

このクイック記事では、OAuth2とZuulでSpring Cloud Securityを使用して、セキュリティで保護された承認サーバーとリソースサーバーを構成する方法と、Oauth2RestTemplateとEmbeddedZuulProxyを使用してサーバー間でOAuth2トークンを中継する方法について説明しました。

いつものように、コードはGitHubから入手できます。