I am working on an existing ASP.NET Core 3.1 web API. The existing authentication scheme is JWT. There is a new requirement that we support Single Sign on using Azure Active Directory.
So, I thought that the strategy I want to follow is to authenticate a user with Microsoft and when my signin-oidc URL callback is called, I will use the token from Microsoft to match my application's user. Then I will produce my existing JWT just the way the application already does, to authorize further actions. Therefore, I want to authenticate with Microsoft but then carry on with the older authorization scheme.
And now the problem. As far as I understand, the signin-oidc URL is not something that you define yourself but is rather hidden somewhere inside Microsoft.Identity.Web
.
Nevertheless, based on the description above, I concluded that I have to define it. So, what is the proper way to implement it? My implementation below works but something tells me I am missing something crucial to security.
[HttpPost("signin-oidc")]
[AllowAnonymous]
[RequireHttps]
public IActionResult AuthorizeAzureAD([FromForm] OIDCForm form)
{
var jwtHandler = new JwtSecurityTokenHandler();
var token = jwtHandler.ReadJwtToken(form.id_token);
var claims = token.Claims.ToArray();
// Use the nonce claim to make sure that this callback is initiated by me.
var guidClaim = claims.FirstOrDefault(c => c.Type == "nonce");
if (guidClaim == null || !_azureGuids.TryRemove(guidClaim.Value, out string guid))
return Unauthorized();
return Ok(/* return the old JWT to the application for further communication. */);
}
Thank you.