我尝试使用OpenID Connect身份验证将标准MVC Auth示例(http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on)扩展到Thinktecture IdentityServer(https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/Simplest%20OAuth2%20Walkthrough)的实例。
我将'openid'范围添加到IdentityServer的范围。 我使用https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/MVC%20Authentication/EmbeddedMvc/Startup.cs中的示例代码将额外调用添加到userinfo端点。
认证中间件链中的更高位 - 根据MVC Auth示例 - UseCookieAuthentication
和UseExternalSignInCookie
。
当我在OpenIdConnectAuthenticationNotifications.SecurityTokenValidated
中放置断点时,我可以看到所有声明都很好地进入。所以与IdentityServer的通信是正确的。
但是当我到AccountController.ExternalLoginCallback
致电
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
始终返回null。
使用Google OAuth2登录时,它不为空。
我怀疑UseOpenIdConnectAuthentication
如何设置(或未设置)Cookie信息与UseCookieAuthentication
提取它的方式不匹配。但我无法解决这个问题。
答案 0 :(得分:3)
事实证明,https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/MVC%20Authentication/EmbeddedMvc/Startup.cs中的示例代码确实用类型
覆盖了声明"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier".
如果未找到此声明,则找不到loginInfo。
问题代码(Startup.Auth.cs):
var nid = new ClaimsIdentity(
n.AuthenticationTicket.Identity.AuthenticationType,
Constants.ClaimTypes.GivenName, // "given_name"
Constants.ClaimTypes.Role // "role"
);
解决方案是保留原始声明,如下所示:
var nid = new ClaimsIdentity(
n.AuthenticationTicket.Identity,
n.AuthenticationTicket.Identity.Claims
);
答案 1 :(得分:0)
我遇到了类似的问题,尽管我没有提出有时可以进行身份验证并恢复身份声明的原因,但我确实设法通过下载和调试Microsoft代码来弄清ExternalLoginInfo始终为空的原因
我遇到的问题是OpenIdConnectAuthenticationOptions中提供的 ResponseType -我将其设置为 OpenIdConnectResponseType.Code ,这是不正确的...将其设置为 OpenIdConnectResponseType.CodeIdToken 使其始终如一地工作。
这是我的Startup.Auth.vb来源的副本:
for (int n = 1; n <= 64; ++n)
{
a[n - 1] = (n * (exp2(n)));
}
for (int n = 1; n <= 64; ++n)
{
a[n - 1] = a[n - 1] - 1;
}