【发布时间】:2018-04-29 13:52:03
【问题描述】:
我正在从事一个非常简单的项目,该项目主要由 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,然后将其注入我的服务层,但这需要我的服务层之上的层来实现该接口。
我在这里阅读 - Placing authorization into the service layer rather than Web API layer - 创建一个授权层,但我不确定它的技术实现。
有什么想法吗?
【问题讨论】:
-
研究 IPrincipal、IIdentity 和声明。
-
我知道这些技术,我正在创建一个通用原则,问题是如何将这些信息从表示层传递到业务层
-
您可以通过方法参数或作为向下层传递的参数的属性显式传递它
-
这个问题主要是基于意见的。
-
就像我在原始问题中提到的那样,我不想将它作为参数传递。我理解它的意见,但我需要其他有经验的开发人员的意见才能得出合适的解决方案
标签: c# asp.net-web-api authorization layered