We have a .Net Core 2.2 WebApi that uses both Windows and Anonymous Authentication. We want to restrict access to controllers/methods Based on a users AD group. We do not want to have to change the [Authorize(Roles="XXX")] group when we go from Development to Staging to Production. Our solutions is to somehow bind the authorized role to the appsettings and than allow our DevOps pipeline transform as we move between environments.
We tried the following implementation: We added the keys to our appsettings.json
"Permissions": {
"Group1": {
"Admin": "Admin-Dev",
"User": "User-Dev"
},
"Group2": {
"Admin": "Admin-Dev2",
"User": "User-Dev2"
}}
We than created a class to read the section:
public class AuthorizationConfiguration
{
public string Group1 { get; set; }
public string Group2 { get; set; }
}
public class AuthorizationConfigurationSection
{
public string Admin { get; set; }
public string User { get; set; }
}
and set it in the startup.cs
services.Configure<AuthorizationConfiguration>(Configuration.GetSection("Permissions"));
Now my issue is my AuthorizationAttribute needs access to IConfig when i add the authorization attribute to my controller.
public class Authorization : AuthorizeAttribute, IAuthorizationFilter
{
private readonly AuthorizationConfiguration _permissonNames;
public Authorization(IOptions<AuthorizationConfiguration> permissonNames)
{
_permissonNames = permissonNames.Value;
}
public string[] Permissions { get; set; } //Permission string to get from controller
public void OnAuthorization(AuthorizationFilterContext context)
{
if (Permissions == null || Permissions.Length ==0)
{
context.Result = new UnauthorizedResult();
return;
}
if(Permissions.Any(perm => IsInRole(perm)))
{
return;
}
context.Result = new UnauthorizedResult();
return;
}
private bool IsInRole(string perm)
{
var groupName = GetPropertyValue(_permissonNames, perm);
return true;
}
private string GetPropertyValue(object o, string path)
{
var propertyNames = path.Split('.');
var value = o.GetType().GetProperty(propertyNames[0]).GetValue(o, null);
if (propertyNames.Length == 1 || value == null)
return value.ToString();
else
{
return GetPropertyValue(value, path.Replace(propertyNames[0] + ".", ""));
}
}
}
I cannot use the attribute without getting the error "There is no argument given that corresponds to the required formal paramater 'permissionNames' of 'Authorization.Authorization(IOptions)'
[Authorize]
[Authorization(Permissions = new string[] {AuthorizationKeys.Admin,AuthorizationKeys.Group1,
AuthorizationKeys.Group2})]
[Route("api/[controller]")]
[ApiController]