我正在开发一个非常简单的项目,主要由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 - 创建授权层,但我不确定技术实现。
有什么想法吗?
答案 0 :(得分:1)
您正在寻找的是细粒度的外部授权:
有一种称为基于属性的访问控制(ABAC)的模型,它定义了细粒度外部化授权的方法。美国国家标准与技术研究院(NIST)已经制作了report on ABAC,您可以在线阅读。
OASIS是推进结构化信息标准的组织,它定义了一个名为XACML(可扩展访问控制标记语言)的标准来实施ABAC。
XACML为您带来:
使用基于XACML的方法,您可以将业务逻辑和API与授权逻辑分开。这有几个好处:
我建议您查看以下资源:
XACML有供应商和开源实现:
HTH, 大卫。