我使用 IdentityServer 4 构建了一个 Android 应用程序,其中可以选择使用 Google 登录。
有没有人可以解释一下这种情况下的工作流程是什么?
我为启动添加了 Google 身份验证:
services.AddAuthentication()
.AddGoogle(options =>
{
IConfigurationSection googleAuthNSection = Configuration.GetSection("Authentication:Google");
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = googleAuthNSection["ClientId"];
options.ClientSecret = googleAuthNSection["ClientSecret"];
});
为 Android 创建了一个触发器端点:
[HttpGet("Google")]
public IActionResult Google(string provider)
{
provider = "Google";
var redirectUrl = Url.Action("ExternalLoginCallback");
var props = new AuthenticationProperties
{
RedirectUri = redirectUrl,
Items =
{
{ "scheme", provider }
}
};
return Challenge(props, provider);
}
Google 登录成功后浏览器重定向到“ExternalLoginCallback”:
[HttpGet("ExternalLoginCallback")]
public async Task<IActionResult> ExternalLoginCallback()
{
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result == null)
return BadRequest("External authentication is null");
if (!result.Succeeded)
{
throw new Exception("External authentication error");
}
var externalUser = result.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 == ClaimTypes.NameIdentifier);
}
if (userIdClaim == null)
{
throw new Exception("Unknown userid");
}
var externalUserId = userIdClaim.Value;
var externalProvider = userIdClaim.Issuer;
var email = externalUser.FindFirstValue(ClaimTypes.Email);
var user = await _userManager.FindByEmailAsync(email);
if (user != null)
{
}
else
{
user = new IdentityUser()
{
Email = email,
UserName = externalUser.FindFirstValue(ClaimTypes.Name)
};
var createResult = await _userManager.CreateAsync(user);
if(!createResult.Succeeded)
{
return BadRequest(string.Join(", ", createResult.Errors.Select(item => item.Code)));
}
//THE QUESTION: WHAT IS THE NEXT STEP TO ANDROID APP CAN INTENT A PAGE AND GET IDENTITYSERVER ACCESS_TOKEN AND REFRESH_TOKEN??
}
}
问题在代码中作为注释。