Skip to content

Instantly share code, notes, and snippets.

@rbrayb
Created July 24, 2019 18:44
Show Gist options
  • Save rbrayb/3d5e2b9040777840a00129412a1b6d89 to your computer and use it in GitHub Desktop.
Save rbrayb/3d5e2b9040777840a00129412a1b6d89 to your computer and use it in GitHub Desktop.
ADFS JWT validation
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ValidateJWT
{
internal static class AsyncHelper
{
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();
}
}
}
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Threading;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Logging;
namespace ValidateJWT
{
// https://www.jerriepelser.com/blog/manually-validating-rs256-jwt-dotnet/
class Program
{
static void Main(string[] args)
{
// Set audience to your expected value
const string issuer = "http://my-adfs/adfs/services/trust";
const string audience = "https://localhost:44321/";
const string adfsWellKnown = "https://my-adfs/adfs/.well-known/openid-configuration";
// Add your JWT here
const string testToken = "eyJ...Reg"; // Obtain a JWT to validate and put it in here
// https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/wiki/PII
IdentityModelEventSource.ShowPII = true;
try
{
// Download the OIDC configuration which contains the JWKS
// NB!!: Downloading this takes time, so do not do it very time you need to validate a token, Try and do it only once in the lifetime
// of your application!!
IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>
(adfsWellKnown, new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration openIdConfig = AsyncHelper.RunSync(async () => await configurationManager.GetConfigurationAsync(CancellationToken.None));
// Configure the TokenValidationParameters. Assign the SigningKeys which were downloaded from ADFS.
// Also set the Issuer and Audience to validate
TokenValidationParameters validationParameters =
new TokenValidationParameters
{
ValidIssuer = issuer,
ValidAudience = audience,
IssuerSigningKeys = openIdConfig.SigningKeys
};
// Now validate the token. If the token is not valid for any reason, an exception will be thrown by the method
SecurityToken validatedToken;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var user = handler.ValidateToken(testToken, validationParameters, out validatedToken);
Console.WriteLine($"Token is validated.\n");
// The ValidateToken method above will return a ClaimsPrincipal.
// Enumerate the ClaimsPrincipal
if (null != user)
{
foreach (Claim claim in user.Claims)
{
Console.WriteLine(claim.Type + " " + claim.Value);
}
}
// Display the JSON
Console.WriteLine("\n" + validatedToken.ToString());
}
catch (Exception e)
{
Console.WriteLine($"Error occurred while validating token: {e.Message}");
}
Console.WriteLine();
Console.WriteLine("Press ENTER to continue...");
Console.ReadLine();
}
}
}
@rbrayb
Copy link
Author

rbrayb commented Jul 24, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment