I am migrating a web API from .net Framework to .net Core. The old version was able to ignore the Authorize Attribute on the controller if the app was running on a private server. Here is the code for that. I know .net core 3.1 does not offer Custom AuthorizeAttributes. That is not my question.
// A custom AuthroizeAttribute
public class ConditionalAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext httpContext)
{
if (environment_private())
return true;
else
return base.IsAuthorized(httpContext);
}
private bool environment_private()
{
// code that will tell you if you are in your dev environment or not
return Properties.Settings.Default.PrivateServer;
}
}
// How it was called from the controller
[ConditionalAuthorize(Roles = "MyRole")]
[Route(...)]
// More code for controller
I just need a simple way to authorized all requests when running the project on our private server (which is determined by a variable in appSettings.json). I have tried policies, but I face the following difficulties:
1) I couldn't pass the variable in the configuration from the controller to a parameterized authorize attribute.
2) I couldn't inject the configuration into a parameterized authorize attribute.
This effectively eliminated my ability to follow this guide in any way: https://learn.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-2.2
This leads to my question: How can I use a value from appSettings.json to override whether the request checks a role or not?
After a lot of research, I found a way to do it using TypeFilterAttribute
. Essentially, it's the same way of doing it (using a custom attribute to filter all requests and check the condition within the custom attribute) except I used .net Core-supported methods.
In case you are trying to solve this same issue, here are the exact steps to my solution.
public class YourAttributeNameAttribute : TypeFilterAttribute
{
public YourAttributeNameAttribute(string role) : base(typeof(YourFilterNameFilter))
{
Arguments = new object[] { role };
}
}
public class YourFilterNameFilter : IAuthorizationFilter
{
private readonly string Role;
public YourFilterNameFilter(string role)
{
Role = role;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var configuration = context.HttpContext.RequestServices.GetService<IConfiguration>();
// If private server, ignore roles
if (private_server_logic_here)
return;
var user = context.HttpContext.User;
// Check role if on public server
if (!user.IsInRole(Role))
{
context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.Unauthorized);
return;
}
}
}
[YourAttributeName("role_name")]
[Route("api/my_route")]
[HttpGet]