首页 > 解决方案 > asp.net核心中的可自定义授权属性

问题描述

我在 Asp.Net Core 中使用 Jwt Token 身份验证,为了进行身份验证,我正在使用内置属性[Authorize],我想做的是使该属性可自定义,这意味着我想让该属性可配置,以启用或禁用身份验证,我可以将设置放在appsetting.json.

标签: asp.net-coreasp.net-web-api.net-core

解决方案


根据您的描述,我建议您可以尝试使用基于策略的授权来实现您的要求。

我建议您可以编写一个自定义处理程序来比较 appsetting.json 值和路由值。

如果 appsetting.json 值包含请求路由值,那么您可以返回成功以避免身份验证。

更多细节,您可以参考以下代码:

Appseting.json(DisableAuthController 值)

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "DisableAuthController": "home,default,account"
  }
}

创建一个名为:UserResourceHandler 的新类

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FormAuthCore
{
    public class UserResourceHandler : AuthorizationHandler<UserResourceRequirement>
    {

        private readonly IConfiguration Configuration;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public UserResourceHandler(IConfiguration configuration, IHttpContextAccessor httpContextAccessor)
        {
            Configuration = configuration;
            _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));


        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext authHandlerContext, UserResourceRequirement requirement)
        {

            var re = Configuration.GetSection("DisableAuthController").Value;

            var context = _httpContextAccessor.HttpContext.GetRouteData();
                var area = (context.Values["area"] as string)?.ToLower();
                var controller = (context.Values["controller"] as string)?.ToLower();
                var action = (context.Values["action"] as string)?.ToLower();

                if (re.Contains(controller))
                {
                    authHandlerContext.Succeed(requirement);
                }

        }
    }
}

创建一个 UserResourceRequirement 类

using Microsoft.AspNetCore.Authorization;

namespace FormAuthCore
{
    public class UserResourceRequirement : IAuthorizationRequirement { }   
}

将以下代码添加到 Startup.cs ConfigureServices 方法中:

      services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();

        services.AddAuthorization(options =>
        {
            options.AddPolicy("UserResource", policy => policy.Requirements.Add(new UserResourceRequirement()));
        });

        services.AddScoped<IAuthorizationHandler, UserResourceHandler>();

为控制器启用基于策略的授权:

[Authorize(Policy = "UserResource")]
public class HomeController : Controller

更新:

我在startup.cs中添加了token1 jwt token auth

            services.AddAuthentication("Token1")
                .AddJwtBearer("Token1", options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
           ValidateIssuer = true,
           ValidIssuer = "abc",
           ValidateAudience = true,
           ValidAudience = "abc",
           ValidateIssuerSigningKey = true,
           IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
       };
       options.Events = new JwtBearerEvents()
       {
           OnMessageReceived = context =>
           {
               var Token = context.Request.Headers["UserCred1"].ToString();
               context.Token = Token;
               return Task.CompletedTask;
           },
       };
   });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("UserResource", policy => policy.Requirements.Add(new UserResourceRequirement()));
            });

            services.AddScoped<IAuthorizationHandler, UserResourceHandler>();

然后我可以_httpContextAccessor.HttpContext.AuthenticateAsync("Token1").Result用来检查令牌是否有效。

  protected override async Task HandleRequirementAsync(AuthorizationHandlerContext authHandlerContext, UserResourceRequirement requirement)
    {


        var re = Configuration.GetSection("DisableAuthController").Value;

        var context = _httpContextAccessor.HttpContext.GetRouteData();
        var re2 = _httpContextAccessor.HttpContext.AuthenticateAsync("Token1").Result;

            var area = (context.Values["area"] as string)?.ToLower();
            var controller = (context.Values["controller"] as string)?.ToLower();
            var action = (context.Values["action"] as string)?.ToLower();

            if (re.Contains(controller) || re2.Succeeded)
            {
                authHandlerContext.Succeed(requirement);
            }



    }

推荐阅读