-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ASPNETIdentityExternalLogin
- 戻る(ASP.NET Identity)
- ASP.NET Identityの外部ログイン
- ASP.NET Core Identity
- ASP.NET IdentityによるSTS実装
外部ログイン・プロバイダを使用して外部ログインを簡単に実装できるが、
(プロトコルを理解してライブラリを自作するより数段楽ではあるものの)
実際は、そんなに簡単ではなかったりする。
外部ログイン・プロバイダとして使用可能な
クレームベース認証のプロトコルには、
以下のようなものがある。
| プロトコル | 状況 |
|---|---|
| OAuth | 現時点では、OAuth(正確には、OAuth 2.0)が主流である模様。OAuth 自体は認可プロトコルなので、外部ログインは拡張仕様である。 |
| OpenID Connect | その他、OpenID Connect に対応したライブラリも拡充しつつある。 |
| OpenID |
Microsoft.Owin.Security.Google では、過去に OpenID を使用していた。 |
| WS-Federation, SAML | WIF(Windows Identity Foundation)によってサポート可能と思われる。 |
補足(最新化): この記述の時点から状況は整理され、
現在の外部ログインは実質すべて OpenID Connect である。
プロバイダ 現在 OIDC( accounts.google.comの Discovery あり)Microsoft アカウント / Entra ID OIDC Apple(Sign in with Apple) OIDC 独自寄りの OAuth 2.0(Graph API) X(旧 Twitter) OAuth 2.0(PKCE 必須。1.0a から移行済み) OpenID Authentication 2.0(無印 OpenID)は 2014 年に廃止され、
現存しない。なお「OAuth 自体は認可プロトコルなので、外部ログインは拡張仕様」
という指摘は極めて重要である。
アクセス トークンを受け取れたことは、認証の証明にならない
(トークンは他所で盗んだものかもしれない)。
だからこそ OpenID Connect の ID トークンが
必要になった、という経緯である。
-
Owin.Security名前空間では、主要 IdP の STS に対応したライブラリが提供されている。 - プロトコルは不問で、プロトコル・レベルの変更などもある模様。
※Microsoft.Owin.Security.Googleでは、過去に OpenID から OAuth 2.0 への
変更などがあった模様。
-
ライブラリ
- NuGet Gallery | Microsoft.Owin.Security.MicrosoftAccount
https://www.nuget.org/packages/Microsoft.Owin.Security.MicrosoftAccount/- Microsoft は「support the Microsoft Account authentication workflow」と
プロトコルを明言していない。 - 2019 年、久々試したら、
AADSTS70011:でwl.basic,wl.emailsが
discon の旨。この scope 外せば取り敢えず動作した。
- Microsoft は「support the Microsoft Account authentication workflow」と
- NuGet Gallery | Microsoft.Owin.Security.MicrosoftAccount
-
設定
- ASP.NET Identity を使って Microsoft アカウントで認証する
http://kendik.hatenablog.com/entry/2014/08/25/020152
- ASP.NET Identity を使って Microsoft アカウントで認証する
補足:
wl.*は旧 Live Connect のスコープで、
Microsoft Graph(openid profile email User.Read)に置き換わった。
現在は **Microsoft ID プラットフォーム(v2.0 エンドポイント)**を使う。
-
ライブラリ
- NuGet Gallery | Microsoft.Owin.Security.Google
https://www.nuget.org/packages/Microsoft.Owin.Security.Google/- 今の所、OAuth 2.0 を使用しているもよう。
- と思いきや、NuGet のサイトの表示がメンテナンスされていないだけっぽい。
- この辺を見ると、現在は、OIDC を使用しているらしい。
- NuGet Gallery | Microsoft.Owin.Security.Google
-
設定
-
ASP.NET MVC 5 で OAuth 2.0 を使用して Google 認証を行う方法: ある SE のつぶやき
http://fnya.cocolog-nifty.com/blog/2014/03/aspnet-mvc-5-oa.html -
Google の OAuth2.0 を使ってプロフィールを取得【PHP】 - FaMirror Project
http://famirror.hateblo.jp/entry/2015/12/18/180000 -
サマリ
- Google Cloud Console にプロジェクトを作成する。
- 認証情報タブ ---> OAuth クライアント ID を作成する。
- 認証情報タブ ---> OAuth 同意画面を入力して保存する。
(注:redirect_uriの末尾は、使用するライブラリによって異なる。) - ライブラリ・タブ → API を有効にする。
-
移行メモ(最新化): 手順中の
- 「Google Developers Console」→ 現在は Google Cloud Console
- 「Google+ API を有効にする」→ Google+ API は 2019 年に廃止。
現在は有効化不要(プロフィール取得は OIDC のuserinfoで行う)である。
-
ライブラリ
-
NuGet Gallery | Microsoft.Owin.Security.Facebook
https://www.nuget.org/packages/Microsoft.Owin.Security.Facebook/今の所、OAuth 2.0 を使用しているもよう。
-
-
変更
- ASP.NET MVC5 OWIN Facebook authentication suddenly not working - Stack Overflow
http://stackoverflow.com/questions/22364442/asp-net-mvc5-owin-facebook-authentication-suddenly-not-working- [Announcement] Facebook 3.0.1 and lower no longer work · Issue #38 · aspnet/AspNetKatana
https://github.com/aspnet/AspNetKatana/issues/38
- [Announcement] Facebook 3.0.1 and lower no longer work · Issue #38 · aspnet/AspNetKatana
- ASP.NET MVC5 OWIN Facebook authentication suddenly not working - Stack Overflow
- ライブラリ
- NuGet Gallery | Microsoft.Owin.Security.Twitter
https://www.nuget.org/packages/Microsoft.Owin.Security.Twitter/- NuGet 上の説明では、OAuth 2.0 を使用しているもよう。
- しかし、コチラの情報では、OAuth 1.0a らしいが…?
HTTP をサポートしないのも、OAuth 1.0a だから。と考えると辻褄が合うのだが。
- NuGet Gallery | Microsoft.Owin.Security.Twitter
補足(この疑問への答え): OAuth 1.0a が正しい。
Microsoft.Owin.Security.Twitterは OAuth 1.0a を実装している
(リクエスト トークン → 認可 → アクセス トークンの 3-legged)。OAuth 1.0a はメッセージ自体に署名する方式のため、
署名の対象に URL(スキームを含む)が入る。
HTTPS 前提の実装になっているのはこのためである
(OAuth 2.0 は署名をやめ、TLS に依存する設計に変えた)。なお X(旧 Twitter)は現在 OAuth 2.0 + PKCE に移行しており、
上記ライブラリは実質使えない。
- 設定
- ASP.NET MVC 5 で Twitter 認証を行う方法: ある SE のつぶやき
http://fnya.cocolog-nifty.com/blog/2014/03/aspnet-mvc-5-tw.html
- ASP.NET MVC 5 で Twitter 認証を行う方法: ある SE のつぶやき
- 最近、Sign in with Apple(
DNET_SignInWithApple.md)がリリースされたが、
NuGet 上にライブラリは、まだ確認できない。 - iOS 上での Native SDK が本丸なので、
Web から外部ログインするための IdP としては、あまり使用されないかも。
補足(最新化): 現在は
AspNet.Security.OAuth.Apple(aspnet-contrib)が広く使われている。
また、Apple はアプリ ストアの規約により
「他の外部ログインを提供するなら Sign in with Apple も提供せよ」
と求めているため、B2C では実質必須になっている。実装上の癖として、
- クライアント シークレットが JWT(ES256 署名、最長 6 か月)
であり、定期的な再生成が要る- 氏名・メールは初回認可時にしか返らない(2 回目以降は空)ので
その場で保存しなければならない- メール非公開を選ばれると
@privaterelay.appleid.comの
中継アドレスになるがある。
OAuth用ライブラリ
Microsoft.Web.WebPages.OAuth.OAuthWebSecurity クラスには、
各サービスに応じて、アカウント認証を行うためのメソッドが用意されている。
| 項番 | メソッド | 処理内容 |
|---|---|---|
| 1 | RegisterFacebookClient |
Facebook アカウントによる認証 |
| 2 | RegisterGoogleClient |
Google アカウントによる認証 |
| 3 | RegisterLinkedInClient |
LinkedIn アカウントによる認証 |
| 4 | RegisterMicrosoftClient |
Microsoft アカウントによる認証 |
| 5 | RegisterTwitterClient |
Twitter アカウントによる認証 |
| 6 | RegisterYahooClient |
Yahoo アカウントによる認証 |
- Using OAuth Providers with MVC 4 | The ASP.NET Site
https://www.asp.net/mvc/overview/older-versions/using-oauth-providers-with-mvc
補足: これは MVC 4 時代の
DotNetOpenAuthベースの仕組みで、
現在は使用しない(DotNetOpenAuth自体が開発終了)。
OpenID Connect用ライブラリ
Microsoft.Owin.Security.OpenIdConnect では、
Microsoft Entra ID(Azure Active Directory)との、
OpenID Connect を使用した認証連携がサポートされている模様。
-
OWIN security components in ASP.NET: OpenID Connect! | .NET Web Development and Tools Blog
https://blogs.msdn.microsoft.com/webdev/2014/03/28/owin-security-components-in-asp-net-openid-connect/ -
IdM実験室
- [AAD/ASP.NET] OpenID Connect を使って AAD でログオンする
http://idmlab.eidentity.jp/2014/05/aadaspnet-openid-connectaad.html - (続)
response_mode=fragment編
http://idmlab.eidentity.jp/2014/05/aadaspnet-openid-connectaadresponsemode.html
- [AAD/ASP.NET] OpenID Connect を使って AAD でログオンする
Google へのログインは現時点(2016 年)ではサポートされていない模様。
- asp.net - OpenIdConnect Owin login with google - Stack Overflow
http://stackoverflow.com/questions/25423898/openidconnect-owin-login-with-google
補足(最新化): 現在は
Microsoft.AspNetCore.Authentication.OpenIdConnect
のAddOpenIdConnect()で、Google を含む
Discovery(/.well-known/openid-configuration)に対応した
任意の OP と連携できる。プロバイダ別のライブラリは基本的に不要になった。.AddOpenIdConnect("google", o => { o.Authority = "https://accounts.google.com"; o.ClientId = "..."; o.ClientSecret = "..."; o.ResponseType = "code"; // ← Implicit は使わない o.UsePkce = true; // 既定 true o.Scope.Add("email"); o.SaveTokens = true; });
WS-Federation, SAML用ライブラリ
WIFの名前空間は、Microsoft.IdentityModel.Claims と、
OWIN ミドルウェア(Microsoft.Owin)と異なるため、
ASP.NET Identityとの連携具合が不明(多分連携していない)。
- 方法: WIF を使用してクレーム対応 ASP.NET MVC Web アプリケーションをビルドする
https://msdn.microsoft.com/ja-jp/library/hh291061.aspx
補足(最新化): ASP.NET Core には
Microsoft.AspNetCore.Authentication.WsFederationがあり、
AD FS との連携が標準でできる。
SAML は標準では提供されず、
Sustainsys.Saml2などのサードパーティを使う
(SAMLを実装する。を参照)。
ASP.NET Core の情報は以下に纏まっている。
https://learn.microsoft.com/aspnet/core/security/authentication/social/
- Google / Facebook / Microsoft / Twitter
※ こちらも、Owin.Security 同様に、MS 製(Microsoft.AspNetCore.Authentication)。
- 連載:Microsoft技術におけるアイデンティティ連携開発のいま - Build Insider
http://www.buildinsider.net/web/msidentitydev- .NET で使えるアイデンティティ連携のためのライブラリまとめ(前・後編)
- カスタム・アプリケーションによる認証フローとプログラミング
以下の手順に従い、実装できる。
- Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#) | The ASP.NET Site
https://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on
外部ログインは、
HttpUnauthorizedResult
の ActionResult を返すことで開始する。通常、redirect_uri は指定しない。
-
Microsoft アカウントでは、localhost も登録できるようになっている。
しかし、Twitter では localhost が登録できないことを確認した。 -
従って、localhost を使用できないログイン・プロバイダを使用する場合、
URL, hosts,applicationhost.configの設定が必要になる。- IIS Express で仮想サイトに複数のホスト名を割り当てる - しばやん雑記
http://blog.shibayan.jp/entry/20130306/1362572283 - なお、
applicationhost.configの位置が、VS2015 から変わっているので注意が必要。- IIS Express で localhost 以外のアドレスでアクセスする方法 - なか日記
http://blog.nakajix.jp/entry/2014/09/19/022536
- IIS Express で localhost 以外のアドレスでアクセスする方法 - なか日記
- IIS Express で仮想サイトに複数のホスト名を割り当てる - しばやん雑記
-
企業プロキシ環境下で外部サービスに接続
プロキシ環境下で外部サービスに接続する場合、以下の実装・設定を行う必要がある。- ASP.NET Identity - プロキシ環境下で外部サービスによるユーザ認証を行う
http://ichiroku11.hatenablog.jp/entry/2014/04/09/224050 - この設定を行うと、下記の「Client の Web アプリ」からの Web アクセスは、
企業プロキシ経由でインターネットにルーティングされるようになる。
- ASP.NET Identity - プロキシ環境下で外部サービスによるユーザ認証を行う
-
企業プロキシのフィルタリング
-
どこから、どこに、アクセスしようとしているかを確認する必要がある。
OAuthに詳しくなると、以下にアクセスしていることが解るようになる。- User Agent から Client の Web アプリ(自分の開発中の Web アプリ)
- User Agent から Authorization Server の Web アプリ(サービス側の Web アプリ)
- Client の Web アプリから Authorization Server の Web アプリ
- Client の Web アプリから Resource Server の WebAPI
- User Agent から Resource Server の WebAPI
-
例えば、Google アカウントでは、下記をフィルタ解除しているだけでは
認証がうまく通らなかった。
(恐らく仲介コードを使用し、Access Token や Claim を取得
するための各エンドポイントの URL が異なるのだと思われる。)https://www.google.com/
-
従って、切り分けのために、企業プロキシの外からテストすることも重要になる。
-
補足(Google で許可すべきホスト): 上の推測は正しい。
OIDC ではブラウザが行く先とサーバが行く先が異なる。
経路 ホスト ブラウザ(認可) accounts.google.comサーバ(トークン取得) oauth2.googleapis.comサーバ(Discovery / JWKS) accounts.google.com,www.googleapis.comサーバ(ユーザ情報) openidconnect.googleapis.comブラウザ側だけを許可しても、
サーバ→ Google のトークン交換で止まる。
これが「認証がうまく通らない」の正体である。
.well-known/openid-configurationを実際に取得して、
出てくる URL のホストを許可リストに入れるのが確実である。
サービス側の
- 仕様が不明確なことや、
- 仕様の変更が多いところがあり、
トラブる事が多い。
プロトコルも不定で、例えば OAuth 2.0 の場合、
詳しい仕様は記載されていないので
必要に応じて分析が必要になる(OAuthによる外部ログイン(認証)の研究(MS_OAuthExternalLoginResearch.md))。
以下のように、インターフェイスの変更が多数あったことが報告されている。
- Using Google and LinkedIn Accounts for Your .net MVC 5 Site's Authentication
https://riccardo-moschetti.org/2014/08/25/using-google-accounts-for-your-net-mvc-5-sites-authentication-tips-and-tricks-and-the-error-externallogincallbackerroraccess_denied/
また、過去 Google の OpenID の外部ログイン・プロバイダが存在しており、
最近 OAuth に置き換えられたことを考えると、
将来的には、OAuth が、OpenID Connect に置き換えられる。
などと言った可能性はある。
補足: この予測はその通りになった。
現在、主要プロバイダの外部ログインはすべて OIDC である。
Discovery に対応した汎用の OIDC ミドルウェアを使っておけば、
プロバイダ側の変更に追従しやすい。
- ASP.NET MVC 5 で OpenID を使用して Google 認証を行う方法: ある SE のつぶやき
http://fnya.cocolog-nifty.com/blog/2014/03/aspnet-mvc-5-op.html- サイトにパスワードを保存する必要なし ― Microsoft、Google等が
ユーザー認証の新規格、OpenID Connect をサポート | TechCrunch Japan
http://jp.techcrunch.com/2014/02/27/20140226openid-foundation-launches-openid-connect-identity-protocol-with-support-from-google-microsoft-others/
- サイトにパスワードを保存する必要なし ― Microsoft、Google等が
ほぼ、AccountController.ExternalLoginCallback 周辺で完結する。
-
外部ログインをしても、既定で E-mail アドレスは取得できないので
プロジェクト・テンプレートも、既定で E-mail アドレスを自分で手入力する
という仕様で実装されている。 -
これでは、あまり外部ログインの意味が無いので(E-mail アドレスの再入力が必要)、
検証済みの E-mail アドレスを取得できるように、
連携先に、E-mail アドレスを要求するように設定する。- c# - Get E-mail of User Authenticated with Microsoft Account in ASP.NET Identity - Stack Overflow
http://stackoverflow.com/questions/22229593/get-e-mail-of-user-authenticated-with-microsoft-account-in-asp-net-identity - twitter の oauth を使ってみる(email も取得) - Qiita
http://qiita.com/kite_999/items/e0ab8c52f918bbb02cfd
- c# - Get E-mail of User Authenticated with Microsoft Account in ASP.NET Identity - Stack Overflow
-
これにより、連携先から、検証済みの E-mail アドレスを取得できるようになるため、
この E-mail アドレスを使用して、ユーザ登録し、外部ログインを追加すれば整合性が取れる。 -
しかし、この状態で、E-mail Confirmation を実装していると矛盾が生じる。
補足(メールをキーにしてはならない): 「連携先から取得した
検証済みメールでユーザを紐づける」という設計には重大な落とし穴がある。
OIDC のemail_verifiedクレームを必ず確認すること。
false(または欠落)のメールで既存アカウントに紐づけると、
攻撃者が任意のメールを名乗って他人のアカウントを乗っ取れる。- メールは変わる。姓の変更・ドメイン移行で別人になる。
正しくは、
iss+sub(プロバイダ + 不変のユーザ ID)の組を
外部ログインのキーにする(AspNetUserLoginsテーブルの
LoginProvider+ProviderKeyがまさにこれ)。
メールは表示・照合の補助に留める。
既定では Claim の保存処理は実装されていないので自分で実装する必要がある。
await UserManager.AddClaimAsync(user.Id, claim);- 参考
- ASP.NET Identity : External Login カスタマイズ (claim, scope, access token などの活用) – Tsmatz
https://blogs.msdn.microsoft.com/tsmatsuz/2014/06/15/asp-net-identity-external-login-claim-scope-access-token/
- ASP.NET Identity : External Login カスタマイズ (claim, scope, access token などの活用) – Tsmatz
-
ExternalLoginCallbackの条件分岐で、外部ログインが有る時・無い時で動きが違う。- 外部ログインは、アカウントに追加される。
- アカウントが作成されていない場合は、
- サインアップ(アカウントの作成)から行なう。
- その後、アカウントに外部ログインを追加してサインインする。
- アカウントが作成されてる場合は、外部ログインをチェックする。
- 外部ログインが存在しない場合は、外部ログインを追加してサインインする。
- 外部ログインが存在する場合は、外部ログインを追加しないでサインインする。
-
別のログイン手段を持たない場合は、外部ログインを削除できない仕様である模様(確認済)。
- 最初にサインアップしてあれば、外部ログインを削除できる。
- 2 つ以上の外部ログインがあれば、外部ログインを削除できる。
- 最初に外部ログインした場合、サインアップできなくなる問題がある。
- この場合、ローカル・サインインできなくなる。
- パスワード・リセットすれば、ローカル・サインインできるようになる。
- これでローカル・サインインができるようになれば、外部ログインを削除できる。
補足(この仕様は正しい): 「最後のログイン手段は削除させない」
という挙動は意図的な安全策である。
削除できてしまうと、ユーザは自分のアカウントに
二度とアクセスできなくなる(= 実質的なアカウント消失)。同じ理由で、2FA を有効にしたら回復コードを必ず提示する、
パスキーのみのアカウントには代替手段を残す、といった
「締め出し(lockout)」への配慮が要る。
アカウント回復の設計は、認証設計と同じだけ重要である。
外部ログインが失敗することがあるらしい。
- ASP.NET Identity の SNS 対応ではまったポイント | 眠るシーラカンスと水底のプログラマー
http://coelacanth.jp.net/ - asp.net mvc - MVC 5 Owin Facebook Auth results in Null Reference Exception - Stack Overflow
http://stackoverflow.com/questions/19564479/mvc-5-owin-facebook-auth-results-in-null-reference-exception
補足(現在の定番の原因): 外部ログインの「よく分からない失敗」は、
現在ではほぼ次のいずれかである。
症状 原因 コールバックで Correlation failed.相関 Cookie が届いていない。 SameSite=None; Secureが必要(IdP から POST で戻る場合)ローカルで動くが本番で失敗 リバース プロキシ配下でスキームが httpになる。UseForwardedHeadersが要るredirect_uri_mismatch上と同じ理由で redirect_uriがhttp://で組み立てられている断続的に失敗 Data Protection の鍵が共有されていない(状態の暗号化・復号に失敗) 特に 1 番目と 2 番目は、ロードバランサ / コンテナ導入時に必ず踏む。
- ASP.NET Identity : External Login カスタマイズ (claim, scope, access token などの活用)
https://blogs.msdn.microsoft.com/tsmatsuz/2014/06/15/asp-net-identity-external-login-claim-scope-access-token/
Tags: 移行, .NET開発, ASP.NET, ASP.NET MVC, ASP.NET Identity, OAuth, 認証基盤, セキュリティ
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。