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>();