1. 序章

このチュートリアルでは、OAuth2.0を使用した動的なクライアント登録を準備します。 OAuth2.0は、HTTPサービス上のユーザーアカウントへの制限付きアクセスを取得できるようにする承認フレームワークです。 OAuth2.0クライアントは、ユーザーのアカウントにアクセスしたいアプリケーションです。 このクライアントは、外部Webアプリケーション、ユーザーエージェント、または単なるネイティブクライアントにすることができます。

動的なクライアント登録を実現するために、ハードコードされた構成ではなく、データベースに資格情報を保存します。 拡張するアプリケーションは、最初は Spring REST API+OAuth2チュートリアルで説明されていました。

:この記事ではSpringOAuthレガシープロジェクトを使用しています。

2. Mavenの依存関係

まず、次の一連の依存関係を設定します。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>    
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
</dependency>

spring-jdbc を使用していることに注意してください。これは、DBを使用して、新しく登録されたユーザーをパスワードで保存するためです。

3. OAuth2.0サーバー構成

まず、OAuth2.0認証サーバーを構成する必要があります。 主な構成は、次のクラス内にあります。

@Configuration
@PropertySource({ "classpath:persistence.properties" })
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig
  extends AuthorizationServerConfigurerAdapter {
    
    // config
}

構成する必要のある主要なものがいくつかあります。 ClientDetailsServiceConfigurer:から始めましょう

@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
    clients.jdbc(dataSource())
    
    // ...		
}

これにより、永続性を使用してクライアント情報を取得していることを確認できます。

もちろん、この標準データソースを設定しましょう。

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
    dataSource.setUrl(env.getProperty("jdbc.url"));
    dataSource.setUsername(env.getProperty("jdbc.user"));
    dataSource.setPassword(env.getProperty("jdbc.pass"));
    return dataSource;
}

そのため、アプリケーションは、メモリクライアントにハードコードされている通常のクライアントではなく、登録されたクライアントのソースとしてデータベースを使用します。

4. DBスキーム

次に、OAuthクライアントを保存するためのSQL構造を定義しましょう。

create table oauth_client_details (
    client_id VARCHAR(256) PRIMARY KEY,
    resource_ids VARCHAR(256),
    client_secret VARCHAR(256),
    scope VARCHAR(256),
    authorized_grant_types VARCHAR(256),
    web_server_redirect_uri VARCHAR(256),
    authorities VARCHAR(256),
    access_token_validity INTEGER,
    refresh_token_validity INTEGER,
    additional_information VARCHAR(4096),
    autoapprove VARCHAR(256)
);

oauth_client_detailsの最も重要なフィールドは次のとおりです。

  • client_id –新しく登録されたクライアントのIDを保存します
  • client_secret –クライアントのパスワードを保存します
  • access_token_validity –クライアントがまだ有効かどうかを示します
  • Authority –特定のクライアントで許可されている役割を示します
  • scope –許可されたアクション、たとえばFacebookでのステータスの書き込みなど。
  • authorized_grant_types は、ユーザーが特定のクライアントにログインする方法に関する情報を提供します(この例では、パスワードを使用したフォームログインです)。

各クライアントはユーザーと1対多の関係を持っていることに注意してください。つまり、複数のユーザーが単一のクライアントを利用できることを意味します。

5. いくつかのクライアントを永続化しましょう

SQLスキーマ定義を使用すると、最終的にシステムにデータを作成できます。基本的にはクライアントを定義します。

次のdata.sqlスクリプト(デフォルトではSpring Bootが実行されます)を使用して、DBを初期化します。

INSERT INTO oauth_client_details
	(client_id, client_secret, scope, authorized_grant_types,
	web_server_redirect_uri, authorities, access_token_validity,
	refresh_token_validity, additional_information, autoapprove)
VALUES
	("fooClientIdPassword", "secret", "foo,read,write,
	"password,authorization_code,refresh_token", null, null, 36000, 36000, null, true);

oauth_client_details の最も重要なフィールドの説明は、前のセクションで提供されています。

6. テスト

動的クライアント登録をテストするには、spring-security-oauth-serverプロジェクトとspring-security-oauth-resourceプロジェクトの両方を8081ポートと8082ポートで実行する必要があります。それぞれ。

これで、ようやくいくつかのライブテストを作成できます。

foosを読み取るためのアクセス権を持つfooClientIdPasswordという名前のクライアントを登録したと仮定します。

まず、定義済みのクライアントを使用して、認証サーバーからアクセストークンを取得しようとします。

@Test
public void givenDBUser_whenRevokeToken_thenAuthorized() {
    String accessToken = obtainAccessToken("fooClientIdPassword", "john", "123");
    
    assertNotNull(accessToken);
}

そして、アクセストークンを取得するロジックは次のとおりです。

private String obtainAccessToken(String clientId, String username, String password) {
    Map<String, String> params = new HashMap<String, String>();
    params.put("grant_type", "password");
    params.put("client_id", clientId);
    params.put("username", username);
    params.put("password", password);
    Response response = RestAssured.given().auth().preemptive()
      .basic(clientId, "secret").and().with().params(params).when()
      .post("http://localhost:8081/spring-security-oauth-server/oauth/token");
    return response.jsonPath().getString("access_token");
}

7. 結論

このチュートリアルでは、無制限の数のクライアントをOAuth2.0フレームワークに動的に登録する方法を学びました。

このチュートリアルの完全な実装は、GitHubにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。

テストするには、クライアントをDBに追加する必要があり、 .inMemory()構成は無効になることに注意してください。 古い。inMemory()構成を使用する場合は、ハードコードされたクライアントの構成を含む2番目のファイルがあります。