使用OWIN Identity从多个API客户端注册Web API 2外部login

我想要下面的架构(我已经为此示例组成了产品名称):

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

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

我想要www.webpics.com客户端应用程序使用Pretty Pictures API来:

  • 使用用户名和密码注册新帐户
  • 使用Facebook / Google / Twitter / Microsoft注册新帐户
  • login
  • 检索图片

除了在Facebook,Google等地注册外部账户外,所有上述作品

我无法制定正确的stream程来从API的单独客户端用户创build外部帐户。

我已经研究了authenticationstream程中可用的大部分文档,如下所示: 在这里输入图像说明

我已经在OWIN中的新身份模型上读了几乎所有的东西。

我已经在Visual Studio 2013中研究了SPA模板。它演示了如何完成我所需要的大部分工作,但只有当客户端和API位于同一个主机上时才需要。 如果我想要多个客户端访问我的API,并能够让用户通过谷歌等注册这是行不通的,据我所知,OWIN身份validationstream程中断。

这是目前的stream程:

  • 用户浏览www.webpics.com/Login
  • www.webpics.com调用api.prettypictures.com/Account/ExternalLogins (带有returnUrl设置回到在www.webpics.comcallback),并显示链接到用户
  • 用户点击“Google”
  • 浏览器使用提供商的名称redirect到api.prettypictures.com/Account/ExternalLogin
  • API的ExternalLogin操作实例化对google.com的挑战
  • 浏览器被redirect到google.com
  • 用户input他们的用户名和密码(如果他们还没有login到google.com
  • google.com现在提出了安全许可: “api.prettypictures.com”想访问您的电子邮件地址,姓名,妻子,孩子等。这是行吗?
  • 用户点击“ YEP ”, 然后用Google设置的cookie将其带回api.prettypictures.com/Account/ExternalLogin

这是我卡住的地方。 接下来应该发生的事情是,应该通知客户端应用程序已经成功通过google.com的身份validation,并被赋予一个单一的访问代码,以便稍后交换访问令牌。 如有必要,客户端应用程序应该有机会提示用户input用户名与其google.comlogin关联。

我不知道如何促进这一点。

事实上,在Google的callback之后,浏览器终于​​坐在了api.prettypictures.com/Account/ExternalLogin端点上。 APIloginGoogle,但客户不知道如何处理。 我应该把这个cookie传回www.webpics.com吗?

在SPA应用程序中,通过AJAX完成, google.com会将一个令牌作为URL片段返回,并且它们都可以很好地工作,因为它们都位于一个域中。 但是,这就意味着有多个客户端可以充分使用的“API”。

帮帮我!

更新:自从我在1月份写这篇文章以来,事情已经发生了变化 :MSFT发布了他们的官方OpenID连接客户端中间件,并且与@manfredsteyer一起努力使内置于Katana的OAuth2授权服务器适应OpenID连接。 这种组合的结果是一个更简单,更强大的解决scheme,不需要任何自定义的客户端代码,并与标准的OAuth2 / OpenID连接客户端100%兼容。 一月份我提到的不同步骤现在可以用几行代替:

服务器:

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仓库find所有的细节(和不同的样本):

https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server

https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/dev/samples/Nancy


乔希,你肯定是在正确的轨道上,你的委托/联合身份validation实现似乎相当不错(我想你已经使用了Microsoft.Owin.Security.Facebook/Google/Twitter预定义的OWIN中间件)。

您需要做的是创build您自己的自定义OAuth2授权服务器 。 你有很多select来实现这个目标,但是最简单的方法是在你的OWIN Startup类中插入OAuthAuthorizationServerMiddleware 。 您可以在Microsoft.Owin.Security.OAuth Nuget包中find它。

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

你会在Katana仓库find一个很好的例子:

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这样的高级框架,请创build您自己的AuthorizationController控制器和Authorize方法(确保同时接受GET和POST),并使用Attribute Routing来匹配OAuth2授权服务器中定义的AuthorizeEndpointPath(即。 [Route("oauth2/authorize")]在我的示例中,我已经更改了AuthorizeEndpointPath使用oauth2/作为path基地)。

您需要做的另一件事是在您的Web应用程序中添加一个OAuth2授权客户端。 不幸的是,在Katana中没有通用的OAuth2客户端支持,你必须build立自己的。 我亲自向武士刀队提交了一个build议,但是被拒绝了。 但不要惊慌,这样做很容易:

从位于那里的Microsoft.Owin.Security.Google存储库复制相应的文件: https : //katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs

您需要GoogleOAuth2AuthenticationHandlerGoogleOAuth2AuthenticationMiddlewareGoogleOAuth2AuthenticationOptionsGoogleAuthenticationExtensions (您将必须移除对应于Google OpenID实施的前两种方法), IGoogleOAuth2AuthenticationProviderGoogleOAuth2ReturnEndpointContextGoogleOAuth2AuthenticationProviderGoogleOAuth2AuthenticatedContextGoogleOAuth2ApplyRedirectContext 。 在托pipe“webpics.com”的项目中插入这些文件后,请相应地重命名这些文件,并更改GoogleOAuth2AuthenticationHandler中的授权和访问令牌端点URL, GoogleOAuth2AuthenticationHandler与您在OAuth2授权服务器中定义的端点URL匹配。

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

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