メインコンテンツまでスキップ

OIDC周りについて調べておく

OIDCについて調査しておく必要があったので、メモしておく

OIDCとは何か?

OIDC(OpenID Connect)はOAuth 2.0を拡張したユーザーの認証を行うための仕組み。
OAuth 2.0は、クライアントがリソースにアクセスする権限の付与(認可)を行うための仕組み。OAuth2.0ではアクセストークンの発行フローを定めている。
OIDCはOAuth2.0がベースとなっている仕組みで、IDトークンの発行フローを定めている。
この二つを区別する要素として「認証」と「認可」で分ければ良さげ。

認証・認可の区別

認証(Authentication AuthN):ユーザーが提供するアイデンティティ(メールアドレス・パスワードなど)を検証し、ユーザーが誰であるかを確認する。 認可(Authorization AuthZ):ユーザーのリソースに対するアクセスを許可・拒否する。

認証

https://qiita.com/TakahikoKawasaki/items/4ee9b55db9f7ef352b47

認証ではIDトークンと呼ばれるものを発行し、クライアントアプリケーションとのセッションを確立する。

IDトークン

https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06

https://openid.net/specs/openid-connect-core-1_0.html#IDToken

The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be Authenticated is the ID Token data structure. The ID Token is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims. The ID Token is represented as a JSON Web Token (JWT).

ユーザーの認証を可能にするために OpenID Connect が OAuth 2.0 に加える主な拡張機能は、ID トークン データ構造です。ID トークンは、クライアントの使用時に認可サーバーによるエンドユーザーの認証に関するクレーム、および場合によってはその他の要求されたクレームを含むセキュリティ トークンです。ID トークンは、 JSON Web トークン (JWT) [JWT] として表されます。

IDトークンはJWTの一種。
OIDCがOAuth2.0に対しておこなった主要な拡張が、まさに ID トークンというデータ構造として表される。

書式(Json Web Token)

ヘッダー.キー.初期ベクター.暗号文.認証タグ

https://tools.ietf.org/html/rfc7519

「JWT とは、JSON 形式で表現されたクレーム (claim) の集合を、JWS もしくは JWE に埋め込んだもの」
ほえ〜知らんかった。 JWTの中でも、ペイロードの埋め込み方法にJWSとJWEがあるらしい。

書式(Json Web Signature)

ヘッダー.ペイロード.署名

認証情報に関してはペイロードをデコードするとJSONを取得可能。ヘッダーとペイロードの中身を担保するために署名がある。
JWS形式のJWTでは、JSON形式で表現されたクレームをBASE64エンコードしたものをペイロードにセットする。

書式(Json Web Encryption)

ヘッダー.キー.初期ベクター.暗号文.認証タグ

IDトークンを暗号化したい場合はこちらの書式らしい。 JWE形式のJWTでは、JSON形式で表現されたクレームをを平文として暗号化したものをBASE64エンコードし、ペイロードにセットする。

認可

認可ではアクセストークンを発行し、それを元にクライアントがアクセス可能なリソースを判別する。

OIDCの認証フロー

https://qiita.com/TakahikoKawasaki/items/4ee9b55db9f7ef352b47

https://datatracker.ietf.org/doc/html/rfc6749

認可エンドポイント、トークンエンドポイントというものが存在しており、認可エンドポイントから返されるresponse_typeによってフローが異なるっぽい。
一般的なのはresponse_type=codeorresponse_type=tokenな印象。
この印象は間違っていなくて、現状一般的に使用されるのはこの二つらしい。 この二つのメリットデメリットはなんだろう。

codeの場合

https://qiita.com/TakahikoKawasaki/items/4ee9b55db9f7ef352b47#1-response_typecode

codeの場合は認可エンドポイントから認可コードを返し、その認可コードを元にトークンエンドポイントからIDトークンとアクセストークンを取得する方式。

scopeにopenidを含める場合にIDトークンも併せて払い出される形。含まれない場合は認可フローと全く同一。

https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f#1-%E8%AA%8D%E5%8F%AF%E3%82%B3%E3%83%BC%E3%83%89%E3%83%95%E3%83%AD%E3%83%BC

tokenの場合

https://qiita.com/TakahikoKawasaki/items/4ee9b55db9f7ef352b47#2-response_typetoken

https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.2

tokenの場合は認可エンドポイントからそのままアクセストークンが返される。IDトークンは返されない。
フロー的にはImplicit(暗黙的)になる。

暗黙的なアクセス許可は、いくつかのクライアント(たとえば、クライアントとして実装されたものなど)の応答性と効率を向上させます。クライアント(ブラウザ内アプリケーションとして実装されたクライアントなど)の応答性と効率を向上させます

応答性を見るのであればtokenを使う感じっぽい?

暗黙のグラントフローでアクセストークンを発行する場合、認可サーバはクライアントを認証しません。 場合によっては場合によっては、アクセストークンをクライアントに配信するために使用されるリダイレクト URIによってクライアントの身元を確認できる場合があります。

IDトークンを返さないところを見るに認証をやらず認可だけやる感じ。クライアントの認証が暗黙的っていう理解で良さげ?

ざっと見た感じ、基本的にはtype=codeを使う形になりそうな印象。

IDaaSを使わず独自実装を行う場合に考慮すべきこと

IDaaSに認証フローを任せる場合、以下のことを考えなくて良くなる。

  • 認証サーバー自体の実装
  • ユーザーに認証情報を入力させる画面の用意
  • 認証サーバーから払い出された認可コードからトークンを取得するロジック
  • リフレッシュトークン管理
  • ログアウト周りの処理

逆にいうと、独自実装を行う場合は上記について考える必要がありそう。

この辺り、具体的にはOSSのライブラリにも使えるものがありそうな感じ。

OIDCが定める認証のフローについてはある程度整理ができたが、この上でフロントエンド側が実装すべき内容について、まだ具体的に見えていない感じ。

なんとなく雰囲気は掴めたので、一旦ここで止めてまたメモを増やしてこ。