I'm using asp.net MVC with Owin middleware to integrate with Azure B2C using authorization code flow.
I need to somehow retain the returnUrl so that upon successful login, user is redirected to requested page per returnURL.
I've tried below but SecurityTokenValidatedNotification.ProtocolMessage.State is NULL on OnSecurityTokenValidated notification.
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
// only modify requests to the authorization endpoint
if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
{
var stateQueryString = notification.ProtocolMessage.State.Split('=');
var protectedState = stateQueryString[1];
var state = notification.Options.StateDataFormat.Unprotect(protectedState);
state.Dictionary.Add("mycustomparameter", "myvalue");
notification.ProtocolMessage.State = stateQueryString[0] + "=" + notification.Options.StateDataFormat.Protect(state);
}
return Task.FromResult(0);
}
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification nofication)
{
// only when authorization code is being swapped for tokens
if (nofication.TokenEndpointRequest?.GrantType == OpenIdConnectGrantTypes.AuthorizationCode)
{
var authority = "xxx";
try
{
var confidentialClient = ConfidentialClientApplicationBuilder.Create(ConfigurationManager.AppSettings["ClientId"].ToString())
.WithClientSecret("xxxx")
.WithB2CAuthority(authority)
.WithRedirectUri(ConfigurationManager.AppSettings["redirectUri"].ToString())
.Build();
var result = await confidentialClient.AcquireTokenByAuthorizationCode(new[] { string.Format("{0} {1}",clientId,OpenIdConnectScope.OfflineAccess) }, code)
.WithSpaAuthorizationCode()
.WithPkceCodeVerifier("ff38b3685b613c1d461ac0c5624baddf3d4243cf0d61f135abfa164c")
.ExecuteAsync();
nofication.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
catch (Exception ex)
{
// Log.Error("Azure B2C Authorization Code Received Method. " + ex, nameof(bla));
throw ex;
}
}
private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
string mycustomparameter;
//THIS LINE THROWS NULL EXCEPTION GIVEN ProtocolMessage.State is NULL
var protectedState = notification.ProtocolMessage.State.Split('=')[1];
var state = notification.Options.StateDataFormat.Unprotect(protectedState);
state.Dictionary.TryGetValue("mycustomparameter", out mycustomparameter);
return Task.CompletedTask;
}
Observations:
I can only get ProtocolMessage.State value if I use ResponseType idtoken or CodeIdToken
Any idea on how to pass returnUrl to azure b2c and get it back when using authorization code flow with OWIN.