using System;
|
using System.Linq;
|
using System.Net;
|
using System.Net.Http;
|
using System.Reflection;
|
using System.Security.Claims;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using System.Web.Http;
|
using System.Web.Http.Controllers;
|
using System.Web.Http.Filters;
|
using WebAPI.Models;
|
using WebAPI.Utility;
|
|
public class JwtAuthorizeAttribute : AuthorizationFilterAttribute
|
{
|
private json objjson = new json();
|
private SQLHelper.ClsCN oCN = new SQLHelper.ClsCN();
|
private Pub_Class.ClsXt_SystemParameter oSystemParameter = new Pub_Class.ClsXt_SystemParameter();
|
private string campanyName = "";
|
|
public JwtAuthorizeAttribute()
|
{
|
if (oSystemParameter.ShowBill(ref DBUtility.ClsPub.sErrInfo))
|
{
|
campanyName = oSystemParameter.omodel.WMS_CampanyName;
|
}
|
}
|
|
|
// 同步鉴权
|
public override void OnAuthorization(HttpActionContext actionContext)
|
{
|
try
|
{
|
// 检查匿名访问(认证)
|
if (IsAnonymousAllowed(actionContext)) return;
|
|
// 获取Token
|
var token = GetTokenFromHeader(actionContext);
|
if (string.IsNullOrEmpty(token))
|
{
|
HandleUnauthorized(actionContext);
|
return;
|
}
|
|
// 验证Token
|
// 可以增加更细粒度的控制,添加 根据组织ID 判断(问题: 公司名不能使用中文,可能需要添加英文字段)
|
var principal = JWTHelper.ValidateToken(token);
|
if (principal == null)
|
{
|
HandleUnauthorized(actionContext);
|
return;
|
}
|
|
// 设置用户
|
actionContext.RequestContext.Principal = principal;
|
|
// 验证是否拥有访问模块的权限
|
// 有两种判断方式 一种是通过角色去判断,一种是通过用户去判断 目前暂时不做区分,后续可增加系统参数来进行区分
|
// 安全控制器描标签
|
var controllerAttr = actionContext.ControllerContext?.ControllerDescriptor?.GetCustomAttributes<PermissionAttribute>().FirstOrDefault();
|
|
// 安全获取Action标签
|
var actionAttr = actionContext.ActionDescriptor?.GetCustomAttributes<PermissionAttribute>().FirstOrDefault();
|
|
string PermissionStr = string.Empty;
|
// 判断控制器级别上是否启用了鉴权标签
|
if(controllerAttr != null && !string.IsNullOrWhiteSpace(controllerAttr?.HModName))
|
{
|
PermissionStr += controllerAttr.HModName;
|
|
// 查看是否需要更细粒度的控制
|
if(actionAttr != null && !string.IsNullOrWhiteSpace(actionAttr?.Operate))
|
{
|
// 该动作对应的模块名和控制器名是否不一致
|
if (string.IsNullOrWhiteSpace(actionAttr.HModName))
|
{
|
PermissionStr = actionAttr.HModName + actionAttr.Operate;
|
}
|
else
|
{
|
PermissionStr += actionAttr.Operate;
|
}
|
|
}
|
|
if(!string.IsNullOrWhiteSpace(PermissionStr))
|
{
|
if (!DBUtility.ClsPub.Security_Log(PermissionStr, 1, false, JWTHelper.getUserName(token)))
|
{
|
HandleForbidden(actionContext);
|
return;
|
}
|
}
|
|
}else if (actionAttr != null && !string.IsNullOrWhiteSpace(actionAttr?.HModName) && !string.IsNullOrWhiteSpace(actionAttr?.Operate))
|
{
|
// 单独在动作上启用鉴权功能
|
PermissionStr = actionAttr.HModName + actionAttr.Operate;
|
|
if (!string.IsNullOrWhiteSpace(PermissionStr))
|
{
|
if (!DBUtility.ClsPub.Security_Log(PermissionStr, 1, false, JWTHelper.getUserName(token)))
|
{
|
HandleForbidden(actionContext);
|
return;
|
}
|
}
|
}
|
|
|
}
|
catch (Exception e)
|
{
|
HandleError(actionContext, e.Message);
|
}
|
}
|
|
// 异步鉴权
|
public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
|
{
|
OnAuthorization(actionContext);
|
|
return Task.FromResult(0);
|
}
|
|
// 是否允许匿名访问(控制器级别和动作级别都可用)
|
private bool IsAnonymousAllowed(HttpActionContext context)
|
{
|
return
|
context.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0 ||
|
context.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0;
|
}
|
|
// 从Header提取Token
|
private string GetTokenFromHeader(HttpActionContext context)
|
{
|
var authHeader = context.Request.Headers.Authorization;
|
if (authHeader != null
|
&& authHeader.Scheme.Equals("Bearer", StringComparison.OrdinalIgnoreCase)
|
&& !string.IsNullOrEmpty(authHeader.Parameter))
|
{
|
return authHeader.Parameter;
|
}
|
return null;
|
}
|
|
// 401 未授权
|
private void HandleUnauthorized(HttpActionContext context)
|
{
|
var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
objjson.code = "0";
|
objjson.count = 0;
|
objjson.Message = "未授权,请登录后重试";
|
response.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(objjson),
|
System.Text.Encoding.UTF8, "application/json");
|
context.Response = response;
|
}
|
|
// 403 无权限
|
private void HandleForbidden(HttpActionContext context)
|
{
|
var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
|
objjson.code = "0";
|
objjson.count = 0;
|
objjson.Message = "您没有该模块权限,请与管理员联系!";
|
response.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(objjson),
|
System.Text.Encoding.UTF8, "application/json");
|
context.Response = response;
|
}
|
|
private void HandleError(HttpActionContext context, string ErrorInfo)
|
{
|
var response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
|
objjson.code = "0";
|
objjson.count = 0;
|
objjson.Message = "服务器异常: " + ErrorInfo;
|
response.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(objjson),
|
System.Text.Encoding.UTF8, "application/json");
|
context.Response = response;
|
}
|
}
|