分层应用程序中的授权

时间:2017-11-16 05:59:53

标签: c# asp.net-web-api authorization layered

我正在开发一个非常简单的项目,主要由getter和搜索组成,并且根据用户的不同,对某些数据的访问受到限制。在这种情况下,我想利用这个机会做一些关于安全性,授权的最佳实践。

应用程序激活一次,此时生成令牌并用于将来的请求。

我的应用程序有一个针对端点的web api,它位于一组服务之上,这些服务位于一组位于sql server db之上的repo。所有控制器都将请求转发到服务层。

以下是一个示例控制器:

[ApiAuthorize]
[RoutePrefix("api/Catalogue")]
public class CatalogueController : ApiController
{
    private ICatalogueService _catalogueService;
    public CatalogueController(ICatalogueService catalogueService)
    {
        _catalogueService = catalogueService;
    }

    [HttpGet]
    [Route("GetCatalogues")]
    public IHttpActionResult GetCatalogues(string branchEan)
    {
        var catalogues = _catalogueService.GetCatalogues(new GetCataloguesRequest()
        {
            BranchEan = branchEan
        });

        return Ok(catalogues);
    }
}

我的自定义授权属性检查令牌,如果有效则从令牌中提取用户详细信息并创建一个通用原则,然后在我的控制器中可用。

对我来说,web api只是一种暴露我的业务\服务层的方式,授权应该在我的服务层中完成,但是我不能想到一种干净的方法来将这些信息传递到该层。在上面的示例中,服务层将需要检查用户(来自令牌)是否可以访问该特定分支,这意味着服务层将需要知道谁在发出请求。我能想到的两个解决方案是:

1)我正在为我的服务层使用请求\响应模式,因此我可以创建一个名为' Request'的抽象基类。作为一个可以存储所有用户详细信息的示例,每个请求对象都可以从服务层继承,从而为我的服务层提供用户详细信息。

public abstract class Request
{
    public Request(string username)
    {
        this.Username = username;
    }

    public string Username { get; private set; }
}

public class GetCataloguesRequest : Request
{
    public GetCataloguesRequest(string username) : base(username)
    {
    }
}

2)定义一个接口,例如ISecurity,然后将其注入我的服务层,但这需要我的服务层上方的层实现接口。

我在这里阅读 - Placing authorization into the service layer rather than Web API layer - 创建授权层,但我不确定技术实现。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您正在寻找的是细粒度的外部授权:

  • 细粒度:您希望创建授权策略,该策略考虑多个参数或属性以及可能的客户端(请求者)与目标实体之间的关系,例如在你的情况下列出。
  • externalized:您希望将业务逻辑与授权逻辑分离。在你的问题中,你抱怨代码和SQL语句变得多么复杂。这是未明确将业务逻辑与授权逻辑分离的直接后果。

有一种称为基于属性的访问控制(ABAC)的模型,它定义了细粒度外部化授权的方法。美国国家标准与技术研究院(NIST)已经制作了report on ABAC,您可以在线阅读。

OASIS是推进结构化信息标准的组织,它定义了一个名为XACML(可扩展访问控制标记语言)的标准来实施ABAC。

XACML为您带来:

  • 如下图所示的架构
    • 策略执行点(PEP)拦截您的API调用。它保护您的API,检查消息并向策略决策点(PDP)发送授权请求。
    • 策略决策点(PDP)根据用XACML编写的一组授权策略评估来自PEP的传入授权请求。 PDP最终达成许可或拒绝决定。要做出决策,可能需要从数据库,Web服务,LDAP或文件中查找其他属性值。这些在架构中称为策略信息点。 XACML Architecture Flow
  • 策略语言:XACML策略语言是基于属性的,这意味着它使用属性来定义可以允许的内容和不允许的内容。例如,您可以定义以下规则:
    • 当且仅当列表位置==代理商位置
    • 时,房地产经纪人才能看到所有列表
    • 当且仅当他/她拥有列表时,房地产经纪人才能编辑列表
    • 当且仅当列出的商品被出售时,且当且仅当代理商是出售商品的人时,房地产经纪人才能关闭商品。
  • 请求/响应方案:XACML还定义了一种查询PDP并获取响应的方法。可以通过单个问题或通过单个请求中的多个问题来查询PDP,例如:
    • Alice可以查看列表123吗?是的,许可。
    • Alice可以查看,编辑或删除列表123吗?允许;拒绝;拒绝。

使用基于XACML的方法,您可以将业务逻辑和API与授权逻辑分开。这有几个好处:

  1. 您始终可以重新实施API并保持相同的授权模式
  2. 您无需重写授权即可轻松扩展API
  3. 您可以独立于代码更改授权逻辑
  4. 您可以更轻松地审核授权逻辑
  5. 您的授权逻辑是技术中立的。它适用于REST API,Web服务,数据库等
  6. 我建议您查看以下资源:

    1. OASIS XACML website
    2. ALFA plugin for Eclipse - 一个编写XACML策略的免费工具。
    3. XACML developer community
    4. XACML有供应商和开源实现:

      • Axiomatics是一种提供.NET和Java XACML实现的供应商解决方案
      • SunXACML是一个长期的开源Java XACML实现

      HTH, 大卫。