asp.net-core - 具有 Windows 身份验证和自定义属性的 .Net Core 2.2
问题描述
我们有一个使用 Windows 和匿名身份验证的 .Net Core 2.2 WebApi。我们希望根据用户 AD 组限制对控制器/方法的访问。当我们从 Development 转到 Staging 再到 Production 时,我们不想更改 [Authorize(Roles="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
以从以下位置获取正确的AuthorizationConfigurationSection
值appsettings.json
:
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[]
来自您的属性的 action 传递:
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;
}
推荐阅读
- c++ - 带字符串的左孩子,右兄弟二叉树
- ruby-on-rails - 将具有增量 id 的现有表(包含数据)转换为 uuid?
- assembly - 如何有效地将 zmm 寄存器的低 64 位保存到内存中?
- git - how to re set up parent branch where we make new branch there
- html - 按钮不会重定向到外部页面
- json - How to convert a response from Invoke-RestMethod to JSON?
- wordpress - 通过 REST API(前端)在 Wordpress 自定义帖子类型中插入 ACF 数据
- python - 如何解决 TypeError:使用 Python 删除特定行时字符串索引必须是整数?
- python - 我不明白为什么这些变量有这些值
- jquery - Filter a list of item, Sort and Group By with jQuery