1

我正在研究一个非常简单的项目,该项目主要由 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)我正在为我的服务层使用请求\响应模式,因此我可以创建一个名为“请求”的抽象基类作为示例,它可以存储所有用户详细信息,并且服务层的每个请求对象都可以从该类继承,因此提供用户详细信息到我的服务层。

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,然后将其注入我的服务层,但这需要我的服务层之上的层来实现接口。

我在这里读到 -将授权放入服务层而不是 Web API 层 - 以创建授权层,但我不确定它的技术实现。

有任何想法吗?

4

1 回答 1

2

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

  • 细粒度:您希望创建考虑到多个参数或属性以及客户(请求者)和目标实体之间可能的关系的授权策略,例如您的案例中的列表。
  • 外部化:您希望将业务逻辑与授权逻辑解耦。在您的问题中,您抱怨代码和 SQL 语句变得多么复杂。这是没有明确区分业务逻辑和授权逻辑的直接后果。

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

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

XACML 为您带来:

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

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

  1. 您始终可以重新实现 API 并保持相同的授权模型
  2. 您可以轻松扩展您的 API,而无需重写授权
  3. 您可以独立于您的代码更改您的授权逻辑
  4. 您可以更轻松地审核您的授权逻辑
  5. 您的授权逻辑是技术中立的。它适用于 REST API、Web 服务、数据库等

我建议您查看以下资源:

  1. OASIS XACML 网站
  2. Eclipse的ALFA 插件- 编写 XACML 策略的免费工具。
  3. XACML 开发者社区

XACML 有供应商和开源实现:

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

HTH,大卫。

于 2017-11-21T21:05:16.813 回答