Skip to content

Instantly share code, notes, and snippets.

@stonetip
Last active August 29, 2015 13:55
Show Gist options
  • Save stonetip/8745656 to your computer and use it in GitHub Desktop.
Save stonetip/8745656 to your computer and use it in GitHub Desktop.
JWT token validation class
internal class TokenValidationHandler : DelegatingHandler
{
// This function retrieves ACS token (in format of OAuth 2.0 Bearer Token type) from
// the Authorization header in the incoming HTTP request from the client.
private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
{
try
{
token = null;
IEnumerable<string> authHeaders;
request.Headers.TryGetValues("Authorization", out authHeaders);
var authHeadersList = authHeaders.ToList();
if (authHeadersList.Count() != 1)
{
// Fail if no Authorization header or more than one Authorization headers
// are found in the HTTP request
return false;
}
token = authHeadersList.FirstOrDefault();
return true;
}
catch (Exception err)
{
Debug.WriteLine(err.Message);
token = null;
return false;
}
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
string token;
if (!TryRetrieveToken(request, out token))
{
return
Task<HttpResponseMessage>.Factory.StartNew(
() => new HttpResponseMessage(HttpStatusCode.Unauthorized), cancellationToken);
}
try
{
// Use JwtSecurityTokenHandler to validate the JWT token
var tokenHandler = new JwtSecurityTokenHandler();
var convertedSecret = EncodeSigningToken(ConfigurationManager.AppSettings["ClientSecret"]);
// Set the expected properties of the JWT token in the TokenValidationParameters
var validationParameters = new TokenValidationParameters()
{
AllowedAudience = ConfigurationManager.AppSettings["AllowedAudience"],
ValidIssuer = ConfigurationManager.AppSettings["Issuer"],
SigningToken = new BinarySecretSecurityToken(convertedSecret)
};
Thread.CurrentPrincipal = tokenHandler.ValidateToken(token, validationParameters);
if (HttpContext.Current != null)
{
HttpContext.Current.User = Thread.CurrentPrincipal;
}
// Treat as ClaimsPrincipal, extract JWT expiration and inject it into request headers
var cp = (ClaimsPrincipal)Thread.CurrentPrincipal;
request.Headers.Add("JWT-Expiration", cp.FindFirst("exp").Value);
return base.SendAsync(request, cancellationToken);
}
catch (SecurityTokenValidationException stvErr)
{
Debug.WriteLine(stvErr.Message);
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Unauthorized));
}
catch (Exception err)
{
Debug.WriteLine(err.Message);
return Task.FromResult((new HttpResponseMessage(HttpStatusCode.InternalServerError)));
}
}
public static byte[] StrToByteArray(string str)
{
var encoding = new UTF8Encoding();
return encoding.GetBytes(str);
}
public static byte[] EncodeSigningToken(string token)
{
try
{
var sha256 = new SHA256Managed();
var secretBytes = StrToByteArray(token + "JWTSig");
var signingKey = sha256.ComputeHash(secretBytes);
return signingKey;
}
catch (Exception)
{
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment