Asp.net-Mvc

使用 OWIN 身份從多個 API 客戶端註冊 Web API 2 外部登錄

  • January 16, 2014

我想要以下架構(我已經為這個範例編造了產品名稱):

在一台伺服器上執行的 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 等註冊外部帳戶外,上述所有工作都有效。

我無法制定正確的流程來從 API 的單獨客戶端使用者創建外部帳戶。

我研究了身份驗證流程中可用的大多數文件,如下所示: 在此處輸入圖像描述

我已經閱讀了幾乎所有關於 OWIN 中新身份模型的內容。

我已經檢查了 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
  • google.com現在提供安全許可:“api.prettypictures.com”想訪問您的電子郵件地址、姓名、妻子、孩子等。可以嗎?
  • 使用者點擊“是”並返回api.prettypictures.com/Account/ExternalLogin並使用 Google 設置的 cookie。

這就是我卡住的地方。接下來應該發生的事情是以某種方式通知客戶端應用程序,使用者已成功通過google.com進行身份驗證,並獲得一次性訪問程式碼,以便稍後交換訪問令牌。如有必要,客戶端應用程序應有機會提示使用者輸入使用者名以與他們的google.com登錄相關聯。

我不知道如何促進這一點。

事實上,此時瀏覽器在Google 回調後最終位於api.prettypictures.com/Account/ExternalLogin端點。API 已為 Google 登錄,但客戶端不知道如何處理。我應該把那個 cookie 傳回www.webpics.com嗎?

在 SPA 應用程序中,它是通過 AJAX 完成的,google.com將返回一個令牌作為 URL 片段,這一切都很好,因為它都位於一個域上。但這在很大程度上違背了擁有多個客戶端可以充分使用的“API”的意義。

幫助!

更新:自從我在一月份寫這篇文章以來,情況發生了變化:MSFT 發布了他們的官方 OpenID 連接客戶端中間件,我與 @manfredsteyer 一起努力將 Katana 中內置的 OAuth2 授權伺服器適配到 OpenID 連接。這種組合產生了一個更簡單、更強大的解決方案,不需要任何自定義客戶端程式碼,並且與標準 OAuth2/OpenID 連接客戶端 100% 兼容。我在一月份提到的不同步驟現在可以只用幾行代替:

伺服器:

app.UseOpenIdConnectServer(options =&gt;
{
   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>


Josh,您絕對走在正確的軌道上,並且您的委託/聯合身份驗證實現看起來相當不錯(我想您已經使用了來自 的預定義 OWIN 中間件Microsoft.Owin.Security.Facebook/Google/Twitter)。

您需要做的是創建自己的自定義OAuth2 授權伺服器。您有很多選擇來實現這一點,但最簡單的一種可能是插入OAuthAuthorizationServerMiddleware您的 OWIN Startup 類。你會在Microsoft.Owin.Security.OAuthNuget 包中找到它。

雖然最佳實踐是創建一個單獨的項目(通常稱為“AuthorizationServer”),但我個人更喜歡將它添加到我的“API 項目”中,因為它不打算跨多個 API 使用(在這裡,您必須插入它在託管“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")]在我的範例,我已將其更改AuthorizeEndpointPathoauth2/用作路徑基礎)。

您需要做的另一件事是在您的 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 個方法)、IGoogleOAuth2AuthenticationProviderGoogleOAuth2ReturnEndpointContext、和。將這些文件插入到託管“webpics.com”的項目中後,相應地重命名它們並更改授權和訪問令牌端點 URL以匹配您在 OAuth2 授權伺服器中定義的那些。GoogleOAuth2AuthenticationProvider``GoogleOAuth2AuthenticatedContext``GoogleOAuth2ApplyRedirectContext``GoogleOAuth2AuthenticationHandler

然後,將重命名/自定義中的 Use 方法添加GoogleAuthenticationExtensions到 OWIN Startup 類。我建議使用AuthenticationMode.Active這樣您的使用者將被直接重定向到您的 API OAuth2 授權端點。因此,您應該禁止“api.prettypictures.com/Account/ExternalLogins”往返並讓 OAuth2 客戶端中間件更改 401 響應以將客戶端重定向到您的 API。

祝你好運。如果您需要更多資訊,請不要猶豫;)

引用自:https://stackoverflow.com/questions/21167648