You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
3.5 KiB
84 lines
3.5 KiB
using Microsoft.IdentityModel.Tokens;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
|
|
namespace JsonRx.Helper
|
|
{
|
|
internal class JwtValidationHandler : DelegatingHandler
|
|
{
|
|
private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
|
|
{
|
|
token = null;
|
|
IEnumerable<string> authzHeaders;
|
|
if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
|
|
{
|
|
return false;
|
|
}
|
|
var bearerToken = authzHeaders.ElementAt(0);
|
|
token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
|
|
return true;
|
|
}
|
|
|
|
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
|
{
|
|
HttpStatusCode statusCode;
|
|
string token;
|
|
//determine whether a jwt exists or not
|
|
if (!TryRetrieveToken(request, out token))
|
|
{
|
|
statusCode = HttpStatusCode.Unauthorized;
|
|
//allow requests with no token - whether a action method needs an authentication can be set with the claimsauthorization attribute
|
|
return base.SendAsync(request, cancellationToken);
|
|
}
|
|
|
|
try
|
|
{
|
|
const string sec = "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1";
|
|
var now = DateTime.UtcNow;
|
|
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
|
|
|
|
SecurityToken securityToken;
|
|
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
|
|
TokenValidationParameters validationParameters = new TokenValidationParameters()
|
|
{
|
|
ValidAudience = "http://localhost:50191",
|
|
ValidIssuer = "http://localhost:50191",
|
|
ValidateLifetime = true,
|
|
ValidateIssuerSigningKey = true,
|
|
LifetimeValidator = this.LifetimeValidator,
|
|
IssuerSigningKey = securityKey
|
|
};
|
|
//extract and assign the user of the jwt
|
|
Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
|
|
HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);
|
|
|
|
return base.SendAsync(request, cancellationToken);
|
|
}
|
|
catch (SecurityTokenValidationException e)
|
|
{
|
|
statusCode = HttpStatusCode.Unauthorized;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
statusCode = HttpStatusCode.InternalServerError;
|
|
}
|
|
return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode) { });
|
|
}
|
|
|
|
public bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
|
|
{
|
|
if (expires != null)
|
|
{
|
|
if (DateTime.UtcNow < expires) return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|