0

有没有人知道将什么用作一般授权服务,并有一个工作代码示例或良好的实现步骤如何实现这样的事情。

我花了很多时间来寻找我所追求的,但还没有找到任何满意的解决方案。

IdentityServer 不是一个选项,而由于令牌的大小,我的权限不能存储为声明。它带有大约 200 个权限,因此应该在 dbcontext 或其他东西中完成。

我查看了 PolicyServer,但它没有按预期工作。当我在 IS4 应用程序中安装它时,它可以在 IS4 控制器上运行,但是当从外部应用程序调用 Authorize 时,它​​根本不会调用 Authorize 覆盖,因为它应该检查权限。而且似乎在 User.Claims 或其他任何外部应用程序中都没有设置权限。我错过了一些我认为的设置。

我想要完成的是我有一个权限存储(表)(例如包含一堆索引、添加、编辑或删除按钮等等)。应该提供给登录的经过身份验证的用户。但是这个单一的权限存储应该在我运行的所有应用程序或 API 中都可用,以便 Authorize 属性可以完成他的工作。

我认为这不应该那么难做,所以我错过了一个很好的工作示例,如何实现这样的事情以及什么是有效的。谁能帮我完成这件事?

我编写了一些代码来通过 API 调用获取权限并在 IsInRole 覆盖中使用它。但是当我使用 Authorize attr 声明它时,它不会进入方法:

[ApiController]
1) [Authorize]
public class AuthController : ControllerBase
{
private readonly IdentityContext _context;
public AuthController(IdentityContext context)
{
   _context = context ?? throw new ArgumentNullException(nameof(context));
}

[HttpGet()]
[Route("api/auth/isinrole")]
public bool IsInRole(string role)
{
2) if (User.FindFirst("sub")?.Value != null)
   {
      var userID = Guid.Parse(User.FindFirst("sub")?.Value);
      if([This is the code that checks if user has role])
         return true;
   }
   return false;

这是 IsInRole 覆盖(ClaimsPrincipal.IsInRole 覆盖):

public override bool IsInRole(string role)
{
    var httpClient = _httpClientFactory.CreateClient("AuthClient");
3)  var accessToken = _httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken).Result; 

    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    var request = new HttpRequestMessage(HttpMethod.Get, "/api/auth/isinrole/?id=" + role);
    var response = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;

etc...

  1. 当它没有在请求中发送 access_token 时,这不起作用
  2. 'sub' 未发送
  3. 始终为空
4

2 回答 2

0

您的解决方案有另一种选择,即使用引用令牌而不是 JWT 令牌。参考令牌只是一个不透明的标识符,当客户端收到这个令牌时,他已经通过后端去查找真正的令牌和详细信息。参考令牌不包含任何信息。它只是客户端可以针对 IdentiyServer 使用的查找标识符

通过使用它,您的令牌将非常小。

使用参考令牌只是您可用的一种选择。

请参阅有关参考令牌的文档

于 2020-08-08T07:59:18.317 回答
0

PolicyServer 的开源版本是本地实现。它所做的只是从存储中读取权限(在示例中为配置文件)并使用中间件将它们转换为声明。

为了使用权限,您必须在要使用权限的所有项目中添加此中间件。

拥有本地权限,就不能与其他资源发生冲突。例如,成为 api1 的管理员并不意味着您也是 api2 的管理员。

但是去中心化的权限可能很难维护。这就是为什么您可能需要一个中央服务器来获取权限,其中存储实际上调用策略服务器而不是从本地配置文件中读取权限。

为此,您需要添加一个鉴别器以区分资源。我使用scopes,因为这是客户端和资源共享的一件事。

它还使响应保持较小,您只需请求特定范围的权限而不是所有权限。

另一种方法是按原样使用 IdentityServer。但不是 JWT 令牌使用引用令牌

随机字符串要短得多,但需要客户端和/或资源通过将引用令牌发送到 IdentityServer 来请求权限。这可能接近 PolicyServer 的工作方式,但对响应的控制较少。

于 2020-08-08T09:22:54.880 回答