Initial commit

This commit is contained in:
2020-04-12 20:52:03 -04:00
parent e750d2848a
commit 01e7627293
249 changed files with 9733 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
using Ninject;
using Ninject.Modules;
using Ninject.Parameters;
using PartSource.Entities.Models;
using PartSource.Services;
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Filters;
namespace PartSource.Filters
{
public class HmacAuthenticationAttribute : Attribute, IAuthenticationFilter, IFilter
{
private readonly SecurityService _securityService;
public bool AllowMultiple { get { return false; } }
public HmacAuthenticationAttribute()
{
_securityService = new StandardKernel().Get<SecurityService>();
}
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
if (context.Request.Headers.Date.HasValue)
{
DateTimeOffset? date = context.Request.Headers.Date;
DateTimeOffset timestamp = date.Value;
if (ValidateTimestamp(timestamp))
{
if (context.Request.Headers.Authorization == null)
{
context.ErrorResult = new HmacErrorResult(HttpStatusCode.Unauthorized);
return;
}
string[] authParams = context.Request.Headers.Authorization.Parameter.Split(':');
ApiClient client = await _securityService.GetApiClientByKeyAsync(authParams[0]);
if (client == null || !client.Active)
{
context.ErrorResult = (IHttpActionResult)new HmacErrorResult(HttpStatusCode.Unauthorized);
return;
}
byte[] secret = Encoding.UTF8.GetBytes(client.Secret);
StringBuilder builder = new StringBuilder();
builder.Append((object)secret);
builder.Append((object)context.Request.Method);
StringBuilder stringBuilder = builder;
date = context.Request.Headers.Date;
string str = date.Value.ToString("r");
stringBuilder.Append(str);
if (context.Request.Method != HttpMethod.Get)
{
using (MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider())
builder.Append((object)md5Provider.ComputeHash(Encoding.UTF8.GetBytes(await context.Request.Content.ReadAsStringAsync())));
}
byte[] numArray;
using (HMACSHA1 hmacshA1 = new HMACSHA1(secret))
{
numArray = Encoding.UTF8.GetBytes(builder.ToString());
numArray = hmacshA1.ComputeHash(numArray);
}
if (Convert.ToBase64String(numArray) == authParams[1])
{
string[] roles = new string[1] { "ValidUser" };
context.Principal = (IPrincipal)new GenericPrincipal((IIdentity)new GenericIdentity(client.AppName), roles);
return;
}
context.ErrorResult = (IHttpActionResult)new HmacErrorResult(HttpStatusCode.Unauthorized);
return;
}
}
context.ErrorResult = (IHttpActionResult)new HmacErrorResult(HttpStatusCode.Unauthorized);
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
return new Task(null);
}
private bool ValidateTimestamp(DateTimeOffset timestamp)
{
if (int.TryParse(ConfigurationManager.AppSettings["ClockDriftThresholdMinutes"], out int result) && DateTimeOffset.UtcNow.AddMinutes((double)(result * -1)) < timestamp)
{
return timestamp < DateTimeOffset.UtcNow.AddMinutes((double)result);
}
return false;
}
}
}