While creating an API to consume in our application or want to interact between applications. One of the key issue we need to address is to pass identity of authenticated user from our applications to our new applications or calling APIs. In my case it was a Azure function APIs which I need to authenticate before returning few details. Here I am referring how can we validate a passed a token in our API calls or app code. Here I am using a token issues by Azure AD so validating token using Microsoft namespaces. Below is the custom method I have written which we can call for validating token and get property of user for control. Here I am returning email address of user:
{
string email = "Invalid token.";
IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(appSigningKey, new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration openIdConfig = AsyncHelper.RunSync(async () => await configurationManager.GetConfigurationAsync(CancellationToken.None));
TokenValidationParameters validationParameters =
new TokenValidationParameters
{
ValidateLifetime = true,
ValidIssuer = appIssuer,
ValidAudiences = new[] { appAudience },
IssuerSigningKeys = openIdConfig.SigningKeys
};
SecurityToken validatedToken;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var user = handler.ValidateToken(jwtToken, validationParameters, out validatedToken);
// The ValidateToken method above will return a ClaimsPrincipal. Get the user ID from the NameIdentifier claim
// (The sub claim from the JWT will be translated to the NameIdentifier claim)
email = user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
if (string.IsNullOrEmpty(email)) { {
email = "Invalid token.";
}
return email;
}
Let me talk bit about this parameters in function:
"jwt": "provide your token here, you can pass it through request header"
"AppTokenIssuer": "https://login.microsoftonline.com/<tid>/v2.0" --- tid needs to be cheked from azure admin.
"AppTokenAudience": "<aud>"--- aud needs to be cheked from azure admin.
"AppSigningKey": "https://login.microsoftonline.com/<tid>/.well-known/openid-configuration" --- tid needs to be cheked from azure admin.
Namespaces we would need for these classes:
Microsoft.IdentityModel.Protocols;
Microsoft.IdentityModel.Protocols.OpenIdConnect
Microsoft.IdentityModel.Tokens
System.IdentityModel.Tokens.Jwt
System.Security.Claims
System.Collections.Generic
You need to add this additional class for execute task asynchronously:
{
private static readonly TaskFactory TaskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);
public static void RunSync(Func<Task> func)
{
TaskFactory.StartNew(func).Unwrap().GetAwaiter().GetResult();
}
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
{
return TaskFactory.StartNew(func).Unwrap().GetAwaiter().GetResult();
}
}
No comments:
Post a Comment