对于在搜索结果中遇到此问题且无法将快速入门与 ASPNET Identity 快速入门相结合的任何人,这里是缺少的部分。
在大多数情况下,您希望使用 ASPNET 身份代码,利用 SignInManager 来完成繁重的工作。一旦你到达那里并从快速开始添加 Window 身份验证代码,你应该到达一切看起来都在工作的地步,但是你在回调中的这一行得到 null:
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
要将 Windows 视为真正的外部提供程序,而不是在第 163 行附近将“方案”添加到 auth 属性中,您希望将密钥更改为“LoginProvider”:
properties.Items.Add("LoginProvider", AccountOptions.WindowsAuthenticationSchemeName);
我使用域查询来提取有关我的用户的额外信息,如下所示:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
using (UserPrincipal up = UserPrincipal.FindByIdentity(pc, wp.Identity.Name))
{
if (up == null)
{
throw new NullReferenceException($"Unable to find user: {wp.Identity.Name}");
}
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, up.Sid.Value));
id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Email, up.EmailAddress));
id.AddClaim(new Claim(Constants.ClaimTypes.Upn, up.UserPrincipalName));
id.AddClaim(new Claim(JwtClaimTypes.GivenName, up.GivenName));
id.AddClaim(new Claim(JwtClaimTypes.FamilyName, up.Surname));
}
添加什么声明由您决定,但您需要使用 ClaimTypes.NameIdentifier 类型之一,以便 SigninManager 找到。 SID 对我来说似乎是最好的用途。最后要更改的是在第 178-181 行附近使用正确方案的 SignInAsync 调用:
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), properties);
除非您覆盖 IdentityServer4 在 .net core 2 中使用的默认方案,否则这是正确的默认方案。现在您在回调中调用 GetExternalLoginInfoAsync 将起作用,您可以继续!