2 回答
TA贡献1816条经验 获得超6个赞
IdentityServer4 QuickStart UI 配置为在通过外部提供商登录时自动配置本地用户帐户。这一切都在处理ExternalController.Callback:
// lookup our user and external provider info
var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);
if (user == null)
{
// this might be where you might initiate a custom workflow for user registration
// in this sample we don't show how that would be done, as our sample implementation
// simply auto-provisions new external user
user = AutoProvisionUser(provider, providerUserId, claims);
}
在您的情况下,您可以执行您需要执行的任何逻辑,而不是调用AutoProvisionUser. 由于这是正在执行的常规 MVC 操作,因此您可以将自己的类注入到ExternalController的构造函数中或注入到Callback自身中(使用[FromServices])。以下是您可能想要进行的更改的粗略想法:
public async Task<IActionResult> Callback([FromServices] IUserRepository userRepository)
{
...
// lookup our user and external provider info
var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);
if (user == null)
{
// We don't have a local user.
return RedirectToAction("SomeAction", "SomeController");
}
...
}
TA贡献1847条经验 获得超11个赞
如果您使用的是 ASP.NET Identity ,则可以在 inExternalLoginCallback函数中编写自定义逻辑。AccountController从 Azure AD 获得 JWT 令牌后,您可以解码令牌,获取用户声明,例如电子邮件/姓名:
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
return RedirectToAction(nameof(Login));
}
// read external identity from the temporary cookie
var aadResult1 = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (aadResult1?.Succeeded != true)
{
throw new Exception("External authentication error");
}
// retrieve claims of the external user
var externalUser = aadResult1.Principal;
if (externalUser == null)
{
throw new Exception("External authentication error");
}
// retrieve claims of the external user
var claims = externalUser.Claims.ToList();
// try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier
// depending on the external provider, some other claim type might be used
var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);
if (userIdClaim == null)
{
userIdClaim = claims.FirstOrDefault(x => x.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier");
}
if (userIdClaim == null)
{
throw new Exception("Unknown userid");
}
然后你可以在数据库中编写你的服务实现/逻辑来确认用户是否已经在数据库中。如果是,则登录用户;如果否,则将用户重定向到确认/注册视图。就像是:
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync("YourProvider", userIdClaim.Value, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in with {Name} provider.", "YourProvider");
// delete temporary cookie used during external authentication
await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
return RedirectToLocal(returnUrl);
}
if (result.IsLockedOut)
{
return RedirectToAction(nameof(Lockout));
}
else
{
// If the user does not have an account, then ask the user to create an account.
ViewData["ReturnUrl"] = returnUrl;
ViewData["LoginProvider"] = "YourProvider";
var email = claims.FirstOrDefault(x => x.Type == ClaimTypes.Upn).Value;
return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
}
如何将 AD 用户链接到本地数据库用户取决于您。使用 Azure AD 的对象 ID 或 UPN。
- 2 回答
- 0 关注
- 230 浏览
添加回答
举报
