OAuth2.0とOIDC1.0

目次

1. はじめに

2. OAuth2.0 の最初の紹介

3.OAuth2.0

4.OIDC1.0

5. OAuth2.0 および OIDC1.0 認証モード選択の提案

6. 典型的なアーキテクチャと例

7. 付録 - OAuth および OIDC の共通エンドポイント


1. はじめに


アプリケーションの使用をユーザーから切り離すことはできないため、通常、ユーザーの認証と認可はアプリケーション アーキテクチャの不可欠な部分になります。今日のマルチフォーム アプリケーション アーキテクチャ システム (従来の WEB、マイクロサービス、SPA、デスクトップ、モバイル、IoT など) に直面して、OAuth2.0 および OIDC 1.0 は、ユーザーの認証と認可のための一連の普遍的なベスト プラクティスを提供します。この記事では、最初に OAuth2 について紹介します。 WeChat ログインを統合することによる .0 関連の概念、次に OAuth2.0 と OIDC1.0 をそれぞれ紹介し、OAuth2.0 および OIDC 1.0 認証モードに適用可能なシナリオと選択の提案を示します。最後に、典型的なアーキテクチャの統合例が次の場所に示されています。記事の終わり。

2. OAuth2.0 の最初の紹介

ここに画像の説明を挿入します
アプリケーション アーキテクチャの進化に伴い、従来の B/S セッション認証を経て、WeChat へのアクセスや Github ログインなど、OAuth2 に基づく三者ログイン統合が市場に登場しました。このとき、OAuth 2.0 (Open Authorization)徐々に多くの IT 実務者の目に留まり、OAuth2 における Token の実際のキャリアである JWT (Json Web Token) も、そのセキュリティ、ステートレスなどの特徴から広く使用されるようになりました。現在、OAuth2.0 および OIDC1.0 (OpenID Connect) アクセスを提供する IDaaS (ID as a Service) アイデンティティ サービス プロバイダー (Auth0、Authing、Azure ADFS など) が市場に登場しています。 OAuth2 の重要性を示しています。.0 および OIDC 1.0 システムの段階的な改善と普及。次に、OAuth2.0とOIDC 1.0の謎を徐々に解明していきます。
アプリケーションの WeChat ログインへのアクセスを例として、WeChat OAuth2.0 ログインにアクセスするためのシーケンス図を以下に示します。

 ここに画像の説明を挿入します

 

アクセス プロセス全体で、アプリケーションは次の 3 つのタイプに分類されます。
1) サードパーティ アプリケーション、つまりユーザーをガイドする必要がある自社開発のアプリケーション (OAuth2.0 のクライアントに相当) (OAuth2 のクライアントに相当) .0) リソース所有者) は、WeChat ログイン ページにジャンプします (ブラウザ リダイレクト、モバイル アプリの起動)。WeChat ユーザー認証が現在のアプリケーションに正常にリダイレクトされた後、現在のアプリケーションは一時的な認証コード code とクライアント キー情報 (クライアント) を渡します。 ID、クライアント シークレット) を使用してアクセス トークンを取得し、アクセス トークンを保持して WeChat ユーザー情報を取得し、WeChat ユーザー情報を現在のアプリケーションのユーザー情報に変換します。このとき、ユーザーを確立する必要もあります。現在のアプリケーションに対応する情報 ログイン ステータス (ログインの成功を示すセッションなど)。

2) WeChat ユーザー認証サービス。WeChat ユーザーがサードパーティのアクセス アプリケーション (つまり、OAuth2.0 認可サーバーに対応する認可サーバー) を認可するように WeChat ユーザーをガイドするサービスであり、次のような WeChat ユーザー認証および認可ページを提供します。 QR コードをスキャンしてログイン ページにログインするブラウザへのリダイレクト。モバイル端末は WeChat APP ログイン確認 (つまり、OAuth2.0 に対応する認可エンドポイント) を呼び出し、ユーザーが認可を完了すると、一時的な認証コード コードはサードパーティ アプリケーションにリダイレクトされ、後続のトークン発行サービス (つまり、アクセス トークン、リフレッシュ トークンのコード交換、リフレッシュ トークン サービスの提供など、OAuth2.0 に対応するトークン エンドポイント) が提供されます。

3) WeChat API サービス。WeChat ユーザーの詳細を照会するためのサードパーティ アプリケーションへのアクセスを提供し、サービス (つまり、OAuth2.0 に対応するリソース サーバー) にアクセスするときにサードパーティ アプリケーションが保持するアクセス トークンの認証と認証を必要とします。リソースサーバー)。
上記のプロセス全体は、OAuth2.0 の 2 つのコア認証モード、つまり認証コード モードとリフレッシュ トークン モードに対応します。

WeChat OAuth2.0 (つまり OAuth2.0 認証コード モード) のアクセスがなぜこれほど複雑なのかを考えてみましょう。
まず、サードパーティ アプリケーションにより、WeChat ユーザーはジャンプ (リダイレクト、WeChat APP の起動) によって WeChat アプリケーションの範囲内 (WeChat Web ドメイン名および WeChat APP 内) で認証と認可を完了でき、次に WeChat ユーザーとパスワード情報が完了します。接続されたサードパーティ アプリケーションに公開されなくなり、認証プロセス全体のセキュリティが向上します。なお、OAuth2.0プロトコルの採用後は、サードパーティアプリケーションとWeChatのアクセスエンドポイント(認可エンドポイント、トークンエンドポイント)が固定となり、両者がこの協定を維持する限り、その後のWeChatの認証・認可方式に関わらず変更されません。 (2 つの QR コード、ログイン フォーム、その他の認証方法の提供など) は、接続されているサードパーティ アプリケーションには影響しません。つまり、WeChat は、すでに接続されているサードパーティ アプリケーションに影響を与えることなく進化し続けることができます。応用。要約すると、OAuth2.0 へのアクセスはある程度の複雑さを伴いますが、WeChat に高いセキュリティと柔軟な拡張性をもたらし、サードパーティ アプリケーションに一度だけの認証アクセス エクスペリエンスをもたらします。これは OAuth2.0 によってもたらされる利点でもあります。
次に、上記の WeChat OAuth 2.0 認証プロセスをさまざまな観点から見てみましょう。
1) WeChat の観点、現時点では、WeChat は OAuth2.0 における認証サービス (Authorization Server) とリソース サービス (Resource Sever) のプロバイダーとして機能します。 OAuth2.0 でクライアントとしてアクセスするアプリケーションは、WeChat 認可サービスを通じて認証と認可を実行し、WeChat リソース サービスを通じてユーザー情報を取得する必要があります。
2) アイデンティティクラウドの観点、すなわち、IDaaS (ID as a Service) アイデンティティサービスプロバイダの観点 IDaaS サービスプロバイダは、OAuth2.0 における認可サービス (Authorization Server) のプロバイダとして機能し、統一的にユーザー、組織、権限、およびその他のユーザー関連事項を管理します。OAuth2.0 でクライアントとしてアクセスする情報およびアプリケーション (Web、SPA、モバイル APP など) は、OAuth2.0 の認可サービスを通じて認証および認可される必要があります。つまり、クライアントは IDaaS が発行する Access Token を保持し、IDaaS による認証を受けて自社 API サービスにアクセスする必要があります。アクセス トークンの認証と認証 (JWT 署名公開キーの検証または IDasS へのトークン認証の要求を介して)。
3) 統合ユーザー認証センターを自社構築する観点から、上記の IDaaS の観点に一歩近づき、独自のユーザー認証センターを構築する場合、ユーザー認証センターが認可サービス (認可サーバー) として機能します。 OAuth2.0 プロバイダーの OAuth2.0 認可エンドポイント Authorization Endpoint、トークン エンドポイント Token Endpoint などを実装します。 私たちのアプリケーションは、クライアント (クライアント) またはリソース サービス (リソース サーバー) の役割で統合ユーザー認証センターにアクセスできます。OAuth2.0 (後述する OIDC 1.0 と組み合わせる) が企業内での統一ユーザー認証センターの構築にも適しており、他のサードパーティに対して一貫したユーザー認証アクセス エクスペリエンスを提供できることを見つけるのは難しくありません。アプリケーション。

3.OAuth2.0


OAuth 2.0 (Open Authorization、開発認可) は、認可のためのオープンな業界標準です。現在、HTTP プロトコル スタックのみをサポートしており、従来の Web アプリケーション、SPA、モバイル アプリケーション、デスクトップ アプリケーション、およびその他のスマート デバイスに適しています。OAuth2.0 では、認可サーバー、クライアント、リソース所有者、リソース サーバーなどの概念が導入され、各役割の責任が分離され、明確に分割されます。従来の認証モードと比較して、OAuth2.0 は、アクセス範囲、有効期間などを含む一時的なアクセス トークン (JWT 形式) をクライアントに発行します (ユーザーのリソース所有者がクライアントに認可することに同意した後)。自動情報 (属性を定義する方法) により、ユーザーのアカウントとパスワードがクライアントに直接公開されることが回避されます。その後、クライアントはアクセス トークンを使用して、リソース サーバー上の保護されたリソースにアクセスします。リソース サーバーは、アクセス トークンを含むリクエストを認証します。そして認証。JWT の利点を利用して、OAuth2.0 は、単一のアクセス トークン (グローバル ユーザー設定ではなく単一の承認に相当) のアクセス スコープ (JWT スコープ) をよりきめ細かい方法で制御し、単一のアクセス トークンの取り消しを制御できます ( OAuth2.0 トークン失効エンドポイントに対応)。同時にトークンリフレッシュモード(OAuth2.0のリフレッシュトークンエンドポイントに相当)も提供し、ユーザーはよりスムーズなログイン継続とより良いエクスペリエンスを提供します。
現在、OAuth 2.0 は次の認証モードをサポートしています。

認可モード 説明する

認可コードモード(認可コード)

コードをトークンに交換する

これはより一般的に使用されており、セキュリティ レベルが高く、Web バックエンドを備えたアプリケーションに適しています。

PKCE 付き認証コード モード (PKCE 付き認証コード)

code+code_verifier をトークンに交換します

フロントエンド サービス (SPA) およびネイティブ アプリケーション (デスクトップ、モバイル) に適用されます。

クライアントの資格情報

Cient 資格情報 (ClientId と Secret) を介してトークンを交換します。

サーバー間 (M2M) 通信に適しています。

リフレッシュトークンモード(リフレッシュトークン)

Refresh_token を介して新しいトークンを交換します

前回の認可時に発行されたrefresh_tokenに基づいて新しいaccess_tokenを取得することで、ユーザーの繰り返しログイン(無意味なログイン)を防止し、ユーザーエクスペリエンスを向上させます。

デバイスコードモード(デバイスコード)

deviceCode+UserCode+VerficationUri は、ユーザーが他のデバイス (携帯電話など) を介して認証および認可できるようにガイドします。

スマート TV、電子フォト アルバム、プリンターなど、ブラウザーを持たない、またはインターネットに接続できる入力が制限されているデバイスの認証に適しています。

暗黙

トークンを直接返す

認可コードモードのフォールバックオプションとしては推奨されません。

パスワードモード(パスワード)

ユーザー名とパスワードをトークンと直接交換します。

推奨されません。最も安全ではありません。クライアントはユーザー アカウントを知る必要があり、クライアントは認証方法に強く束縛されています。その後の認証方法の変更には、クライアントの変更も必要です。


現在、OAuth 2.0 は次の認証モードをサポートしています。

認可コードモード (Authorization Code) とリフレッシュトークンモード (Refresh Token) については、上記の WeChat OAuth2.0 認証と認可アクセスを参照してください。表に記載されている暗黙的モード (Implict) では認可コードが省略されています。モードです。コードで認証コードを発行する代わりに、トークンがクライアントに直接返されます。このモードでは、トークンがブラウザに直接公開されるため、トークンが漏洩するリスクが増加します。そのため、OAuth コミュニティでは推奨されなくなりました。このモードは現在、認証コード モードが使用できない場合の代替手段としてのみ使用されます。
前述の認証コード モードでは、クライアントがクライアント キーを安全に保存する必要がありますが、今日の SPA、モバイル端末、およびその他のクライアントの場合、クライアントの実行環境に直接公開されているため (バックエンド サーバー アプリケーションとは異なり、ユーザーが直接アクセスすることはできません)サーバーにアクセスする)、ユーザーは特別な方法でそのコードを表示できるため、クライアント キーが公開される危険性があります。そこで、OAuth2.0 では、認証コードモードに基づく **PKCE (Proof Key for Code Exchange)** 暗号化方式を使用し、悪意のある第三者による不正アクセスを防止する認証コード + PKCE モード (Authorization Code With PKCE) を提供しています。たとえ認可コードが傍受されても、認証サーバーとアクセストークンをやり取りすることはできず、同時にクライアントシークレットの漏洩を防ぐためにクライアント側にクライアントシークレットを保存する必要もありません。認証コード + PKCE モードは次のとおりです。

ここに画像の説明を挿入します
クライアント認証情報モードは、特定のユーザー操作を必要としないサーバー間 (M2M) 通信に適しており、クライアント認証情報のセット (クライアント ID、クライアント シークレット) がサーバーごとに事前に発行され、その後、サーバーは認可を直接呼び出します。サーバーは、アクセス トークンのクライアント資格情報を交換し、アクセス トークンを伝送して他のリソース サーバー (リソース サーバー) と通信します。クライアント資格情報モードの具体的なシーケンス図は次のとおりです。

ここに画像の説明を挿入します 


パスワード モードは実装が最も簡単なモードですが、最も推奨されないモードでもあります。つまり、クライアントはユーザーのアカウント パスワードを取得した後、認可サーバーのトークン エンドポイントを直接呼び出してアクセス トークンを取得します。パスワード モードの具体的なシーケンス図は次のとおりです。

ここに画像の説明を挿入します
WeChat アカウントとパスワードが接続されたクライアントに公開されている (たとえば、新しく開発されたアプリがログインするために WeChat に接続されている) と、クライアントはユーザーの WeChat アカウントでやりたいことを何でもできると想像してください。これは明らかに最も安全ではありません。たとえそれが自社構築の認証センターであっても、接続されているクライアントは当社のアプリケーションであり、接続されているクライアントはユーザー アカウントとパスワードを取得できるため、明らかに情報漏洩のリスクも高まります。ユーザー アカウントとパスワードについては、明らかに望ましくありません。ユーザーのアカウントとパスワードに関しては、知っている人が少ないほど (クライアント アプリケーションが少ないほど)、より良くなります。もう 1 つのポイントは、ログインにパスワード モード (ユーザー名、パスワード) を使用することです。クライアントは認証方法にバインドされます。たとえば、今日ユーザー名とパスワードを使用してログインする場合、携帯電話番号を使用してログインしたいとします。明日は検証コードを追加し、明後日には検証コードを追加します... , その後、クライアントはそれに応じて変更する必要があります。ユーザー名とパスワードの 2 つのパラメータだけを使用するだけでは十分ではないため、一度ユーザー認証ロジックが変更された場合、すべてのクライアントはそれに応じて変更し、認証コード モードを使用する必要があります。クライアントと認証センター間のプロトコルは固定されており、認証ロジックの変更は認証センターに限定されており、影響はありません。クライアント。これが、パスワード モードが推奨されない理由です。

デバイス コード モードは、スマート TV、電子フォト アルバム、プリンターなど、ブラウザなしで、または入力が制限された状態でインターネットに接続できるデバイスの認証に適しています。スマート TV 上のアプリケーション ログインを参照できます。このとき、スマート TV がデバイス、スマート TV にインストールされているアプリケーションがクライアントになります。テレビ上のアプリケーションは、最初に認証サーバーにリクエストを開始して、デバイス コード、次にテレビ上のアプリケーションが返されたデバイス コード (デバイス コード) に基づいてバックエンド認証サーバーとの長いポーリングを確立し、ユーザーが検証 URL にアクセスして正しいユーザー コードを入力するように誘導します。認可サーバーはユーザー コードが正しいことを確認すると、ユーザーにログインと認可を案内します (ブート プロセス全体を QR コードをスキャンして簡素化し、より良いユーザー エクスペリエンスでログインできます)。ユーザーが現在の TV デバイス上のアプリケーションを認証および承認すると、デバイス上のアプリケーションに直ちに通知され、アクセス トークンが返されます。その後、TV デバイス上のアプリケーションは、アクセス トークンを介して他のリソース サーバー (リソース サーバー) と通信できるようになります。特定のデバイス コード モードのタイミング図は次のとおりです。

ここに画像の説明を挿入します
前述の OAuth2.0 に加えて、新しい OAuth2.1 ドラフトもリリースされており、OAuth2.0 と比較した主な変更点は次のとおりです。

 

認証コード、クライアント認証情報、リフレッシュ トークン、およびデバイス コード モードのみが保持されます。
暗黙的モード (Implicit) とパスワード モード (Password) を削除します。
認証コードモードではPKCEを使用する必要があります。
ベアラー トークンはクエリ パラメーター フォームを使用できません。
リフレッシュ トークン モード (パブリック クライアント用のリフレッシュ トークン) はより厳密です。つまり、クライアント シークレット (送信者制限) を提供できないクライアントには合理的な制限が課されます。または、リフレッシュ トークンでのみ使用できるのは、使用は 1 回 (one -time)、各リフレッシュの後、古いリフレッシュ トークンは無効になり、新しいリフレッシュ トークンが同時に発行されます。


4.OIDC1.0


OIDC1.0(OpenID Connect)は、OAuth2.0プロトコル(OAuth2.0のスーパーセット)をベースとした本人認証標準プロトコルであるOAuth2.0上にアイデンティティ層(Identity、Authentication)を構築します。OAuth2.0 では認可がより重視されています。OIDC1.0 は、OAuth2 認可サーバーを使用してサードパーティのクライアントにユーザー ID 認証を提供し、対応する ID 認証情報 ID トークンをクライアントに渡し、ユーザー情報 (UserInfo) を取得するためのインターフェイスを提供します。エンドポイント)、さまざまなタイプのクライアント (サーバー アプリケーション、モバイル APP、JS アプリケーション (SPA) など) に適しており、OAuth2.0 と完全に互換性があります。つまり、OIDC1.0 認証サービスが構築されています。 OAuth2.0 認証サービスとしても使用できます。この段階では、ユーザー認証と認可 (最初にユーザーを認証してからリソースを返す)、およびシングル サインオン SSO とシングル サインアウト SLO を実装するには、OIDC1.0 プロトコルを使用することをお勧めします。
OIDC1.0 プロトコルの用語は OAuth2.0 の内容と基本的に同じですが、名称が若干異なります。

OIDC1.0 OAuth2.0  説明する
EU
エンドユーザー
リソース所有者 リソースを所有するユーザー
RP
依拠当事者
クライアント
サードパーティアプリケーション
OAuth2で信頼できるクライアント(Webアプリケーション、SPA、モバイルアプリケーション...)を参照するには、つまり認証センター(OP、認可サーバー)にアクセスしてログインし、ジャンプしてトークン(IdToken、AccessToken)を取得します。 IdToken を使用してユーザー ID 情報を取得し、AccessToken を使用してリソース (リソース サーバー、ユーザー情報エンドポイント) にアクセスできます。
OP
OpenID プロバイダー
認可サーバー ユーザー (EU、リソース所有者) に認証サービス (WeChat 認証プラットフォーム、Github 認証プラットフォーム、自社構築ユーザー センターなど) を提供し、ユーザー (EU、リソース所有者) の ID をアプリケーション クライアント (RP) に提供します。 、クライアント)認証情報。
リソースサーバー リソースサーバー リソースサーバーはリソースAPIを提供するサービスであり、(保護された)リソースへのアクセスを認証する必要があり、Cilent側がResourceServerにアクセスするためのAccessTokenを保持し、リソースサーバーがAccessTokenを認証します。
終点 終点 エンドポイント、つまり提供された API インターフェース
IDトークン なし 認証に使用される ID トークン (JWT) は、ユーザーの ID が認証されたことを示し、ユーザー ID 情報 (ユーザー名、アバターなど) を取得するために使用できます。取得した ID トークンの署名検証と属性検証 (aud)、azp、nonce など)。
アクセストークン アクセストークン 認証に使用されるアクセス トークン (JWT)。API アクセス認証に適しています。
ユーザーエージェント ユーザーエージェント ブラウザや携帯電話などのアプリケーションの実行側がRPの実行側となります。


OIDC1.0定义了实现单点登录SSO、单点登出SLO的扩展协议,相关协议如下:

OIDC1.0补充协议 说明
OpenID Connect Core 1.0 - UserInfo Endpoint RP端向OP发出查询用户详细信息的请求。
OpenID Connect RP-Initiated Logout 1.0 RP端向OP发出的初始登出请求(适用于单点登出SLO,end_session_endpoint),OP首先清除OP端的session,然后向当前session下的其他已登录的RP触发Front-Channel或者Back-Channel登出请求,最终可通过post_logout_redirect_uri 重定向会当前RP。3
OpenID Connect Front-Channel Logout 1.0 返回OP前端登出页面,页面通过嵌入iframe(src=frontchannel_logout_uri),同时触发当前OP Session对应的多个Client的登出接口。
OpenID Connect Back-Channel Logout 1.0     OP直接向当前OP Session对应的多个Client后端服务(不依赖User Agent,如不依赖浏览器)发送登出请求backchannel_logout_uri,且适用于User Agent被关闭的时候也可以退出登录。
OpenID Connect Session Management 1.0 RP端通过check_session_iframe监听当前UserAgent中用户的登录状态,收到登录状态改变通知后RP应该清除自己的Session信息、页面跳转等。


五、OAuth2.0 & OIDC1.0授权模式选型建议


关于授权模式的选择可以参见下图(图片截取自国内身份云厂商Authing - 选择OIDC授权模式):

ここに画像の説明を挿入します
总结上图,关于OAuth2.0 & OIDC1.0授权模式的最佳选型建议如下:

 

应用类型(即Client) 选型建议
WEB应用(即存在Web后端服务)
适用于获取第三方资源、集成第三方登录(如微信登录)
授权码模式
接入OAuth后携带code回调到Web后端, 由后端获取AccessToken, 在后端携带AccessToken请求资源, 可使用session存储Token和User信息, 即使用session作为当前Web应用的身份验证机制
服务器间通信
无终端用户
Client Credentials 模式
SPA
如Vue、React等单页应用(前后端分离), 有专门的后端资源服务层(Resource Server)提供API服务
PKCE + 授权码模式
即由前端接入认证,而后端仅接入鉴权
注: 如采用Node.js运行时环境并提供安全的后端存储,则可直接使用授权码模式。
原生应用Native(移动端应用、桌面应用)
如Android、Ios(前后端分离), 有专门的后端服务层(Resource Server)提供API服务
PKCE + 授权码模式
即由前端接入认证,而后端仅接入鉴权


六、典型架构及示例


接下来我们以如下比较典型的架构(前后端分离+微服务+应用网关)为例,具体讲解如何结合Spring生态(Spring Cloud Gateway、Spring Security OAuth2)实现一套基于OAuth2.0 & OIDC1.0(授权码+PKCE)的统一用户认证及鉴权示例,整体架构如下图:

ここに画像の説明を挿入します
各应用类型说明如下表:

 
各应用间交互的时序图如下:

ここに画像の説明を挿入します

 

接下来对各应用的具体实现依次说明。

6.1 用户认证中心
用户认证中心可基于Spring社区开源的OAuth2授权服务器实现:
https://github.com/spring-projects/spring-authorization-server
spring-authorization-server构建于Spring Security之上,所以可以通过简单的实现UserDetailsService来完成用户信息的检索,且关于授权信息的后端存储支持JDBC实现(支持自定义实现),与Spring框架集成方便,支持主流的OAuth2.0 & OIDC1.0授权模式,如授权码(Authorization Code)、授权码+PKCE(本示例基于此模式)、客户端凭证(Client Credentials)、刷新令牌(Refresh Token)等。在集成启动认证服务器后,还需要注册对应的客户端信息(即对应本示例的客户端定义),注册代码如下:

ここに画像の説明を挿入します

 

在认证服务集成启动后,客户端即可通过认证服务提供的自动发现端点(/.well-known/openid-configuration),获取OAuth2.0 & OIDC1.0的端点、授权类型、公钥等相关信息,具体返回信息如下:

ここに画像の説明を挿入します

 

在OAuth2.0协议中关于用户具体的 登录方式(账号密码、手机号、集成第三方等) 和 授权方式(授权页面,如点击按钮确认等) 并没有给出定义,开发者可以根据需要灵活扩展,此处的变动并不会影响整个OAuth2.0授权流程,对接入的客户端也没有影响。本例采用spring-authorization-server实现授权服务器,其底层默认使用Spring Security的FormLogin模块,所以在用户进行认证时,其默认的登录页面如下:

ここに画像の説明を挿入します
6.2 客户端
客户端采用SPA实现可参见:https://github.com/panva/node-openid-client,本作者非专业前端开发,所以以后端集成为例,但二者集成原理类似,同样具有借鉴作用。作为客户端,其主要的工作包括:
1)引导用户跳转(附加PKCE挑战码coder_challenge)到统一用户认证授权页面(即对应OAuth2.0授权端点Authorization Endpoint)。
2)处理授权码Authroization Code回调请求,携带授权码(附加PKCE验证码coder_verifier)调用统一用户认证服务(即对应OAuth2.0的令牌端点Token Endpoint)换取访问令牌Access Token、身份令牌ID Token和刷新令牌Refresh Token。
3)验证身份令牌ID Token(签名验证、属性验证aud、azp、nonce等)
4)安全地存储令牌(加密存储 或session存储)。
5)携带访问令牌Access Token获取并存储用户详细信息(即对应OIDC1.0 UserInfo Endpoint)
6)携带访问令牌Access Token访问API服务(即访问应用网关后再由网关进行转发)
7)待访问令牌即将过期时自动刷新令牌
可以发现,客户端的工作内容还是比较多的,但是借助相关的OIDC开发框架(如SPA端的openid-connect,Java端的spring-boot-starter-oauth2-client),集成还是很方便的。有了这些框架帮助开发者把核心流程、API等固定下来(上面提到的1~5,7步都由框架完成),开发要做的就只剩如下几块: 

1)配置客户端注册信息,需要与之前在用户认证中心Authorization Server中的注册信息相对应,示例配置如下:

ここに画像の説明を挿入します
2)获取发起请求的用户信息(例如需根据用户身份查询数据等),在Spring Security中可通过SecurityContextHolder.getContext().getAuthentication()获取,又或者直接通过参数注入进行获取,示例如下图:

 ここに画像の説明を挿入します

 


3)访问资源服务时携带令牌(Bearer Token),例如使用WebClient进行Http调用的集成示例代码如下:

ここに画像の説明を挿入します
6.3 应用网关
由之前的客户端Client对Resource Server(也即此应用网关)发起调用,Resource Server提取请求头中的Authorization: Bearer AccessToken 中的AccessToken,此处的AccessToken即对应OAuth2.0的Access Token,Resource Server端提供2种对此令牌的鉴权方式:
1)方式1 - JWT:Resource Server端通过public JWK(JWT签名公钥或其发现端点)对令牌中的签名进行验证,配置示例如下:

 ここに画像の説明を挿入します

 


2)方式2- Opaque Token:Resource Server端调用授权服务器(即之前的用户认证中心)端的令牌验证端点(introspection-uri)对令牌进行验证,配置示例如下:

ここに画像の説明を挿入します
关于以上2种方式,推荐方式1 -JWT,可以减少一次Resource Server到授权服务端的HTTP调用,性能更好。若应用场景中对令牌时效及安全性有强制要求,可配合使用方式2 - Opaque Token和OAuth2.0的吊销令牌端点(Token Revocation Endpoint),即完全由授权服务端控制令牌的有效性,但性能相应也会有所降低。
在以上2种鉴权方式的基础上,亦可添加额外的自定义权限验证,示例代码如下:

ここに画像の説明を挿入します 

 


6.4 后端API服务
由于使用了SCG应用网关,将用户鉴权的操作前置到网关层,所以后端的服务实现仅需关注核心业务逻辑即可。如果后端API服务有获取用户身份的需要(例如需根据用户身份查询数据、确定操作人等),可参见如下几种实现方式:

1)SCG应用网关将客户端请求中携带的请求头Authorization: Bearer AccessToken透传到后端服务,后端服务通过解析此Access Token(无需JWT签名公钥)中的相关属性便可获取对应的用户信息(如JWT sub)。

2)可在SCG应用网关处对AccessToken属性(如JWT sub)进行解析,生成用户信息后再通过指定请求头透传到后端服务,后端服务可直接通过该请求头获取用户信息。

3)由客户端提供用户信息(解析ID Token或者UserInfo)作为参数或者请求头,然后由网关透传到后端服务,后端服务可直接解析对应的用户信息。

关于后端服务间的相互调用为集群内的服务调用,可无需鉴权,仅通过应用网关进入(客户端调用)的请求需要鉴权。若对集群内的服务间调用有安全层面的限制,建议通过Service Mesh层面(如使用Istio的AuthorizationPolicy)进行控制,避免服务过于臃肿。

七、附录- OAuth & OIDC常用端点


OIDC和OAuth的常用端点(Endpoint,即提供的API接口)

endpoint 提供方 调用方 认证 格式 desc
authoriztion_endpoint OP RP

Code Flow模式:
GET authorization_endpoint
?response_type=code
&redirect_uri={redirect_uri}
&client_id={client_id}
&state={random_str}
&nonce={another_random_str}
&scope=openid profile email

PKCE + Code Flow模式
(额外添加code_challenge参数)
GET authorization_endpoint
?response_type=code
&redirect_uri={redirect_uri}
&client_id={client_id}
&state={random_str}
&nonce={another_random_str}
&scope=openid profile email
&code_challenge_method=S256
&code_challenge={code_challenge}

进入OP登录授权界面
redirect_uri RP OP GET redirect_uri
?code={code}
&state={random_str}
在OP登录成功后,将code回调给RP
token_endpoint OP RP client_secret_post
client_secret_basic

Code Flow模式:
POST token_endpoint
?grant_type=authorization_code
&code={code}
&redirect_uri={redirect_uri}
&client_id={client_id}
&client_secret={client_secret}

PKCE + Code Flow模式
(删除client_secret参数后 额外添加code_verfier参数)
POST token_endpoint
?grant_type=authorization_code
&code={code}
&redirect_uri={redirect_uri}
&client_id={client_id}
&code_verifier={code_verifier}


客户端凭证模式:
POST token_endpoint
?grant_type=client_credentials
&client_id={client_id}
&client_secret={client_secret}
&scope=user roles(空格分隔的scope列表)

Refresh Token模式:
POST token_endpoint
?grant_type=refresh_token
&client_id={client_id}
&client_secret={client_secret}
&refresh_token={refresh_token}
注:在PKCE模式下、客户端凭证模式下不支持刷新token流程

通过code获取access_token、id_token,

根据refresh_token获取新的access_token
userinfo_endpoint OP RP Bearer {access_token} GET userinfo_endpoint 根据acces_token获取用户信息
revocation_endpoint OP RP client_secret_post
client_secret_basic
POST revocation_endpoint
?token={your_token}
&token_type_hint={}
&token_type_hint=access_token
撤销token、access_token,
若撤销refresh_token,则此refresh_token关联的access_token也会被撤销
introspection_endpoint OP Resource Server client_secret_post
client_secret_basic
POST introspection_endpoint
?token={your_token}
用于验证access_token是否有效,
通过返回结果中的active进行标识
end_session_endpoint OP RP GET end_session_point
?id_token_hint={id_token_issued_to_client}
&post_logout_redirect_uri={post_logout_redirect_uri}
&state={random_str}
结束浏览器中OP的session会话,
并触发后续的多RP的Front-Channel或Back-Channel登出,
最后可配合post_logout_redirect_uri 重定向回RP页面
post_logout_redirect_uri RP OP post_logout_redirect_uri を取得する OP が正常にログアウトすると、RP ページにリダイレクトされる
か、RP ログイン インターフェイス、ログアウト ステータス表示ページなどに対応します。
check_session_iframe OP RP なし RP iframe.src=check_session_iframe セッション管理、現在の RP のログイン ステータスを確認します。
Frontchannel_logout_uri      RP iframe がオンの場合   なし    GET fontchannel_logout_uri
?iss={issureId}
&sid={idToken.sid}  
RP フロントエンドによって実装されたログアウト処理ページは、
OP フロント チャネル モードで返される Html iframe によって呼び出されます。
backchannel_logout_uri       RP  OP なし

役職

backchannel_logout_uri
?logout_token={idToken のような logout_token}

RP バックエンドによって実装されるバックエンド ログアウト インターフェイス。RP
バックエンドは、logout_token を検証し、logout_token に基づいてバックエンドの対応するセッション情報を検索してクリアする必要があります。

おすすめ

転載: blog.csdn.net/gnwu1111/article/details/132163787