2

在 .NET WebAPI 中,我创建了一种将所有授权规则放在一个中央位置的方法,而不是分散在各个控制器中。我很好奇为什么不经常进行这种集中化;是否有影响/安全问题?

我目前的方法是在 App_Start 期间创建一个字典,其中包含我的所有授权数据,然后使用 DelegatingHandler 来应用限制(下面的代码)。字典键是Controller和Action的元组,值是授权角色。DelegatingHandler 绑定到 WebAPI 的路由配置以获取调用哪个控制器,然后使用 Dictionary 来确定是否允许请求。

字典:

var authorizations = new Dictionary<Tuple<string, string>, string>();
authorizations.Add(new Tuple<string, string>("values", "get"), "public");
authorizations.Add(new Tuple<string, string>("values", "put"), "private");

委托处理程序:

public class SecurityDelegateHandler : DelegatingHandler
{
    private readonly Dictionary<Tuple<string, string>, string> _authorizations;

    public SecurityDelegateHandler(Dictionary<Tuple<string, string>, string> auth)
    {
        _authorizations = auth;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var config = GlobalConfiguration.Configuration;
        var controllerSelector = new DefaultHttpControllerSelector(config);
        var descriptor = controllerSelector.SelectController(request);

        string restrictions;

        if (!_authorizations.TryGetValue(
                new Tuple<string, string>(descriptor.ControllerName.ToLower(),
                request.Method.ToString().ToLower()), out restrictions))
        {
            return Task<HttpResponseMessage>.Factory.StartNew(() =>
                        request.CreateResponse(HttpStatusCode.Forbidden, 
                        "Access denied on unconfigured actions"), 
                        cancellationToken);
        }

        if (!(Roles.Provider).GetRolesForUser(
               HttpContext.Current.User.Identity.Name).Any(r => 
               restrictions.Contains(r)))
        {
            return Task<HttpResponseMessage>.Factory.StartNew(() => 
                        request.CreateResponse(HttpStatusCode.Forbidden, 
                        "Access Denied"), cancellationToken);
        }

        return base.SendAsync(request, cancellationToken);
    }
}

总之,我的问题是:

  • 以这种方式实施基于角色的授权有什么问题吗?
  • 有没有什么好的包可以处理 WebAPI 的集中授权?我调查了 FluentSecurity,但似乎不支持 WebAPI

谢谢!

4

1 回答 1

2

你的方法很好。你应该分开关注点。这意味着将业务逻辑与非功能性逻辑/需求(例如日志记录、身份验证,当然还有授权)分开。

之所以没有更广泛地这样做是因为外部化身份验证或日志记录比外部化与您的业务更相关的授权要容易得多。

如今,不同的编程框架提供了外部化授权。Microsoft 有基于声明的授权,Java 有多个框架,例如 Spring Security、SunXACML……PHP 有 Yii,Ruby 有 CanCan……这些框架让您可以实现基于角色的访问控制,甚至是基于属性的访问控制。如果您不熟悉这些术语,请查看 NIST 的网页:

如果您想要一个技术中立的解决方案,即可以用于 Java、.NET、PHP 的解决方案……您可以使用 XACML,即可扩展访问控制标记语言。它是一个 OASIS 标准,就像 SAML 一样(SAML 专注于联合身份和 SSO;XACML 专注于细粒度授权)。您可以在OASIS网站和我尝试维护该页面的Wikipedia上阅读更多关于 XACML 的信息。除了外部化授权之外,XACML 还定义了一种基于策略的授权方法,这是一种非常可扩展的方法。

XACML 有几个开源选项(JBoss、SunXACML、OpenAM...)以及供应商,例如我工作的Axiomatics

高温高压

于 2013-10-23T14:47:26.433 回答