OWIN Identityで複数のAPIクライアントからWeb API 2の外部ログインを登録する
質問事項
次のようなアーキテクチャが欲しいのですが(この例では製品名を作りました)。
1台のサーバで動作するWeb API 2アプリケーション http://api.prettypictures.com
MVC 5 クライアントアプリが別のサーバーで動作している http://www.webpics.com
私は www.webpics.com クライアントアプリでPretty Pictures APIを使用することができます。
- ユーザー名とパスワードによる新規アカウント登録
- Facebook/Google/Twitter/Microsoft の新規アカウント登録
- ログイン
- 画像の取得
FacebookやGoogleなどの外部アカウントを登録する以外は、すべて動作します。
を作成するための正しいフローがわかりません。 外部 アカウントを作成する正しいフローがわかりません。
認証の流れについて公開されているほとんどのドキュメントを調べましたが、こんな感じです。
OWINの新しいIdentityモデルについて、できる限りのことを読みました。
私は Visual Studio 2013 で SPA テンプレートを調べました。私が必要とすることのほとんどを行う方法を示していますが、クライアントと API が同じホスト上にある場合のみです。複数のクライアントが私の API にアクセスし、Google などを通じてユーザーがサインアップできるようにしたい場合、うまくいかず、私が知る限り、OWIN 認証フローが壊れています。
ここまでの流れはこんな感じです。
- ユーザーは www.webpics.com/Login
- www.webpics.com コール api.prettypictures.com/Account/ExternalLogins (このとき returnUrl でのコールバックに戻るように設定されています。 www.webpics.com にあるコールバックに戻るように設定されています) そして、結果として得られるリンクをユーザーに表示します。
- ユーザーは "Google"をクリックします。
- ブラウザは api.prettypictures.com/Account/ExternalLoginにリダイレクトされます。 をプロバイダ名などで指定します。
- API の ExternalLogin アクションは google.com
- ブラウザがリダイレクトされる先は google.com
- ユーザはユーザ名とパスワードを入力します (まだ google.com )
- グーグルドットコム は、現在、セキュリティクリアランスを提示しています。 "api.prettypictures.com" は、あなたの電子メールアドレス、名前、妻、子供などへのアクセスを希望しています。これはOKですか?
- ユーザーは "Yep"をクリックし、次のページに移動します。 api.prettypictures.com/Account/ExternalLoginに戻されます。 をクリックすると、Googleが設定したCookieで
ここで私は行き詰ってしまいました。次に起こるはずのことは、何らかの方法でクライアントアプリに、ユーザーが google.com での認証に成功し、後でアクセストークンと交換するための1回限りのアクセスコードが渡されることです。クライアントアプリは、必要であれば、ユーザーがgoogle.comと関連付けるユーザー名を入力する機会を持つべきです。 google.com ログインに関連付けるユーザー名を入力する必要があります。
どうすればスムーズにできるのかわかりません。
実際この時点では、ブラウザは結局 api.prettypictures.com/Account/ExternalLoginに座っています。 エンドポイントに座っています。APIはGoogleのためにサインインしていますが、クライアントはそれを処理する方法を知らないのです。そのクッキーをパイプで www.webpics.com ?
SPAアプリでは、AJAXで行われ google.com は URL 断片としてトークンを返し、すべてが 1 つのドメイン上にあるため、うまく機能します。しかし、これは、複数のクライアントが完全に使用できる API を持つことの重要性の多くを無視しています。
助けてください!
どのように解決するのですか?
更新:1月にこの記事を書いたときとは状況が変わっています。 : MSFT は公式の OpenID connect クライアントミドルウェアをリリースし、私は @manfredsteyer とともに、Katana に組み込まれた OAuth2 認証サーバーを OpenID connect に適応させるべく懸命に働きました。この組み合わせにより、カスタムクライアントコードを必要とせず、標準的なOAuth2/OpenID connectクライアントと100%互換性のある、はるかに簡単ではるかに強力なソリューションが実現しました。1月に紹介したさまざまなステップは、今ではたった数行で置き換えることができるのです。
サーバです。
app.UseOpenIdConnectServer(options =>
{
options.TokenEndpointPath = new PathString("/connect/token");
options.SigningCredentials.AddCertificate(certificate);
options.Provider = new CustomOpenIdConnectServerProvider();
});
クライアントです。
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "http://localhost:55985/",
ClientId = "myClient",
ClientSecret = "secret_secret_secret",
RedirectUri = "http://localhost:56854/oidc"
});
すべての詳細(と異なるサンプル)はGitHubのリポジトリで見つけることができます。
https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server
https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/dev/samples/Nancy
ジョシュ、あなたは間違いなく正しい道を歩んでいますし、あなたの
委任/フェデレート認証
の実装はかなり良さそうです(私は、あなたが
Microsoft.Owin.Security.Facebook/Google/Twitter
).
必要なのは、独自のカスタムを作成することです。
OAuth2 認証サーバー
. これを実現するためのオプションはたくさんありますが、最も簡単なのは、おそらく
OAuthAuthorizationServerMiddleware
をOWINスタートアップ・クラスに挿入することです。あなたはそれを
Microsoft.Owin.Security.OAuth
Nuget パッケージにあります。
ベストプラクティスは別のプロジェクト(しばしば "AuthorizationServer" と呼ばれる)を作成することですが、個人的には、複数の API にわたって使用することを意図しない場合、私の "API project" に追加することを好みます(ここでは、 "api.prettypictures.com" をホストするプロジェクトに挿入する必要があるでしょう)。
Katanaリポジトリで素晴らしいサンプルを見つけることができます。
https://katanaproject.codeplex.com/SourceControl/latest#tests/Katana.Sandbox.WebServer/Startup.cs
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AuthorizeEndpointPath = new PathString("/oauth2/authorize"),
TokenEndpointPath = new PathString("/oauth2/token"),
ApplicationCanDisplayErrors = true,
AllowInsecureHttp = true,
Provider = new OAuthAuthorizationServerProvider
{
OnValidateClientRedirectUri = ValidateClientRedirectUri,
OnValidateClientAuthentication = ValidateClientAuthentication,
OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials,
},
AuthorizationCodeProvider = new AuthenticationTokenProvider
{
OnCreate = CreateAuthenticationCode,
OnReceive = ReceiveAuthenticationCode,
},
RefreshTokenProvider = new AuthenticationTokenProvider
{
OnCreate = CreateRefreshToken,
OnReceive = ReceiveRefreshToken,
}
});
シンプルな Razor ファイルを使って、どのように承認同意書が実装されたかを見るために、遠慮なくプロジェクト全体をブラウズしてください。ASP.NET MVC や NancyFX のような上位のフレームワークを好む場合は、独自の
AuthorizationController
コントローラと
Authorize
メソッドを追加し (GET と POST の両方を受け付けるようにしてください)、属性ルーティングを使用して OAuth2 認証サーバーで定義されている AuthorizeEndpointPath に一致させます (例.
[Route("oauth2/authorize")]
を変更したサンプルです。
AuthorizeEndpointPath
を使用するように変更しています。
oauth2/
をパスのベースとして使用します)。
もうひとつ必要なのは、WebアプリにOAuth2認証クライアントを追加することです。残念ながら、Katana には一般的な OAuth2 クライアントのサポートがなく、自分で構築する必要があります。私は個人的にKatanaチームに提案を出しましたが、拒否されました。でも慌てないでください、むしろ簡単にできますよ。
そこにある Microsoft.Owin.Security.Google リポジトリから適切なファイルをコピーします。 https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs
必要なのは
GoogleOAuth2AuthenticationHandler
,
GoogleOAuth2AuthenticationMiddleware
,
GoogleOAuth2AuthenticationOptions
,
GoogleAuthenticationExtensions
(Google OpenIDの実装に対応する最初の2つのメソッドを削除する必要があります)。
IGoogleOAuth2AuthenticationProvider
,
GoogleOAuth2ReturnEndpointContext
,
GoogleOAuth2AuthenticationProvider
,
GoogleOAuth2AuthenticatedContext
と
GoogleOAuth2ApplyRedirectContext
. これらのファイルをホスティングしているプロジェクトに挿入したら、ファイル名を適宜変更し、認証とアクセストークンのエンドポイント URL を
GoogleOAuth2AuthenticationHandler
にある認証とアクセストークンのエンドポイント URL を、OAuth2 認証サーバーで定義したものと同じになるように変更します。
次に、リネームした/カスタムの
GoogleAuthenticationExtensions
をOWINスタートアップ・クラスに追加します。私は
AuthenticationMode.Active
を使用することをお勧めします。そうすれば、ユーザーはあなたの API OAuth2 認証エンドポイントに直接リダイレクトされることになります。したがって、quot;api.prettypictures.com/Account/ExternalLogins" のラウンドトリップを抑え、OAuth2クライアントミドルウェアが401レスポンスを変更してクライアントをあなたのAPIにリダイレクトさせるようにする必要があります。
幸運を祈ります。そして、より多くの情報が必要な場合は、躊躇しないでください;)
関連
-
[解決済み】同じキーのアイテムがすでに追加されています。
-
[解決済み] Kendo UI MVC用パスワードテキストボックス
-
[解決済み] Entity Framework Code Firstを使用して一意制約を設定することは可能ですか?
-
[解決済み] Visual Studioのデバッグ/ロードが非常に遅い
-
[解決済み] コントローラ '...' でパブリックアクションメソッド '...' が見つかりませんでした。
-
[解決済み】OAuth2の「暗黙の」フローはとてもうまく機能しているのに、なぜ「認証コード」フローがあるのですか?
-
[解決済み】OAuth 2の暗黙のグラント承認タイプの目的は何ですか?
-
[解決済み] セキュリティ透過的なメソッド 'WebMatrix.WebData.PreApplicationStartCode.Start()' による試行。
-
[解決済み] 型名または名前空間名 'DbContext' が見つかりませんでした [閉鎖]。
-
[解決済み] ASP.NET_SessionId + OWIN Cookieがブラウザに送信されない。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】VS 2015でコントローラからビューを追加できない : "選択されたコードジェネレータの実行にエラーが発生しました"
-
[解決済み] System.Web.HttpException (0x80004005)。リクエストの最大長を超えました
-
[解決済み] 修正方法: ハンドラ "PageHandlerFactory-Integrated" のモジュールリストに "ManagedPipelineHandler" という不正なモジュールが含まれています。
-
[解決済み] OwinStartupが起動しない
-
[解決済み] 既存のASP.NET MVC 4 WebアプリケーションのプロジェクトにWeb APIを追加するにはどうすればよいですか?
-
[解決済み】ASP.NET MVC 3 razor ViewStart ファイルで異なるレイアウトを指定するには?
-
[解決済み】ASP.NET MVC Html.ValidationSummary(true) でモデルエラーが表示されない。
-
[解決済み】AutoMapper.CreateMapsをどこに配置するか?
-
[解決済み] ASP.Net MVC デフォルトの HTTP ヘッダーを削除する方法は?
-
[解決済み] 型名または名前空間名 'DbContext' が見つかりませんでした [閉鎖]。