-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ASPNETIdentitySTSOAuth2
- 戻る(ASP.NET IdentityによるSTS実装)
- ASP.NET IdentityのOAuth2によるSTS実装
- ASP.NET IdentityのOAuth2拡張によるSTS実装
- ASP.NET IdentityのOIDCによるSTS実装
ASP.NET Identityの、OAuth 2.0 による
セキュアトークンサービス(STS)の Endpoint 追加実装。
OAuth 2.0 Server、Client 共に以下からダウンロード可能。
- The ASP.NET Site - OWIN OAuth 2.0 Authorization Server - Download the sample code.
このサンプルは、VS2013・2015 で、そのまま F5 実行可能で非常に便利。
ダウンロードしたサンプルを使用して、以下のシナリオの検証ができる。
- Authorization Code グラント種別(OAuth)
- Implicit グラント種別
- Resource Owner Password Credentials グラント種別
- Client Credentials グラント種別
補足(最新化): Implicit / ROPC は
現在使用してはならない(ASP.NET IdentityによるSTS実装を参照)。
学習目的でサンプルを動かす分には有用だが、
本番実装のテンプレートにしてはならない。
-
認証には、(基本的に)ASP.NET Identityを使用する。
-
Bearer Token の発行には、
ClaimsIdentityを使用する。 -
ASP.NET MVC アプリケーションの認可エンドポイント上
-
Cookie 認証チケットから
ClaimsIdentityを生成できる。AuthenticateResult ticket = this.AuthenticationManager .AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie).Result; ClaimsIdentity identity = (ticket != null) ? ticket.Identity : null;
-
以下の方法で Token を発行する。
「Authorization Code グラント種別」では仲介トークンを、
「Implicit グラント種別」では Access Token を生成する。this.AuthenticationManager.SignIn(identity);
-
-
OAuthAuthorizationServerProviderの Token エンドポイント上-
ユーザ情報を使用して
ClaimsIdentityを生成する。ClaimsIdentity identity = await userManager.CreateIdentityAsync( user, DefaultAuthenticationTypes.ExternalBearer);
-
以下の方法で Token を発行する。
「Resource Owner Password Credentials グラント種別」
「Client Credentials グラント種別」の両方で Access Token を生成する。context.Validated(identity);
-
-
ClaimsIdentityに Custom の情報を格納する場合、以下の様に Claim を追加する。identity.AddClaim(new Claim("urn:oauth:scope", scope));
補足(ここが「RFC に無い」ことの意味): OAuth 2.0 の
RFC 6749 は「トークンをどう作るか」を規定していない。
規定しているのは
- エンドポイントの URL 構造とパラメタ名
- グラント種別ごとのやり取りの流れ
- エラー応答の形式
だけであり、アクセス トークンの中身は不透明(opaque)でよい。
したがって「認証をどうやるか」「トークンに何を詰めるか」は
各実装の裁量になる。上記のClaimsIdentityを使う仕掛けは、
Katana(OWIN)実装のローカル ルールである。逆に言えば、この部分は移植性が無い。
OpenIddict や IdentityServer に移ると、まったく別の書き方になる。
「技術文書中での Shall / Should / May」があるため、
サービス / ミドルウェア毎に仕様は異なってくる。以下が参考になる。
- OAuth2.0 対応サービスの state, redirect_uri パラメータの扱い色々 - BangBlog
http://bang.hateblo.jp/entry/2012/10/09/002003
やはり、サービスによって扱いがマチマチなのは、
redirect_uri パラメタと state パラメタであるもよう。
補足(現在は締められた): この「マチマチ」は
セキュリティ上の問題を多発させたため、
RFC 9700(OAuth 2.0 Security BCP)と OAuth 2.1 で規定が厳格化された。
パラメタ 現在の規定 redirect_uri完全一致(simple string comparison)が必須。ワイルドカード・前方一致・パス以下の可変は不可 stateCSRF 対策として必須扱い(PKCE を使う場合は stateの役割は遷移先の保持に寄る)PKCE全クライアントで必須(機密クライアントも含む)
redirect_uriの部分一致を許すと、
- オープン リダイレクタと組み合わせて認可コードを奪える
- サブドメイン乗っ取りで奪える
という攻撃が成立する。必ず完全一致にすること。
-
認可サーバ(Authorization Server)とリソースサーバ(Resource Server)が
同じマシン上に無い場合、
Bearer Token を暗号化・復号化する秘密鍵を双方のマシン間で一致させる必要がある。 -
これには、以下のように、
machineKeyを両方のWeb.configファイルに
追加する必要がある。
<system.web>
<machineKey decryptionKey="Enter decryption Key here"
validation="SHA1"
validationKey="Enter validation Key here" />
</system.web>machineKey セクションの生成には、以下のツールが使えそう。
- インストール時に MachineKey を自動生成する NuGet パッケージを作った - しばやん雑記
http://blog.shibayan.jp/entry/20150703/1435897073- NuGet Gallery | MachineKeyGenerator
https://www.nuget.org/packages/MachineKeyGenerator/ - garafu/MachineKeyGenerator
https://github.com/garafu/MachineKeyGenerator
- NuGet Gallery | MachineKeyGenerator
補足(この設計の限界): 「共通鍵でトークンを暗号化し、
リソース サーバが復号して中身を読む」という方式には、
次の制約がある。
- リソース サーバに復号鍵を配る=トークンを偽造できる鍵を配る
(リソース サーバが 1 つでも侵害されると全体が破れる)- リソース サーバが増えるたびに鍵の配布・更新が要る
validation="SHA1"は現在の基準では弱い(HMACSHA256以上にする)現在の設計では、トークンは JWS(公開鍵署名)にし、
リソース サーバはjwks_uriから公開鍵を取って検証する
のが標準である。復号鍵を配る必要がなくなる。あるいはトークンを不透明なままにし、
**トークン イントロスペクション(RFC 7662)**で
認可サーバに毎回問い合わせる方式もある。
JWTとOAuth2.0を参照。
- OAuthAuthorizationServerProvider クラス (Microsoft.Owin.Security.OAuth)
https://learn.microsoft.com/dotnet/api/microsoft.owin.security.oauth.oauthauthorizationserverprovider
- OWIN OAuth 2.0 Authorization Server
https://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server
このコンテンツは以下の様な構成になっている。
- Download the sample code.
- Create an Authorization Server.
- Creating a Resource Server.
- Create OAuth 2.0 Clients.
以下から、サンプル・コードをダウンロードできる。
-
この Authorization Server は OAuth の 4 つのフローをサポートしている。
- Authorization Code Grant Client
- Implicit Grant Client
- Resource Owner Password Credentials Grant Client
- Client Credentials Grant Client
-
サーバーの設定と実装
- OWIN Startup class での設定
-
OAuthAuthorizationServerProviderの実装
| メソッド | 対象グラント種別 |
|---|---|
ValidateClientRedirectUri |
Authorization Code, Implicit |
ValidateClientAuthentication |
Resource Owner Password Credentials, Client Credentials |
GrantResourceOwnerCredentials |
Resource Owner Password Credentials |
GrantClientCredentials |
Client Credentials |
-
AuthorizeEndpointの実装(Authorization Code, Implicit グラント種別)
移行メモ: 元ページは
GrantClientCredetailsと綴られていたが、
正しいメソッド名はGrantClientCredentialsである。
アクセストークンによって保護された Resource Server の Endpoint を作成。
.NET クライアント・アプリから HTTP アクセスする際のライブラリとしては、
DotNetOpenAuth.OAuth2
を使用している。
| クライアント | 実装形態 |
|---|---|
| Authorization Code Grant Client | WebApplication として実装 |
| Implicit Grant Client | JavaScript で実装 |
| Resource Owner Password Credentials Grant Client | コンソール・アプリケーションで実装 |
| Client Credentials Grant Client | コンソール・アプリケーションで実装 |
補足:
DotNetOpenAuthは開発終了している。
現在の .NET クライアント実装は
Microsoft.Identity.Client(MSAL) — Entra ID / MSA 向けIdentityModel(Duende) — 汎用の OAuth / OIDC クライアントMicrosoft.AspNetCore.Authentication.OpenIdConnect— Web アプリを使う。
-
The ASP.NET Forums
- OWIN and Authorization Code Grant Flow - Always Bad Request (Invalid Grant)
https://forums.asp.net/t/1975505.aspx
- OWIN and Authorization Code Grant Flow - Always Bad Request (Invalid Grant)
-
Stack Overflow
- MVC 5 application - implement OAuth Authorization code flow
http://stackoverflow.com/questions/25845420/mvc-5-application-implement-oauth-authorization-code-flow - asp.net - Authorization_code grant flow on Owin.Security.OAuth: returns invalid_grant
http://stackoverflow.com/questions/24515211/authorization-code-grant-flow-on-owin-security-oauth-returns-invalid-grant
- MVC 5 application - implement OAuth Authorization code flow
補足(
invalid_grantの定番原因): この 2 つの質問が示す通り、
Authorization Code フローでinvalid_grantになる原因は限られている。
原因 内容 認可コードの二重使用 コードは一度きり。ブラウザの再読込やリトライで再送すると失敗する redirect_uriの不一致認可時とトークン要求時で完全に同じ文字列である必要がある(末尾スラッシュ、大文字小文字も) コードの有効期限切れ 通常 30 秒〜数分 クライアント認証の失敗 client_secretの不一致、送信方法(Basic / body)の相違machineKeyの不一致認可コード自体が暗号化されており、復号できない
実装方法の調査で参照にしたサイト。
- ASP.NET WebAPI2 で Ajax で OAuth 認証するよ(ついでに TypeScript と React)- かずきのBlog@hatena
http://blog.okazuki.jp/entry/2016/01/15/215901 - ASP.NET SPA (JavaScript) の Web API 認証 (ASP.NET Identity) – Tsmatz
https://blogs.msdn.microsoft.com/tsmatsuz/2014/05/20/asp-net-spa-javascript-web-api-asp-net-identity-html5biz/ - asp.net - How do you consume extra parameters in OAuth2 Token request within .net WebApi2 application - Stack Overflow
http://stackoverflow.com/questions/21243996/how-do-you-consume-extra-parameters-in-oauth2-token-request-within-net-webapi2 - c# - Can't get UserManager from OwinContext in apicontroller - Stack Overflow
http://stackoverflow.com/questions/24001245/cant-get-usermanager-from-owincontext-in-apicontroller - Simple OAuth Server: Implementing a Simple OAuth Server with Katana OAuth Authorization Server Components (Part 1) - Tugberk Ugurlu's Blog
http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part-1
Tags: 移行, .NET開発, ASP.NET, ASP.NET MVC, ASP.NET Identity, OAuth, 認証基盤, セキュリティ
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。