【楽天ビューティー】Keycloakによる認証・認可実装

commerce-engineer.rakuten.careers

 

はじめに

こんにちは、レジャープロダクト部の楽天ビューティでアプリケーションエンジニアをしているKentaです。楽天ビューティは、ユーザーがサロンを検索・予約したり、サロンが設定や予約状況を管理したりするためのサービスです。この記事では、Keycloakを使用したOAuth2.0プロトコルに準拠した認証・認可プラットフォームを構築した経験について共有したいと思います。

 

当社には連携機能があり、サロンオーナーの同意を得て、サロンの在庫データをパートナー企業に提供しています。この連携機能は、サービス初期から運用されている比較的古い機能です。パートナー企業がサロンに代わってログインし、管理アプリケーションにアクセスして連携を実施していました。

 

近年、より現代的なアプローチや手法を取り入れるために、連携機能を更新することが議論されてきました。そして昨年、連携のためのAPIを提供し、認証と認可を管理するこの刷新に取り組むことを決定しました。

 

今回の刷新において、APIを他社に公開するのが初めてだったため、認証・認可に業界標準のアプローチをどのように実装するかが主要なポイントでした。検討の結果、Oauth2.0プロトコルを使用し、認証サーバーとしてKeycloakを使用することにしました。

 

Auth2.0Keycloakを選んだ理由

Oauth2.0は、ウェブサイトやアプリケーションが、ユーザーに代わって他のウェブアプリケーションがホストするリソースにアクセスできるように設計された標準です。2012年にOAuth 1.0に代わり、現在ではオンライン認可の事実上の業界標準となっています。一般的に、以下のフローに従います。

 

1.クライアントは、認証サーバーに認証を要求し、認証情報(クレデンシャル)を識別情報として提供します。

2.認証サーバーはクライアントを認証し、要求されたスコープが許可されていることを確認します。

3.リソースオーナーは、認証サーバーとやり取りしてアクセスを許可します。

4.認証サーバーは、グラントタイプに応じて、認証コードまたはアクセス/リフレッシュトークンをクライアントにリダイレクトします。

5.クライアントは、アクセストークンを使用して、リソースサーバーからリソースへのアクセスを要求します。

 

(参照: https://auth0.com/intro-to-iam/what-is-oauth-2 )

 

 

このプロトコルを選んだ理由は以下の通りです。

 

*安全で信頼性の高いプロトコルであり、多くのアプリケーションで広く採用されている。

*第三者アプリケーションがデータオーナーの承認を得てリソースにアクセスする必要があるという当社の要件に合致している。

*広く採用されているプロトコルであるため、両者が実装すべき内容が明確かつシンプルである。

 

Keycloakは、JavaベースのOSS製品で、IDおよびアクセス管理のためのものであり、ユーザーフェデレーション、強力な認証、ユーザー管理、きめ細かい認可などの機能を提供しています。また、RedHatの一部門であるWildFlyによって開発され、Apache License Version 2.0の下でライセンスされており、活発なオープンソースコミュニティがあります。

 

上の図は、セキュアなAPIアクセスを実現するための最終的なアーキテクチャを示しています。

 

大まかに、準備のために行った手順は以下の通りです。

 

 

このプロトコルを選んだ理由は以下の通りです。

 

*安全で信頼性の高いプロトコルであり、多くのアプリケーションで広く採用されている。

*第三者アプリケーションがデータオーナーの承認を得てリソースにアクセスする必要があるという当社の要件に合致している。

*広く採用されているプロトコルであるため、両者が実装すべき内容が明確かつシンプルである。

 

Keycloakは、JavaベースのOSS製品で、IDおよびアクセス管理のためのものであり、ユーザーフェデレーション、強力な認証、ユーザー管理、きめ細かい認可などの機能を提供しています。また、RedHatの一部門であるWildFlyによって開発され、Apache License Version 2.0の下でライセンスされており、活発なオープンソースコミュニティがあります。

 

上の図は、セキュアなAPIアクセスを実現するための最終的なアーキテクチャを示しています。

 

大まかに、準備のために行った手順は以下の通りです。

 

 

Keycloakを選んだ理由は以下の通りです。

 

・ライセンス料がかからない。

・比較的簡単に統合できるにもかかわらず、最新のセキュリティ標準をサポートおよび準拠しており、本番環境での使用に十分な機能とパフォーマンスを備えている。

・多くのカスタマイズが可能であり、特にユーザー認証やアクセス許可における当社サービス固有の仕様を満たしていた。

・大規模なオープンソースコミュニティが存在し、カスタマイズで困難に直面した場合に役立つと考えられた。

 

 

上の図は、セキュアなAPIアクセスを実現するための最終的なアーキテクチャを示しています。

 

大まかに、準備のために行った手順は以下の通りです。

 

Keycloakサーバーの準備

Keycloakイメージの選択

カスタマイズ

カスタムプロバイダーの実装

Keycloakは、ユーザーとそのアクセス権、認可などを管理するための多くの機能をサポートしています。ただし、これらの標準機能だけでは、ビジネスニーズや仕様をカバーできない場合があります。Keycloakはカスタムプロバイダーを提供しているため、独自のニーズに合わせたソリューションを実装することで機能を拡張できます。

統合方法は非常に簡単です。目的は、1つ以上のサービス実装を含むjarファイルを用意し、Keycloakが認識できる場所に配置することです。起動時に、Keycloakはクラスパスをスキャンし、標準のjava.util.ServiceLoaderメカニズムを使用して利用可能なすべてのプロバイダーを選択します。

Gradleプロジェクトの作成

Keycloakのサービスプロバイダーインターフェース(SPI)を使用して、独自の実装クラスを作成

拡張したいインターフェースにちなんで名付けられたサービス定義ファイルをプロジェクトに追加し、実装の完全修飾名を含めます。

 

 

# SPIクラスの実装

full.qualified.name.of.YourImplementation

```

Dockerfileを更新して、JARが指定されたディレクトリに配置されるようにします。

```

FROM quay.io/keycloak/keycloak:latest as builder

...

# プロバイダーJARファイルをプロバイダーディレクトリに追加

ADD --chown=keycloak:keycloak --chmod=644 myprovider.jar

/opt/keycloak/providers/myprovider.jar

# コンテキスト: ビルドコマンドを実行

RUN /opt/keycloak/bin/kc.sh build

```

構成の適用

Keycloakは、環境変数やCLIオプションを介して、ロギング、データソース設定、機能の有効/無効化などの構成のカスタマイズを提供します。

Jenkinsジョブの作成

アプリケーションのデプロイはJenkinsで管理しているため、イメージをビルドし、必要なKubernetesコンポーネントを適用するためのJenkinsジョブを作成しました。

 

トークン検証サービスの準備

oauth2.0はjwtアクセストークンで動作するため、トークンが有効で、リクエストがアクセススコープに従っている場合にリクエストを認可できるサービスを準備する必要がありました。

 

一般的に、このトークン検証はオンラインまたはオフラインのいずれかの方法で実行できます。

*オンライン:トークンの使用が試行されるたびに、Keycloakがサポートするトークン検証エンドポイントを呼び出す。

*オフライン:トークンをローカルで検証する。

 

クライアントからのリクエストがあるたびにKeycloakサーバーにアクセスすることによるオーバーヘッドが懸念されたため、オフライン方式を使用することにしました。また、ユーザーが無効になったらすぐに終了するのではなく、アクセストークンをそのTTLまで有効にする仕様としました。その他、リソースAPIへのリクエストをインターセプトし、それに応じてトークンを検証するサービスも実装しました。

 

これで実装完了です。連携機能のための認証・認可プラットフォームを構築することができました。

 

感想

Keycloakを初期実装から運用してきた中で、技術的な感想をいくつか共有しようと思います。

 

*非常に簡単かつ迅速に始めることができます。必要な構成に注意すれば、短時間でサーバーを起動できます。

*カスタムプロバイダーを使用すると、機能を簡単に拡張できますが、Keycloakのその部分がどのように機能するかをある程度学習する必要がありました。カスタマイズの複雑さと、拡張するために知っておくべきことは、仕様がより「カスタム」になるほど明らかに増加します。したがって、機能のカスタマイズの範囲が広い場合は、Spring Authorization Serverのようなフレームワークを利用して、関数に対するオーナーシップを高めることを検討するかもしれません(追加の労力を許容できる場合に限ります)。

*更新は頻繁かつタイムリーであり、セキュリティ関連のコンポーネントにとっては非常にありがたいことです。ただし、バージョン間のパッチのサポートは限られています。最新のメジャービルドのみがアクティブな開発とセキュリティ修正を受けます。最高のものを得るには、比較的短い期間でバージョン更新を処理する準備が必要です。

*高可用性アーキテクチャに関する具体的な手順はあまりないようです。コンセプトガイドと設計図は利用できるため、出発点として参照し、そこからソリューションを構築できるはずです。

 

個人的な感想として、認証・認可のソリューションに取り組むことで、当社のサービスのモダン化に大きく貢献できたと感じます。私にとっては不慣れな分野でしたが、この適応を学び、Keycloak実装プロジェクトを成功裏にやり遂げる機会を得られたことを嬉しく思っています

 

終わり

ここまでお読みいただきありがとうございました。

認証・認可方法を検討したい方、開発者が何に取り組んでいるのかを見たい方にとって、この記事が役立つことを願っています。

 

私たちと一緒に働きませんか?

コマース & マーケティングカンパニー レジャープロダクト部(LPD)では、新たなサービス開発から日々の運用・改善まで、一緒に働く仲間を募集中!エンジニアやプロダクトマネージャーなど、幅広い職種で募集しています。ご応募をお待ちしております。

 →LPDの採用情報はこちら

→全ての採用情報はこちら

corp.rakuten.co.jp