Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
32
Help us understand the problem. What is going on with this article?
@TakahikoKawasaki

Spring + OAuth 2.0 + OpenID Connect

More than 3 years have passed since last update.

1. クイックスタート

1.1. 認可サーバーをポート 8080 で起動

$ git clone https://github.com/authlete/spring-oauth-server
$ cd spring-oauth-server
$ vi authlete.properties
$ mvn spring-boot:run

1.2. リソースサーバーをポート 8081 で起動

$ git clone https://github.com/authlete/spring-resource-server
$ cd spring-resource-server
$ vi authlete.properties
$ mvn spring-boot:run

1.3. アクセストークンと ID トークンを発行

http://localhost:8080/api/authorization
    ?client_id={クライアントID}
    &response_type=token+id_token
    &scope=openid
    &redirect_uri={リダイレクトURI}
    &state={任意文字列}
    &nonce={任意文字列}

Web ブラウザで上記 URL にアクセスし、表示された認可ページで、ログイン ID = john、 パスワード = john を入力し『Authorize』ボタンを押す。

1.4. 保護リソースエンドポイントのサンプルにアクセス

$ curl http://localhost:8081/api/country/JP \
    -d access_token={アクセストークン}

1.5. ユーザー情報エンドポイントOpenID Connect Core 1.0

$ curl http://localhost:8081/api/userinfo \
    -d access_token={アクセストークン}

1.6. ディスカバリーエンドポイントOpenID Connect Discovery 1.0

$ curl http://localhost:8080/.well-known/openid-configuration

1.7. JWK Set エンドポイントRFC 7517

$ curl http://localhost:8080/api/jwks

1.8. イントロスペクションエンドポイントRFC 7662

$ curl http://localhost:8080/api/introspection \
    -d token={アクセストークン}

1.9. アクセストークン削除(リボケーションエンドポイント; RFC 7009

$ curl http://localhost:8080/api/revocation \
    -d token={アクセストークン}

2. アーキテクチャー

spring-oauth-server は OAuth 2.0 と OpenID Connect をサポートする認可サーバー兼 OpenID プロバイダーの実装です。

spring-resource-server は OpenID Connect で定義されているユーザー情報エンドポイントの実装を含むリソースサーバーの実装です。

どちらの実装も Spring Boot を使用していますが、Spring Security OAuth は使っていません。かわりに、OAuth 2.0 と OpenID Connect の実装として Authlete を使用しています。

Authlete それ自身は認可サーバー・OpenID プロバイダーの実装ではなく、それらを実装するための Web API のセットです。

relationship-between-frontend-server-and-authlete.png

このアーキテクチャーの一番の利点は、バックエンドサーバー(Authlete)が OAuth 2.0 と OpenID Connect の実装に集中でき、他の技術要素〜アイデンティティー管理、ユーザー認証、ログインセッション管理、API 管理、不正検出等〜を気にする必要がないことです。逆の言い方をすると、開発者は、OAuth 2.0 と OpenID Connect の実装を気にする必要なく、アイデンティティー管理やユーザー認証等で好きなソリューションを選択することができます。さらに言えば、開発者は、認可サーバー・OpenID プロバイダーを実装するのに、好きなプログラミング言語を選択することができます。このアーキテクチャーの詳細については、『OAuth 2.0 / OIDC 実装の新アーキテクチャー』を参照してください。

このアーキテクチャーのおかげで、フロントエンドサーバー(spring-oauth-server と spring-resource-server)は、アクセストークンやリフレッシュトークン、認可コード、クライアントアプリケーションのメタ情報、認可サーバー・OpenID プロバイダーのメタ情報などといった、OAuth 2.0 と OpenID Connect に関するデータを管理するためのデータベースを持つ必要がありません。これらのデータはバックエンドサーバー(Authlete)が管理します。

2.1. Spring Security OAuth に関する注意点

Spring Security OAuth がデータベーステーブルのスキーマさえ提供していないことは、ここで述べておいたほうがよいかもしれません。次の文は、Spring Security OAuth の『OAuth 2 Developers Guide』からの抜粋です。

NOTE: the schema for the JDBC service is not packaged with the library (because there are too many variations you might like to use in practice), but there is an example you can start from in the test code in github.

これはつまり、Spring Security OAuth ライブラリの API(ClientDetails インターフェース等)を調査し、対応するデータを保存するためのデータベーステーブルを自分で設計しなければならないということです。

OpenID Connect をサポートするためには、認可サーバー・OpenID プロバイダーは『3. OpenID Provider Metadata』(OpenID Connect Discovery 1.0)にリストアップされているメタ情報を持つべきですし、クライアントアプリケーションは『2. Client Metadata』(OpenID Connect Dynamic Client Registration 1.0)にリストアップされているメタ情報を持つべきです。しかしながら、Spring Security OAuth は OpenID Connect をサポートしていないので、Spring Security OAuth 上に OpenID Connect を実装しようと試みない限り、これらのメタ情報に対応するカラムをデータベーステーブルに含める必要はありません。

3. 技術詳細

3.1. Authlete API にアクセスするための API キー

Authlete API にアクセスするための API キーと API シークレットを取得し、spring-oauth-server と spring-resource-server の authlete.properties に設定する必要があります。

簡単です。アカウント登録ページでアカウント登録するだけです。アカウント登録時に、一つのサービス(認可サーバー・OpenID プロバイダーに対応するもの)と、そのサービスに属するクライアントアプリケーションが一つ、自動的に生成されます。そのサービスの API キーと API シークレットは、管理コンソール(Service Owner Console)で確認できます。

from-signup-to-service-details.png

3.2. クライアント ID

認可リクエストを実行するには、クライアントアプリケーションのクライアント ID を知る必要があります。Authlete はクライアントアプリケーション管理用のウェブコンソール(Developer Console)を用意しています。そのウェブコンソールの URL は https://cd.authlete.com/{サービスAPIキー} で、{サービスAPIキー}はクライアントアプリケーションが属するサービスの API キーです。ウェブコンソールにはサービスの API キーと API シークレットでログインすることができ、クライアント ID はそこで確認することができます。

from-so_console_to-cd_console-client_id.png

3.3. 認可サーバー・OpenID プロバイダー

まず、spring-oauth-server をダウンロードします。

$ git clone https://github.com/authlete/spring-oauth-server

次に、テキストエディタで設定ファイル authlete.properties を開き、service.api_keyservice.api_secret の値を変更します。

$ cd spring-oauth-server
$ vi authlete.properties

最後に、spring-oauth-server を起動します。

$ mvn spring-boot:run

3.4. 認可リクエスト

spring-oauth-server は /api/authorization で認可エンドポイントを公開しています。認可リクエストの response_type リクエストパラメーターの値が token id_token の場合、認可エンドポイントから直接、アクセストークンと ID トークンの両方が発行されます。OpenID Connect のフローにあまり詳しくない場合は『OpenID Connect 全フロー解説』を参照してください。

下記はアクセストークンと ID トークンの両方を取得するための認可リクエストの例です。

http://localhost:8080/api/authorization
    ?client_id={クライアントID}
    &response_type=token+id_token
    &scope=openid
    &redirect_uri={リダイレクトURI}
    &state={任意文字列}
    &nonce={任意文字列}

もちろん、{クライアントID}{リダイレクトURI}{任意文字列} の値は置き換えてください。クライアントアプリケーションのリダイレクト URI の値は Developer Console で確認できます。デフォルト値を変更していなければ、リダイレクト URI は https://api.authlete.com/api/mock/redirection/{サービスAPIキー} になっています。

認可エンドポイントは認可ページを返します。ログインフォームがあるので、ログイン ID とパスワードとして、johnjohn(もしくは janejane)を入力してください。それから『Authorize』ボタンを押します。この結果、ウェブブラウザはクライアントアプリケーションのリダイレクト URI にリダイレクトされます。

リダイレクト URI のデフォルト値を変更していなければ、Authlete サーバーが提供するリダイレクトエンドポイントのモック実装にリダイレクトされます。そのモック実装は受け取ったパラメーターを表示するので、発行されたアクセストークンと ID トークンの値をその場で確認することができます。

from-authorization_request-to-redirection_endpoint.png

3.5. リソースサーバー

アクセストークンが取得できたので、保護リソースエンドポイントへの API コールを実行することができます。しかしその前に、リソースサーバーを起動する必要があります。

まず、spring-resource-server をダウンロードします。

$ git clone https://github.com/authlete/spring-resource-server

次に、テキストエディタで設定ファイル authlete.properties を開き、service.api_keyservice.api_secret の値を変更します。

$ cd spring-resource-server
$ vi authlete.properties

最後に、spring-resource-server を起動します。

$ mvn spring-boot:run

3.6. API コール

spring-resource-server が提供する保護リソースエンドポイントのサンプルに対して API コールを実行する準備が整いました。もちろん、{アクセストークン}はアクセストークンの実際の値で置き換えてください。

$ curl http://localhost:8081/api/country/JP \
    -d access_token={アクセストークン}

おめでとうございます。全ての手順が完了しました。

次のステップ

  1. spring-oauth-server と spring-resource-server の README.mdCUSTOMIZATION.md を参照してください。

  2. java-oauth-serverjava-resource-server は JAX-RS API だけを用いた実装です。spring-oauth-server や spring-resource-server よりも、これらの実装のほうに興味をもたれるかもしれません。

さいごに

認可サーバー・OpenID プロバイダーの実装をお探しなら、Authlete をご検討ください。『OAuth 2.0 / OIDC 実装の新アーキテクチャー』を読めば、Authlete のアークテクチャーを好きになっていただけると思います :wink:

32
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
TakahikoKawasaki
株式会社 Authlete の共同創業者。プログラマー兼代表取締役社長。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
32
Help us understand the problem. What is going on with this article?