简体   繁体   English

分层应用程序中的授权

[英]Authorization in a layered application

I am working on a pretty simple project that is mostly made up of getters and searches and access to certain data is limited depending on the user. 我正在做一个非常简单的项目,该项目主要由吸气剂组成,搜索和对某些数据的访问受到用户的限制。 I want to use this opportunity to do some best practices when it comes to security, authorization in this case. 在这种情况下,我想借此机会在安全性和授权方面做一些最佳实践。

The application is activated once at which time a token is generated and used for future requests. 一次激活该应用程序,这时将生成令牌并将其用于将来的请求。

My application has a web api for the endpoint which sits on top of a set of services which sits on top a set of repo's which sits on top of a sql server db. 我的应用程序具有用于端点的Web api,该api位于一组服务的顶部,而该服务位于一组repo的顶部,而这些repo则位于sql server db的顶部。 All the controllers do is forward the request down to the service layer. 控制器要做的就是将请求向下转发到服务层。

Here is an example controller: 这是一个示例控制器:

[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);
    }
}

My custom authorization attribute checks the token and if valid pulls the user details out from the token and creates a generic principle which is then available in my controllers. 我的自定义授权属性会检查令牌,如果有效,则会从令牌中拉出用户详细信息,并创建通用原则,然后该通用原则可在我的控制器中使用。

To me the web api is just a way to expose my business\\service layer and authorization should be done lower down in my service layer but I can't think of a clean way to get that information down to that layer. 对我来说,Web api只是公开我的业务\\服务层的一种方法,应该在服务层的较低层进行授权,但是我无法想到一种将信息收集到该层的干净方法。 In the above example, the service layer will need to check if the user (from the token) has access to that particular branch which means the service layer will need to know who is making the request. 在上面的示例中,服务层将需要检查用户(从令牌中)是否有权访问该特定分支,这意味着服务层将需要知道谁在发出请求。 The two solutions I can think of is: 我能想到的两个解决方案是:

1) I am using a request\\response pattern for my service layer so I could create an abstract base class called 'Request' as an example which could store all the user details and each request object to the service layer could inherit from this therefore providing user details to my service layer. 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) To define an interface, for example ISecurity, which is then injected into my service layer but this would require the layers above my service layer to implement the interface. 2)要定义一个接口,例如ISecurity,然后将其注入到我的服务层中,但这将需要服务层之上的各层来实现该接口。

I read here - Placing authorization into the service layer rather than Web API layer - to create an authorization layer but I am not sure of the technical implementation of this. 我在这里读到了- 将授权放置在服务层而不是Web API层中 ,以创建一个授权层,但是我不确定这在技术上是否实现。

Any ideas? 有任何想法吗?

What you are looking for is fine-grained, externalized authorization: 您正在寻找的是细粒度的外部授权:

  • fine-grained: you want to create authorization policies that take into account multiple parameters or attributes and possibly relationships between the client (the requestor) and the targeted entity eg a listing in your case. 细粒度:您要创建授权策略,其中要考虑多个参数或属性以及客户端(请求者)和目标实体之间的关系,例如您的案例中的列表。
  • externalized: you want to decouple the business logic from the authorization logic. 外部化:您希望将业务逻辑与授权逻辑分离。 In your question you complain about how complex the code and the SQL statements are becoming. 在您的问题中,您抱怨代码和SQL语句变得越来越复杂。 This is a direct consequence of not clearly separating business logic from authorization logic. 这是未将业务逻辑与授权逻辑明确分开的直接结果。

There is a model called attribute-based access control (ABAC) that defines an approach to fine-grained externalized authorization. 有一个称为基于属性的访问控制(ABAC)的模型,该模型定义了一种用于细化外部授权的方法。 NIST, the National Institute of Standards and Technology, has produced a report on ABAC which you can read online. 美国国家标准与技术研究院NIST已发布了一份关于ABAC报告 ,您可以在线阅读该报告

OASIS, the organization for the advancement of structured information standards, has defined a standard called XACML (eXtensible Access Control Markup Language) to implement ABAC. OASIS是促进结构化信息标准的组织,已经定义了一个称为XACML (可扩展访问控制标记语言)的标准来实现ABAC。

XACML brings you: XACML为您带来:

  • an architecture as illustrated below 如下所示的架构
    • The policy enforcement point (PEP) intercepts your API calls. 策略执行点(PEP)拦截您的API调用。 It protects your API, inspects the messages and sends an authorization request to the policy decision point (PDP). 它可以保护您的API,检查消息并将授权请求发送到策略决策点(PDP)。
    • The policy decision point (PDP) evaluates incoming authorization requests from the PEP against a set of authorization policies written in XACML. 策略决策点(PDP)根据XACML编写的一组授权策略评估来自PEP的传入授权请求。 The PDP eventually reaches a Permit or Deny decision. PDP最终会做出“允许”或“拒绝”决定。 To reach decisions it may need to look up additional attribute values from databases, web services, LDAP, or files. 为了做出决定,可能需要从数据库,Web服务,LDAP或文件中查找其他属性值。 These are called policy information points in the architecture. 这些在体系结构中称为策略信息点。 XACML架构流程
  • a policy language: the XACML policy language is attribute-based which means it uses attributes to define what can be allowed and what is not. 一种策略语言:XACML策略语言是基于属性的,这意味着它使用属性来定义允许的内容和不允许的内容。 For instance, you could define rules such as: 例如,您可以定义规则,例如:
    • a real estate agent can see all the listings if and only if the listing location == the agent location 当且仅当房源位置==代理商位置时,房地产经纪人才能查看所有列表
    • a real estate agent can edit a listing if and only if he/she owns the listing 房地产经纪人只有在拥有该房源的情况下,才能编辑该房源
    • a real estate agent can close a listing if and only if the listing's item is sold and if and only if the agent is the person that sold the item. 当且仅当售出该物品的物品并且仅当该代理商是出售物品的人时,房地产经纪人才能关闭该物品。
  • a request/response scheme: XACML also defines a way to query the PDP and to get responses back. 请求/响应方案:XACML还定义了一种查询PDP并获取响应的方法。 A PDP can be queried either via single questions or via multiple questions in a single request eg: 可以通过单个问题或单个请求中的多个问题来查询PDP,例如:
    • Can Alice view listing 123? 爱丽丝可以查看列表123吗? Yes, permit. 是的,请允许。
    • Can Alice view, edit, or delete listing 123? 爱丽丝可以查看,编辑或删除列表123吗? Permit; 允许; Deny; 拒绝; Deny. 拒绝。

With a XACML-based approach, you get to maintain your business logic and your API separate from the authorization logic. 使用基于XACML的方法,您可以将业务逻辑和API与授权逻辑分开维护。 This has several benefits: 这有几个好处:

  1. you can always reimplement the API and keep the same authorization model 您可以随时重新实现API并保留相同的授权模型
  2. you can easily expand your API without having to rewrite the authorization 您可以轻松扩展您的API,而无需重写授权
  3. you can change your authorization logic independently of your code 您可以独立于代码来更改授权逻辑
  4. you can audit your authorization logic more easily 您可以更轻松地审核授权逻辑
  5. your authorization logic is technology-neutral. 您的授权逻辑与技术无关。 It works for REST APIs, web services, databases, and more 它适用于REST API,Web服务,数据库等

I recommend you check out the following resources: 我建议您检查以下资源:

  1. the OASIS XACML website OASIS XACML网站
  2. the ALFA plugin for Eclipse - a free tool to write XACML policies. EclipseALFA插件 -编写XACML策略的免费工具。
  3. The XACML developer community XACML开发人员社区

There are both vendor and open-source implementations of XACML: XACML既有供应商也有开源实现:

  • Axiomatics is a vendor solution that provides both .NET and Java XACML implementations 公理学是一种提供.NET和Java XACML实现的供应商解决方案
  • SunXACML is a long-standing open source Java XACML implementation SunXACML是一个长期的开源Java XACML实现。

HTH, David. 戴维

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM