はじめに
OAuthとOIDC(OpenID Connect)の違いについて、
それぞれで登場する概念やIDトークンとアクセストークンなどの説明を交えながら
まとめました。
OAuthとOIDCの違いは??
OAuthは認可、OIDCは認証のためのプロトコルです。
OIDCはOAuthの認可コードフロー(KeycloakではStandard Flowと表記)がベースになってその拡張なので、
まずは認可コードフローの登場人物と具体的なフローについて理解することが重要だと考えています。
こちらの記事で認可コードフローを図解してまとめているので、
必要であればご覧ください。
認可コードフローを図解|OAuth2.0(OIDC)の仕組みをSPAのSSO機能を例に解説
ちなみに、
僕はAuthleteの川崎さんの記事でOAuthの認可コードフローを勉強しました。
こちらもかなりわかりやすいです!!
OAuthとOIDCに登場する概念
OAuthの認可コードフローと、OIDCのフローはほぼ同じなのですが、
登場する概念に対する呼び名が異なります。(僕はこの辺りかなりこんがらがってました)
OAuthのクライアントについて補足
クライアントには大きく2つあります。
【コンフィデンシャルクライアント】
シークレットキーを機密に扱えるクライアント
(サーバーサイドで動くアプリがクライアントになるケース)
【パブリッククライアント】
シークレットキーを機密に扱えないクライアント
(SPAのフロントエンドがクライアントになるケース)
認可サーバとしてkeycloakを利用する際は、
クライアントの設定で、この辺り使い分けが必要です。
IDトークンとアクセストークン
OAuthの認可コードフローでは認可サーバからアクセストークンを発行してもらいます。
OIDCはOIDCフローでOPからIDトークン+アクセストークンが発行されます。
OIDCは認可コードフローとほぼ同じフローで
アクセストークンも発行するので認可に利用することもでき、
これで認証と認可OAuth、OIDCがこんがらがるんですよね。。。
ここからはおまけで・・・・
認可サーバが発行するトークンは、
JWTに改竄されても検知できるようにシグネチャを付与したJWS形式にすることがあります。
JWTには複数のクレーム入っており、
ユーザに独自の属性を持たせる(例えばユーザの所属先情報とか)場合、
keycloakではマッパーという機能を使えばクレームを追加できます。
JWSを解読できるjwt.ioというサイトのがあり、
それを使ってとあるトークンを解読できるようにしたのがこんな感じです。
アクセストークン
IDトークン
クレームは紫のところで、ここにorganization_typeという
所属先情報を追加したIDトークンにしたり、
さらに言うと、
SSOで初回ログイン時にシステム固有のユーザ項目などはここに追加しておいて、
そこから値を取り出して初回登録する。などに使えます。
SSOの初回ログインの実装方法悩んでたんですが、、
次はこのやり方で実装してみようと個人的に考えています。
トークンとリフレッシュトークン
IDトークンやアクセストークンと同時に、
リフレッシュトークンがKeycloakからは発行されます。
(あえて発行させない設定などもありますが一旦置いときます)
リフレッシュトークンの目的は、
簡単に言うと、何度も認証なり認可の作業をユーザにさせないことです。
トークンの有効期限が切れても、
リフレッシュトークンで新しいトークンを自動で発行できるイメージ。
keycloakの本では、
トークンの有効期限は数分〜数十分、
リフレッシュトークンの有効期限は数時間から数日を推奨されていました。
こうしておくと、トークンが盗まれても、数分くらいしか使えないようになります。
これもおまけですが・・・
以前、SPAにおけるアクセストークンやリフレッシュトークンの扱いは
何がベストプラクティスなんだろう。。。
と悩んでた時期があり、
OAuth2.0のブラウザベースアプリ(SPA)の
ベストプラクティスに近いこれを参考にいろいろ考察していたのですが
以下のサイトにたどり着きました。
>>OAuth 2.0 for Browser-Based Apps draft-ietf-oauth-browser-based-apps-08
In particular, authorization servers:
o MUST either rotate refresh tokens on each use OR use sender-
constrained refresh tokens as described in [oauth-security-topics]
Section 4.13.2o MUST either set a maximum lifetime on refresh tokens OR expire if
the refresh token has not been used within some amount of timeo MUST NOT extend the lifetime of the new refresh token beyond the
lifetime of the initial refresh tokeno upon issuing a rotated refresh token, MUST NOT extend the lifetime
of the new refresh token beyond the lifetime of the initial出典:OAuth 2.0 for Browser-Based Apps draft-ietf-oauth-browser-based-apps-08
ここには、ざっくり言うと
リフレッシュトークンは使用する度にローテーションしなければならない。
ローテーションの際、元のリフレッシュトークンの有効期限を伸ばしてはいけない。
(有効期限をそのまま引き継いでローテーションしなさい)
と述べられていました。
KeycloakでもTokenの設定でこの辺りできるので、
SPAでフロントエンドにトークンを返却しなければならない場合は
最低限この設定しておくべきかなと思います。
まとめ
今回はOAuthとOIDCの違いについてまとめました。
この辺りは押さえておきましょう。
- OIDCはOAuthの認可コードフローがベースになっている(認可コードフローの理解重要)
- OIDCとOAuthの登場人物の呼び名は違う
- アクセストークンとIDトークンとリフレッシュトークンの関係
おまけ
keycloakを認可サーバとして立ててSpring Bootで作成したRestAPIを保護、
SPAにKeycloakのSSO機能でログイン機能を付与、
などなど認証認可周りをまとめた記事を作りました。
是非こちらもご覧ください。
keycloakでAPI保護・SPAログイン機能設定例、OIDC・OAuth・PKCE・認可コードフロー図解などまとめ