using Manjinba.Dynamics.Domain.Common;
using Manjinba.Dynamics.Domain.Models.ResponseBase;
using Manjinba.Dynamics.Infrastructure.Cache.Redis.Implement;
using Manjinba.Dynamics.Infrastructure.Cache.Redis.Interface;
using Manjinba.Dynamics.Infrastructure.Utility.AppSettingsGet;
using Manjinba.Dynamics.Infrastructure.Utility.Encrypt;
using Manjinba.Dynamics.WebApi.Attributes;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Net;
namespace Manjinba.Dynamics.WebApi.Filters
{
public class CustomerAuthorizationFilter : IAuthorizationFilter
{
/// <summary>
///
/// </summary>
private readonly ILogger _logger;
/// <summary>
///
/// </summary>
/// <param name="loggerFactory"></param>
public CustomerAuthorizationFilter(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<CustomerActionFilter>();
}
/// <summary>
/// Called early in the filter pipeline to confirm request is authorized.
/// </summary>
/// <param name="context"></param>
public void OnAuthorization(AuthorizationFilterContext context)
{
#region token signature 验证
var response = new OperationResult(OperationResultType.UnDefined);
var actionDescriptor = ((ControllerActionDescriptor)context.ActionDescriptor).ControllerName + "/" + ((ControllerActionDescriptor)context.ActionDescriptor).ActionName;
var ignoreAttribute = ((ControllerActionDescriptor)context.ActionDescriptor).MethodInfo.GetCustomAttributes(typeof(IgnoreAuthCheckAttribute), true);
var allowAnonymousAttribute = ((ControllerActionDescriptor)context.ActionDescriptor).MethodInfo.GetCustomAttributes(typeof(AllowAnonymousAttribute), true);
if (!ignoreAttribute.Any() && !allowAnonymousAttribute.Any())
{
_logger.LogDebug($"收到'{actionDescriptor}'请求,过滤验证。");
}
else
{
// 获取头参数,代理亦可用
string tokenKey = string.Empty, innerTokenKey = string.Empty, timeStampKey = string.Empty, signatureKey = string.Empty, versionKey = string.Empty;
string token = string.Empty, innerToken = string.Empty, timeStamp = string.Empty, signature = string.Empty, version = string.Empty;
var headers = context.HttpContext.Request.Headers;
if (headers.Keys.Any(w => w.Equals("Token", StringComparison.CurrentCultureIgnoreCase)))
{
tokenKey = headers.Keys.Where(w => w.Equals("Token", StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
token = headers.GetCommaSeparatedValues(tokenKey).FirstOrDefault();
}
if (headers.Keys.Any(w => w.Equals("InnerToken", StringComparison.CurrentCultureIgnoreCase)))
{
innerTokenKey = headers.Keys.Where(w => w.Equals("InnerToken", StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
innerToken = headers.GetCommaSeparatedValues(innerTokenKey).FirstOrDefault();
}
if (headers.Keys.Any(w => w.Equals("TimeStamp", StringComparison.CurrentCultureIgnoreCase)))
{
timeStampKey = headers.Keys.Where(w => w.Equals("TimeStamp", StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
timeStamp = headers.GetCommaSeparatedValues(timeStampKey).FirstOrDefault();
}
if (headers.Keys.Any(w => w.Equals("Signature", StringComparison.CurrentCultureIgnoreCase)))
{
signatureKey = headers.Keys.Where(w => w.Equals("Signature", StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
signature = headers.GetCommaSeparatedValues(signatureKey).FirstOrDefault();
}
if (headers.Keys.Any(w => w.Equals("Version", StringComparison.CurrentCultureIgnoreCase)))
{
versionKey = headers.Keys.Where(w => w.Equals("Version", StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
version = headers.GetCommaSeparatedValues(versionKey).FirstOrDefault();
}
if ((string.IsNullOrWhiteSpace(token) && string.IsNullOrWhiteSpace(innerToken)) || string.IsNullOrWhiteSpace(timeStamp) || string.IsNullOrWhiteSpace(signature))
{
_logger.LogError($"token:{token} signature:{signature}存在为空值。");
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
response.code = OperationResultType.Unauthorized;
context.Result = new JsonResult(response);
return;
}
if (!string.IsNullOrWhiteSpace(innerToken) && !innerToken.Equals(AppSettingsProvider.InnerToken))
{
_logger.LogError($"innertoken:{token}失效。");
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
response.code = OperationResultType.TokenInvalid;
context.Result = new JsonResult(response);
return;
}
#region 验证token
User user = null;
string[] tokenArr = UtilityCryptography.AESDecrypt(token, AppSettingsProvider.AuthKey).Split(',');
using (IRedisCache cache = new RedisProvider())
{
var rdskey = ConstRedisKey.AuthUser_Prev + tokenArr[0];
user = cache.StringGet<User>(rdskey);
}
if (!token.Equals(user.token))
{
_logger.LogError($"token:{token}失效。");
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
response.code = OperationResultType.TokenInvalid;
context.Result = new JsonResult(response);
return;
}
#endregion
#region 验证signature
// 验证签名
if (!DEncryptUtil.ValidateSign(Convert.ToInt64(timeStamp), AppSettingsProvider.AuthKey, null, null, signature))
{
_logger.LogError($"timeStamp:{timeStamp} signature:{signature}验证失败。");
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
response.code = OperationResultType.TokenInvalid;
context.Result = new JsonResult(response);
return;
}
#endregion
}
#endregion
}
}
}