I have been working with AADB2C Authentication and struggling over redirecting the user to home page with id_token as fragment in redirect url. below is how i initiate authentication challenge in Account controller
public class AccountController : Controller
{
public AzureAdB2COptions AzureAdB2COptions { get; set; }
public AccountController(IOptions<AzureAdB2COptions> b2cOptions)
{
AzureAdB2COptions = b2cOptions.Value;
}
// GET: /<controller>/
[HttpGet]
public IActionResult SignUpSignIn()
{
var redirectUrl = "http://localhost:7878/dasdfsd/home";
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl },
OpenIdConnectDefaults.AuthenticationScheme);
}
}
and below is where i redirect user to redirect url(http://localhost:7878/dgddfg/home) with id token fragmented along with url
public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
// Use MSAL to swap the code for an access token
// Extract the code from the response notification
var code = context.ProtocolMessage.Code;
string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
try
{
AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' '));
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
context.HandleResponse();
context.Response.Redirect("dfgfd/home#grant_type=" + context.ProtocolMessage.GrantType + "&id_token=" + result.IdToken);
}
catch (Exception)
{
//TODO: Handle
throw;
}
}
when user redirects to home page using javascript i get the id_token from url and calling Account controller action("GetAccessTokenAsync") to get access token using identity user
[HttpGet]
public async Task<string> GetAccessTokenAsync()
{
string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache = new MSALSessionCache(signedInUserID , HttpContext).GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
try
{
var userAccounts = await cca.GetAccountsAsync();
if (userAccounts == null && userAccounts.Count()==0)
{
throw new Exception("The User is NULL. Please clear your cookies and try again. Specifically delete cookies for 'login.microsoftonline.com'. See this GitHub issue for more details: https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi/issues/9");
}
AuthenticationResult result = await cca.AcquireTokenSilentAsync(AzureAdB2COptions.ApiScopes.Split(' '),userAccounts.FirstOrDefault());
return result.AccessToken;
}
catch (Exception ex)
{
//TODO: Handle
return "";
}
}
the problem here is the HttpContext.User
in action method is null. but if i remove the part where i have written the redirect url with id_token appended and context.HandleResponse();
in OnAuthorizationCodeReceived
,
user will be redirected without the id token yet when getAccessToken action executed HttpContext.User
will not be null, user will have every detail including claims.
How can i redirect user with id token in url and also to have user without being null to get access token in controller method? Is it something to do with cookie?