Home > Software design >  How to get connectionstring in implementing IAuthorization Filter in .Net Core MVC?
How to get connectionstring in implementing IAuthorization Filter in .Net Core MVC?

Time:09-24

I am newbie to .Net Core and I want to call my database to fetch all rights of user from database. So, while implementing IAuthorization Filter I am not able to fetch connectionstring.

Authorize Attribute:

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) { 
        
        }
    }
}

}

Controller :

[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?}");
        });
    }
}

Here I am implementing Custom Role based authorization so in authorize attirbute I want to fetch all the rights of the user and check whether user has right to access the action or not. In CustomAuthorize attribute I am not able to get connectionstring.

Tried this below code to get connectionstring but throwing error object does not contain defination for GetService.

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

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

Tried like injecting IConfiguration but I am not able place attribute on Controller because it was expecting to pass IConfiguration.

Any help will be appriciated . Thanks in Advance.

CodePudding user response:

The first way, you can use context.HttpContext.RequestServices to get the 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)
    {
    }
}

The second way, you can inject IConfiguration by constructor like below:

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)
        {
        }
    }
}

Controller:

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

Register the service:

services.AddScoped<CustomAuthorizeAttribute>();
  • Related