1
llj
2 天以前 599aeb0d380f9b194e1dc363364779f3b498969e
WebAPI/Service/JwtAuthorizeAttribute.cs
@@ -1,9 +1,12 @@
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;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
@@ -31,7 +34,7 @@
    {
        try
        {
            // 检查匿名访问
            // 检查匿名访问(认证)
            if (IsAnonymousAllowed(actionContext)) return;
            // 获取Token
@@ -51,12 +54,77 @@
                return;
            }
            // 验证是否拥有访问模块的权限
            // 有两种判断方式 一种是通过角色去判断,一种是通过用户去判断 目前暂时不做区分,后续可增加系统参数来进行区分
            // 检查 Token和当前登录用户是否匹配
            var HUserName = GetUserNameFromHeader(actionContext) ?? "";
            var TokenUserName = JWTHelper.getUserName(token);
            if(!string.IsNullOrWhiteSpace(HUserName))
            {
                HUserName = HttpUtility.UrlDecode(HUserName);
            }
            if(TokenUserName != HUserName)
            {
                // 如果Token和当前登录用户不匹配,则需要告知前端用户 Token 过期,需重新登录
                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)
        {
@@ -93,6 +161,19 @@
        return null;
    }
    // 从Header中获取用户名
    private string GetUserNameFromHeader(HttpActionContext context)
    {
        var headers = context.Request.Headers;
        string userName = "";
        if (headers.Contains("X-Username"))
        {
            userName = headers.GetValues("X-Username").FirstOrDefault();
        }
        return userName;
    }
    // 401 未授权
    private void HandleUnauthorized(HttpActionContext context)
    {
@@ -111,7 +192,7 @@
        var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
        objjson.code = "0";
        objjson.count = 0;
        objjson.Message = "当前角色无权限";
        objjson.Message = "您没有该模块权限,请与管理员联系!";
        response.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(objjson),
            System.Text.Encoding.UTF8, "application/json");
        context.Response = response;