【问题标题】:.Net Core 2.2 with Windows Authentication and Custom Attribute具有 Windows 身份验证和自定义属性的 .Net Core 2.2
【发布时间】:2020-03-14 14:01:53
【问题描述】:

我们有一个使用 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]

【问题讨论】:

    标签: asp.net-core active-directory windows-authentication


    【解决方案1】:

    您的代码中有很多问题。首先,您应该修改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;
    }
    

    【讨论】:

    • 感谢您的帮助。我唯一的问题是现在身份是作为 ClaimsPrincipal 而不是 WindowsPrincipal,因此 User.IsInRole 总是错误的。
    • 参见 this ,使用 IClaimsTransformation 将自定义声明添加到 ClaimsPrincipal
    猜你喜欢
    • 1970-01-01
    • 2021-05-20
    • 2011-06-23
    • 2019-11-28
    • 2020-01-06
    • 2019-12-24
    • 2018-09-26
    • 2018-06-22
    • 1970-01-01
    相关资源
    最近更新 更多