如何在 .Net Core MVC 中实现 IAuthorization Filter 时获取连接字符串?

How to get connectionstring in implementing IAuthorization Filter in .Net Core MVC?

我是 .Net Core 的新手,我想调用我的数据库以从数据库中获取用户的所有权限。因此,在实施 IAuthorization 过滤器时,我无法获取连接字符串。

授权属性:

using Demo.Respositories;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace Demo.Web.Providers
{
 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        try
        {
            if (context.HttpContext.User.Identity.IsAuthenticated)
            {
                var requiredRights = String.Format("{0}-{1}", context.HttpContext.Request.RouteValues["controller"].ToString(), context.HttpContext.Request.RouteValues["action"].ToString());
                var userName = context.HttpContext.User.Identity.Name;
                if (!String.IsNullOrEmpty(userName))
                {
                    
                    var config = context.HttpContext.RequestServices.GetSection<IConfiguration>();
            //Error object does not have defination for GetSection
            string connectionString = config.GetSection("ConnectionStrings:DefaultConnection").Value;
                    
                    var rights = AuthHelper.GetUserRightsByUserName(userName, connectionString);

                    if (!rights.Contains(requiredRights.ToLower()))
                    {
                        context.Result = new RedirectResult("~/account/unauthorized");
                    }
                }
            }
            else
            {
                context.Result = new RedirectResult("~/account/login");
            }
        }
        catch (Exception ex) { 
        
        }
    }
}

}

控制器:

[CustomAuthorize]
public class UserController : Controller
{
}

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(o => o.LoginPath = new PathString("/Account/Login")); ;
        services.AddControllersWithViews().AddRazorRuntimeCompilation(); 
        services.AddOptions();
        services.Configure<DataConnection>(Configuration.GetSection("ConnectionStrings"));
        services.AddRepositoryDependency();
        services.AddServiceDependency();
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        
        services.AddMvc().AddNToastNotifyToastr(new ToastrOptions()
        {
            ProgressBar = false,
            PositionClass = ToastPositions.TopRight
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
        app.UseNToastNotify();
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        //app.UseMiddleware<CustomAuthorizeAttribute>();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

我在这里实现了基于自定义角色的授权,所以在授权属性中我想获取用户的所有权限并检查用户是否有权访问该操作。在 CustomAuthorize 属性中,我无法获取连接字符串。

尝试了以下代码来获取连接字符串,但抛出的错误对象不包含 GetService 的定义。

var configuration = context.HttpContext.RequestServices.GetService(typeof(IConfiguration)); 

 var  connectionstring = configuration.GetService("Connectionstrings:DefaultConnection").Value;

尝试注入 IConfiguration,但我无法在 Controller 上放置属性,因为它期望通过 IConfiguration。

我们将不胜感激任何帮助。提前致谢。

第一种方式,可以用context.HttpContext.RequestServices得到IConfiguration:

using Microsoft.Extensions.DependencyInjection; //be sure add this reference...

public void OnAuthorization(AuthorizationFilterContext context)
{            
    try
    {
        if (context.HttpContext.User.Identity.IsAuthenticated)
        {
            var requiredRights = String.Format("{0}-{1}", context.HttpContext.Request.RouteValues["controller"].ToString(), context.HttpContext.Request.RouteValues["action"].ToString());
            var userName = context.HttpContext.User.Identity.Name;
            if (!String.IsNullOrEmpty(userName))
            {
                var config = context.HttpContext.RequestServices.GetService<IConfiguration>();
                string connectionString = config.GetSection("ConnectionStrings:DefaultConnection").Value;
                //....
            }
        }
        else
        {
            context.Result = new RedirectResult("~/account/login");
        }
    }
    catch (Exception ex)
    {
    }
}

第二种方式,你可以通过构造函数注入IConfiguration,如下所示:

public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter
{
    private readonly string connectionString;

    public CustomAuthorizeAttribute(IConfiguration configuration)
    {
        this.connectionString = configuration
                   .GetSection("ConnectionStrings:DefaultConnection").Value;
    }
    public void OnAuthorization(AuthorizationFilterContext context)
    {          
        try
        {
            if (context.HttpContext.User.Identity.IsAuthenticated)
            {
                var requiredRights = String.Format("{0}-{1}", context.HttpContext.Request.RouteValues["controller"].ToString(), context.HttpContext.Request.RouteValues["action"].ToString());
                var userName = context.HttpContext.User.Identity.Name;
                if (!String.IsNullOrEmpty(userName))
                {
                    //....
                }
            }
            else
            {
                context.Result = new RedirectResult("~/account/login");
            }
        }
        catch (Exception ex)
        {
        }
    }
}

控制器:

[ServiceFilter(typeof(CustomAuthorizeAttribute))]
public class UserController : Controller
{
}

注册服务:

services.AddScoped<CustomAuthorizeAttribute>();