I am creating IdentityServer4 auth with ASP.NET Identity, for React SPA and an ASP.NET Core Web API with policy-based authorization.
Take a look at this flow diagram as I am not yet able to embed images directly into the question.
So basically what I have done till now,
- React SPA will have "Sign in with Google" ("react-google-login" lib) on successful Google login
- Received response with "tokenObj" which contains IdToken and other stuff
- POST request, using Id token and some extra claims field, from React SPA to the IdentityServer4 endpoint
- Validated IdToken from IdentityServer4 controller endpoint using Google client library method Google.Apis.Auth.GoogleJsonWebSignature.ValidateAsync
- On successful IdToken validation Create/Get the user using ASP.NET Identity UserManager methods and,
- Also, the custom claim which was passed in the POST request is added for that user into DB
What I want to do now,
- Getting an "access_token" from the IdentityServer4, to pass it into that POST request's successful response.
Note: Don't want to pass Google provided access_token to the React SPA. Want to pass an IdentityServer4 issued access_token to the SPA. And Access token should contain that custom claim while decoded, further to process policy-based authorization in another API. I also knew about ProfileService is used to pass the custom claims inside the access token issued by IdentityServer4, so ProfileService I have implemented.
So the question is mainly focused on how to pass the new access_token issued by IdentityServer4 after validating users using Google IdToken.
Minimal working example
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();
}
}