问题描述
我正在使用ASP.NET Identity创建ASP.NET Identity,用于React SPA和具有基于策略授权的ASP.NET Core Web API。
Take a look at this flow diagram as I am not yet able to embed images directly into the question.
所以基本上到目前为止我所做的,
- 成功登录Google后,React SPA将具有“使用Google登录”(“ react-google-login”库)
- 通过“ tokenObj”收到的响应,其中包含 IdToken 和其他内容 从 React SPA 到 IdentityServer4 端点,使用 Id令牌和一些其他声明字段进行
- POST请求 使用Google客户端库方法Google.Apis.Auth.GoogleJsonWebSignature.ValidateAsync从IdentityServer4控制器端点进行了
- Validate IdToken
- 成功进行IdToken验证后,使用ASP.NET Identity UserManager方法创建/获取用户,
- 此外,在POST请求中传递的自定义声明已为该用户添加到数据库中
我现在要做什么,
- 从IdentityServer4获取“ access_token”,并将其传递到该POST请求的成功响应中。
注意:不想将Google提供的access_token传递给React SPA。想 将通过 access_token 发行的IdentityServer4传递给SPA。并且访问令牌在解码时应包含该自定义声明,以进一步处理基于策略的 另一个API中的授权。 我还知道ProfileService用于在IdentityServer4发出的访问令牌中传递自定义声明,因此我已经实现了ProfileService。
因此,问题主要集中在使用Google IdToken验证用户后如何传递由 IdentityServer4 发行的新 access_token 。
最小的工作示例
public class ExternalLoginModel
{
public string IdToken { get; set; }
public string UserRole { get; set; }
}
[Route("api/[controller]")]
[ApiController]
public class ExternalAuthController : ControllerBase
{
[HttpPost]
[Route("google")]
public async Task<IActionResult> AuthenticateGoogleSignin(ExternalLoginModel externalLoginModel)
{
Payload payload;
var provider = "google";
try
{
// currently no need to validate
var validationSettings = new ValidationSettings
{ Audience = new[] { "YOUR_CLIENT_ID" } };
payload = await GoogleJsonWebSignature.ValidateAsync(
externalLoginModel.IdToken,validationSettings);
// create custom claims and store claims for the user found from Google IdToken
// storing custom claims passed in request if user is created.
var userRole = externalLoginModel.UserRole;
var user = await GetOrCreateExternalLoginUser("google",payload.Subject,payload.Email,userRole);
return Ok(new
{
access_token = "want_to_give_identity_server4_issued_access_token"
});
}
catch
{
// Invalid token
}
return BadRequest();
}
}
解决方法
我认为您使事情变得比必须的复杂。
我认为更好的方法是让您的SPA应用程序要求您的后端(ASP.NET身份)要求IdentityServer验证用户身份。然后,使用外部身份验证,IdentityServer将要求用户向Google进行身份验证。
这样做,IdentityServer和Google将直接相互通信。身份验证之后,您将从IdentityServer获得令牌并将其发送回ASP.NET Identity。使用这些令牌,可以向您的SPA应用程序发出正确的会话cookie。
这是避免SPA应用程序处理此问题的更安全的方法。
要进行外部身份验证,请注意以下几点:
- Exchanging external tokens from Facebook,Google and Twitter
- Sign-in with External Identity Providers
除了我认为这个问题可能需要进一步澄清之外?也许您的设置图片会有所帮助。
关于您的图片,您不应从React直接转到Google,而应先通过IdentityServer再通过Google,如下图所示:
反应和Google绝不应直接互动。 IdentityServer使您的应用程序免受Google的攻击。
,您必须执行以下步骤才能获得用户的海关索赔:-
- 将自定义声明添加到IdentityResource列表中。
- 针对用户提出索赔。
- 在允许的范围列表中针对客户添加声明 必须发行哪个令牌。
- 使用以下方式从身份服务器获取访问令牌后
然后可以调用用户Info端点
GET /connect/userinfo
的令牌来获取列表 为用户设置的索赔数量。