使用 OWIN 标识从多个 API 客户端注册 Web API 2外部登录

我希望采用以下体系结构(我已经为这个示例创建了产品名称) :

在一台服务器上运行的 WebAPI 2应用程序 Http://api.prettypictures.com

在另一台服务器上运行的 MVC 5客户端应用程序 Http://www.webpics.com

我希望 Www.webpics.com客户端应用程序使用漂亮的图片应用程序接口:

  • 用用户名和密码注册新帐户
  • 在 Facebook/Google/Twitter/Microsoft 注册新账户
  • 登陆
  • 检索图片

除了在 Facebook、 Google 等网站注册外部账户以外,以上所有工作都可以完成。

我无法从 API 的单独客户端用户创建 外部帐户的正确流程。

我研究了认证流程中可用的大多数文档,如下所示: enter image description here

关于 OWIN 的新身份模型,我已经读了几乎所有我能读到的东西。

我研究了 VisualStudio2013中的 SPA 模板。它演示了如何做我需要的大部分,但只有当客户端和 API 在同一个主机上; 如果我想多个客户端访问我的 API,并能够让用户通过谷歌等注册,它不工作,至少我可以告诉 OWIN 认证流中断。

以下是迄今为止的流程:

  • 用户浏览到 Www.webpics.com/login
  • Www.webpics.com 调用 Api.prettypictures.com/account/externallogins(将 返回设置为返回到 Www.webpics.com的回调)并显示给用户的结果链接
  • 用户点击“ Google”
  • 浏览器使用提供程序的名称等重定向到 Api.prettypictures.com/account/externallogin
  • API 的 外部登录动作实例化了对 Google.com的挑战
  • 浏览器被重定向到 Google.com
  • 用户输入他们的用户名和密码(如果他们还没有登录到 Google.com)
  • Google.com 现在显示安全许可: < strong > “ api.prettypictures.com”希望访问您的电子邮件地址、姓名、妻子、孩子等。这样可以吗?
  • 用户点击“是的”,然后用谷歌设置的 cookie 返回到 Api.prettypictures.com/account/externallogin

这就是我被困住的地方。接下来应该发生的是,应该以某种方式通知客户机应用程序,用户已经成功地通过了 Google.com身份验证,并获得一个单一使用的访问代码,以便在以后交换访问令牌。如果需要,客户机应用程序应该有机会提示用户输入与其 Google.com登录相关联的用户名。

我不知道该怎么帮你。

事实上,在这一点上,浏览器最终停留在 Api.prettypictures.com/account/externallogin端点后,从谷歌的回调。这个 API 是为 Google 注册的,但是客户端不知道如何处理。我应该把曲奇传回 Www.webpics.com吗?

在 SPA 应用程序中,它是通过 AJAX 完成的,而 Google.com将返回一个标记作为 URL 片段,这一切都工作得很好,因为它都位于一个域上。但是,这在很大程度上违背了拥有一个多个客户端可以充分使用的“ API”的意义。

救命啊!

27997 次浏览

更新: 自从我在一月份写这篇文章以来,事情已经发生了变化 : 微软发布了他们官方的 OpenID 连接客户端中间件,我和@manfredsteyer 一起努力将在卡塔纳建立的 OAuth2授权服务器改造成 OpenID 连接。这种组合使得解决方案更加简单和强大,不需要任何自定义客户端代码,并且100% 兼容标准 OAuth2/OpenID 连接客户端。我在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 安全 OpenidConnect 服务器

Https://github.com/aspnet-contrib/aspnet。安全性。 OpenidConnect。服务器/树/dev/sample/Nancy


Josh,你绝对是在正确的轨道上,你的 委托/联邦身份验证实现看起来相当不错(我想你已经使用了来自 Microsoft.Owin.Security.Facebook/Google/Twitter的预定义的 OWIN 中间件)。

您需要做的是创建自己的定制 OAuth2授权服务器。您有很多选择来实现这一点,但最简单的一个可能是插入 OAuthAuthorizationServerMiddleware在您的 OWIN 启动类。你可以在 Microsoft.Owin.Security.OAuth Nuget 软件包中找到它。

虽然最好的做法是创建一个单独的项目(通常称为“ AuthorizationServer”) ,但我个人更喜欢将其添加到我的“ API 项目”中,因为它不适合跨多个 API 使用(在这里,您必须将其插入到托管“ API.prettypictures.com”的项目中)。

您将在卡塔纳知识库中找到一个很好的例子:

Https://katanaproject.codeplex.com/sourcecontrol/latest#tests/katana ,沙盒,网络服务器/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 (即。在我的示例中,我将 AuthorizeEndpointPath更改为使用 oauth2/作为路径基)。

您需要做的另一件事是在 Web 应用程序中添加 OAuth2授权客户端。不幸的是,在 Katana 中没有通用的 OAuth2客户端支持,您必须自己构建。我个人已经向卡塔纳队提交了一份提案但是被拒绝了。但不要惊慌,这很容易做到:

从位于此处的 Microsoft.Owin.Security.Google 存储库复制适当的文件: https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs

您将需要 GoogleOAuth2AuthenticationHandlerGoogleOAuth2AuthenticationMiddlewareGoogleOAuth2AuthenticationOptionsGoogleAuthenticationExtensions(您必须删除与 Google OpenID 实现相对应的前两个方法)、 IGoogleOAuth2AuthenticationProviderGoogleOAuth2ReturnEndpointContextGoogleOAuth2AuthenticationProviderGoogleOAuth2AuthenticatedContextGoogleOAuth2ApplyRedirectContext。将这些文件插入到承载“ webpics.com”的项目中后,相应地重命名它们,并更改 GoogleOAuth2AuthenticationHandler中的授权和访问令牌端点 URL,使其与在 OAuth2授权服务器中定义的端点相匹配。

然后,将重命名的/自定义的 GoogleAuthenticationExtensions中的 Use 方法添加到 OWIN Startup 类中。我建议使用 AuthenticationMode.Active,这样您的用户将被直接重定向到您的 API OAuth2授权端点。因此,您应该禁止“ API.prettypictures.com/account/externallogins”往返,让 OAuth2客户端中间件更改401响应,以将客户端重定向到您的 API。

祝你好运,如果你需要更多的信息,不要犹豫;)