How to inject custom data into the ‘state’ parameter in an OpenID Connect MVC Application

It’s often desirable for an Azure Active Directory (Azure AD)- integrated application to maintain application state when sending request to Azure AD for login. The recommended way to achieve this is to use the ‘state’ parameter as defined in the OpenID Connect standards. Also mentioned in our documentation, the ‘state’ parameter is used for both preventing cross-site request forgery attacks and to maintain user’s state before authentication request occurs:

For an ASP.NET or ASP.NET CORE web application using OpenID Connect OWIN middleware, the ‘state’ parameter is maintained automatically by the middleware when sending out an authentication request as followed.

GET https://contoso.b2clogin.com/contoso.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1a_signup_signin
&client_id=<Application ID>
&redirect_uri=<Some redirect URL>
&response_mode=form_post
&response_type=id_token
&scope=openid
&state=OpenIdConnect.AuthenticationProperties%3dgAAAALy6…i
&nonce=defaultNonce

 

Upon receiving the response from Azure AD, the middleware takes care of validating the ‘state’ parameter to prevent cross-site forgery attack. Because this work is done automatically by the middleware framework, this begs the question: How can application developers still utilize this same ‘state’ parameter to maintain user state without compromising the middleware’s security feature?

The way to do this is…

The OpenID Connect OWIN middleware use .Net framework’s Data Protection API to encrypt the value stored in the ‘state’ parameter. Thinking along the same line we can use the following code in OpenIdConnectNotifications’s RedirectToIdentityProvider event to inject custom data into the ‘state’ parameter:

var stateQueryString = notification.ProtocolMessage.State.Split('=');
var protectedState = stateQueryString[1];
var state = notification.Options.StateDataFormat.Unprotect(protectedState);
state.Dictionary.Add("MyData", "123");
notification.ProtocolMessage.State = stateQueryString[0] + "=" + notification.Options.StateDataFormat.Protect(state);

And we can use the following code to read our custom data back in the AuthenticationFailed event, MessageReceived event, or at any other relevant place in the code after we receive a response from Azure AD:

string mycustomparameter;
var protectedState = notification.ProtocolMessage.State.Split('=')[1];
var state = notification.Options.StateDataFormat.Unprotect(protectedState);
state.Dictionary.TryGetValue("MyData", out mycustomparameter);

Reference:

https://stackoverflow.com/questions/37489964/custom-parameter-with-microsoft-owin-security-openidconnect-and-azuread-v-2-0-en/37520329#37520329

Troubleshooting Asp.Net OWIN and Asp.Net Core Authentication sign-in failures with Azure Active Directory

Let get started!

This article assumes you are using your own code to perform the authentication to Azure Active Directory.

IMPORTANT: So if your using Azure App Services or Azure Function Apps Authentication/Authorization feature, this article is not for you.

You are developing a Asp.Net OWIN or Asp.Net Core Authentication web application and integrating it with Azure Active Directory. You run into some issues during the sign-in process with no error message or any hint on what the problem might be. Some of the behaviors that you might see are…

  • The dreaded infinite loop between your web app and Azure Active Directory.
  • After signing into Azure Active Directory, you land back on to your Web Application like it never signed in.
  • You land on your error page with no useful error message.

The purpose of this article is not to show you how to resolve the failed sign-in attempt. Rather, I want to show you how to troubleshoot and maybe expose the hidden error message. Once you have unraveled the hidden error message, hopefully that will lead you down a path to resolve the failed sign-in attempt.


This is where the OnAuthenticationFailed notification comes in handy…

In Asp.Net, you want to make sure your code looks something like this for the for the AuthenticationFailed event notification event notification (in startup.auth.cs)…
[gist id=”5773aac85537d35ca0f0d496d1e7b581″ file=”AspNet_OWIN_OnAuthenticationFailed.cs”]


In Asp.Net Core, you want to make sure your code looks something like this for the for the OnAuthenticationFailed event notification event notification (in startup.cs)…
[gist id=”813dd19091dfa8650895182cb45d5d1c” file=”AspNetCore_Auth_OnAuthenticationFailed.cs”]


You can of course tweak this so that you can either send the error message to your logs or send it to a custom error page.

At minimum, we should see the error message in the address bar…

or in the case of the infinite loop, see it in the Fiddler capture…


For more information about using Fiddler, check out our Blog post here…

For a list of Azure Active Directory errors and and some tips on how to resolve, check out the following article…
https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes