Hey there, my fellow tech-savvy readers!
Now, picture this: you've got a trusty ASP.NET 4.5 WebAPI application chugging along like a well-oiled machine, doing its thing, and you're thinking, "Why change something that works just fine?" 💼🕶️
But as the tech world evolves faster than a cheetah chasing its morning coffee, I started feeling the pressure once I set sails to incorporate Azure Active Directory B2C into my relatively older codebase. 💨☁️
And there's the rub! 🌶️ Integrating ADB2C into this tried-and-true ASP.NET version came to me like introducing a jazz band to a black-tie ball. 😂🎷
But fear not as I'm here to help you navigate these waters with a smile on your face and a skip in your step. 💃🕺
I'll show you how to combine the old and the new in a seamless dance that'll make your ASP.NET 4.5 WebAPI look and feel like it's on cloud nine! ☁️💫
So grab your coding wands, and let's sprinkle some Azure Active Directory B2C fairy dust over your beloved ASP.NET 4.5 WebAPI! 🧙♂️✨
Assumptions
At this point, I'm assuming the following:
- You have already set up your Azure Account
- You already have the necessary information and credentials required to create the hand-shake between Azure and your ASP.NET App
- You have already defined scopes, and policies
Step 1
Start by adding the necessary credentials and information in your Web.config file. Per my experience, you're going to be needing the following
<add key="AZB2C:AadInstance" value="https://<YOUR_AZURE_DOMAIN>.b2clogin.com/{0}/{1}/v2.0/.well-known/openid-configuration" />
<add key="AZB2C:Tenant" value="<YOUR_AZURE_DOMAIN>.onmicrosoft.com" />
<add key="AZB2C:TenantId" value="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" />
<add key="AZB2C:ClientId" value="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" />
<add key="AZB2C:ClientSecret" value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
<add key="AZB2C:RedirectUri" value="http://localhost:3000/" />
<add key="AZB2C:SignUpSignInPolicyId" value="SIGN_IN_POLICY_NAME" />
<add key="AZB2C:ResetPasswordPolicyId" value="PASSWORD_RESET_POLICY_NAME" />
<add key="AZB2C:SOME_SCOPE_NAME" value="Scope.Something.Something" />
<add key="AZB2C:ANOTHER_SCOPE_NAME" value="Scope.Yes.AnotherSomething" />
We are going to be basing our code off of these credentials.
Step 2
Create a *civilized * way of using these environment variables in your code by creating a static class that extracts all the env variables from the Web.config into a Static Class Instance. This way, you can easily access these environment variables all across your application.
public static class AzureEnvironmentVariables
{
public static string AadInstance = ConfigurationManager.AppSettings["AZB2C:AadInstance"];
public static string Tenant = ConfigurationManager.AppSettings["AZB2C:Tenant"];
public static string TenantId = ConfigurationManager.AppSettings["AZB2C:TenantId"];
public static string ClientId = ConfigurationManager.AppSettings["AZB2C:ClientId"];
public static string ClientSecret = ConfigurationManager.AppSettings["AZB2C:ClientSecret"];
public static string RedirectUri = ConfigurationManager.AppSettings["AZB2C:RedirectUri"];
public static string SignUpSignInPolicyId = ConfigurationManager.AppSettings["AZB2C:SignUpSignInPolicyId"];
public static string ResetPasswordPolicyId = ConfigurationManager.AppSettings["AZB2C:ResetPasswordPolicyId"];
public static string DefaultPolicy = SignUpSignInPolicyId;
public static string FirstScope = AadInstance + ConfigurationManager.AppSettings["api:SOME_SCOPE_NAME"];
public static string SecondScope = AadInstance + ConfigurationManager.AppSettings["api:ANOTHER_SCOPE_NAME"];
public static string[] Scopes = new string[] { FirstScope, SecondScope };
public static string B2CAuthority = string.Format(AadInstance, Tenant, DefaultPolicy);
public static string WellKnownMetadata = $"{AadInstance}/v2.0/.well-known/openid-configuration?p={SignUpSignInPolicyId}";
}
Step 3
Create your auth provider
No go ahead and create a new file in your App_Start
folder called Startup.Auth.cs
In this file, you are going to create a Startup Extension Method that will be triggered on Startup time and register your Auth Provider, called Startup.Auth into your application.
public partial class Startup
{
public static string AadInstance = AzureEnvironmentVariables.AadInstance;
public static string Tenant = AzureEnvironmentVariables.Tenant;
public static string TenantId = AzureEnvironmentVariables.TenantId;
public static string ClientId = AzureEnvironmentVariables.ClientId;
public static string SignUpSignInPolicy = AzureEnvironmentVariables.SignUpSignInPolicyId;
public static string DefaultPolicy = SignUpSignInPolicy;
public void ConfigureAuth(IAppBuilder app)
{
TokenValidationParameters tvps = new TokenValidationParameters
{
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy,
SaveSigninToken = true,
};
string metadataEndpoint = String.Format(AadInstance, Tenant, DefaultPolicy);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(metadataEndpoint))
});
}
}
public class OpenIdConnectCachingSecurityTokenProvider : IIssuerSecurityKeyProvider
{
public ConfigurationManager<OpenIdConnectConfiguration> _configManager;
private string _issuer;
private IEnumerable<SecurityKey> _keys;
private readonly string _metadataEndpoint;
private readonly ReaderWriterLockSlim _synclock = new ReaderWriterLockSlim();
public OpenIdConnectCachingSecurityTokenProvider(string metadataEndpoint)
{
_metadataEndpoint = metadataEndpoint;
_configManager = new ConfigurationManager<OpenIdConnectConfiguration>(metadataEndpoint, new OpenIdConnectConfigurationRetriever());
RetrieveMetadata();
}
public string Issuer
{
get
{
RetrieveMetadata();
_synclock.EnterReadLock();
try
{
return _issuer;
}
finally
{
_synclock.ExitReadLock();
}
}
}
public IEnumerable<SecurityKey> SecurityKeys
{
get
{
RetrieveMetadata();
_synclock.EnterReadLock();
try
{
return _keys;
}
finally
{
_synclock.ExitReadLock();
}
}
}
private void RetrieveMetadata()
{
_synclock.EnterWriteLock();
try
{
OpenIdConnectConfiguration config = Task.Run(_configManager.GetConfigurationAsync).Result;
_issuer = config.Issuer;
_keys = config.SigningKeys;
}
finally
{
_synclock.ExitWriteLock();
}
}
}
Step 4
Now go ahead and call your Startup extension method in the Configurations
function within your Startup.cs file to actually register your Auth Provider.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
}
}
Step 5
Finally, add the Authorize
annotation in your controllers on the Endpoints that you'd like to protect and avoid any unauthorized access.
[Authorize]
public class YourAwesomeApiController: ApiController
And there you have it! 🎉✨
You've now unlocked the secrets of integrating Azure Active Directory B2C in your ASP.NET 4.5 WebAPI, proving once and for all that old dogs can learn some fantastic new tricks! 🐶🎩
Happy coding and may your cloud adventures be filled with endless fun and success! 🌌💖✨
Top comments (0)