具有Windows身份验证和自定义属性的.Net Core 2.2



我们有一个.Net Core 2.2 WebApi,它同时使用Windows和匿名身份验证。我们希望基于用户AD组限制对控制器/方法的访问。当我们从开发到暂存再到生产时,我们不希望必须更改[授权(角色="XXX"(]组。我们的解决方案是以某种方式将授权角色绑定到应用程序设置,并允许我们在环境之间移动时进行DevOps管道转换。

我们尝试了以下实现:我们将密钥添加到了appsettings.json

"Permissions": {
"Group1": {
"Admin": "Admin-Dev",
"User": "User-Dev"
},
"Group2": {
"Admin": "Admin-Dev2",
"User": "User-Dev2"
}}

我们创建了一个类来阅读部分:

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; }
}

并将其设置在startup.cs 中

services.Configure<AuthorizationConfiguration>(Configuration.GetSection("Permissions"));

现在我的问题是,当我将授权属性添加到控制器时,我的AuthorizationAttribute需要访问IConfig。

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] + ".", ""));
}
}
}

我不能在使用该属性时不得到错误"没有给出与"Authorization。Authorization(IOptions("所需的形式参数"permissionNames"相对应的参数

[Authorize]
[Authorization(Permissions = new string[] {AuthorizationKeys.Admin,AuthorizationKeys.Group1,
AuthorizationKeys.Group2})]
[Route("api/[controller]")]
[ApiController]

您的代码中有很多问题。首先,您应该修改AuthorizationConfiguration以从appsettings.json:中获得正确的AuthorizationConfigurationSection

public class AuthorizationConfiguration
{
public AuthorizationConfigurationSection Group1 { get; set; }
public AuthorizationConfigurationSection Group2 { get; set; }

}
public class AuthorizationConfigurationSection
{
public string Admin { get; set; }
public string User { get; set; }
}

然后修改Authorization类以接受在操作上从属性传递的string[]

public Authorization(string[] values)
{
Permissions = values;
}
public Authorization() : base()
{
}

要读取AuthorizationConfiguration,您可以通过HttpContext.RequestServices within过滤器AuthorizationFilterContext:进行解析

public void OnAuthorization(AuthorizationFilterContext context)
{
var  _permissonNames = context.HttpContext.RequestServices.GetService<IOptions<AuthorizationConfiguration>>().Value;
if (Permissions == null || Permissions.Length == 0)
{
context.Result = new UnauthorizedResult();
return;
}
if (Permissions.Any(perm => IsInRole(perm, _permissonNames)))
{
return;
}
context.Result = new UnauthorizedResult();
return;
}

同时修改您的IsInRole方法:

private bool IsInRole(string perm , AuthorizationConfiguration _permissonNames)
{
var groupName = GetPropertyValue(_permissonNames, perm);
return true;
}

最新更新