Authentication 我们能否将identity Server 4中的用户限制为特定的应用程序?

Authentication 我们能否将identity Server 4中的用户限制为特定的应用程序?,authentication,identity,identityserver4,Authentication,Identity,Identityserver4,我正在尝试为企业场景实现IdentityServer 4 我知道用户是根据Identity server注册的 我的问题是如何授予用户对应用程序的权限,就像用户需要分配给特定的应用程序一样,如果未分配,应用程序应该返回未经授权的 如果用户需要访问多个应用程序,则需要多个分配 我正在寻找一种方法,让Identity server在用户无法一次性访问应用程序时使提交的令牌无效,即使被质询的令牌可能是由用户有权访问的其他应用程序提交的有效令牌。对于用户,Identity server仅是身份验证。授权

我正在尝试为企业场景实现IdentityServer 4

我知道用户是根据Identity server注册的

我的问题是如何授予用户对应用程序的权限,就像用户需要分配给特定的应用程序一样,如果未分配,应用程序应该返回未经授权的

如果用户需要访问多个应用程序,则需要多个分配


我正在寻找一种方法,让Identity server在用户无法一次性访问应用程序时使提交的令牌无效,即使被质询的令牌可能是由用户有权访问的其他应用程序提交的有效令牌。对于用户,Identity server仅是身份验证。授权应由您的应用程序处理

身份验证=验证用户是谁

授权=验证用户可以做什么

更新
我写了一篇关于这个主题的文章,以澄清OAuth2.0如何不是用户级授权。希望有帮助

正如Scott所说,Identity Server将验证用户是他们所说的人,而不是明确告诉您该用户可以做什么

您可以使用作为身份验证的一部分返回的声明,然后在应用程序内执行授权检查。例如,您可以使用
sub
id
声明从应用程序中检查与该sub/id关联的用户是否允许访问特定资源


当您将
角色
声明带入图片时,情况会变得更糟,但只要您了解身份验证和授权之间的区别,您就应该可以了。

Identity Server绝对可以在最基本的级别上处理授权。它创建在应用程序授权中必不可少的授权代码和访问令牌。没有他们,你就不能得到授权。因此,对于其他人来说,声称Identity Server不进行授权是完全错误的

一周前,我来到这里,寻找解决同样问题的方法。如果用户不能满足某些参数(在我的例子中是UserClient表),我希望通过不授予他们访问令牌来限制用户对特定应用程序的访问。幸运的是,我有一个解决办法。Identity Server 4实现了一些在授权或令牌创建时发生的CustomValidator,他们称之为CustomValidator。是的

   internal class DefaultCustomAuthorizeRequestValidator : ICustomAuthorizeRequestValidator
   internal class DefaultCustomTokenRequestValidator : ICustomTokenRequestValidator
   public class DefaultCustomTokenValidator : ICustomTokenValidator
当他们接到电话时,他们的名字真的说明了这一点。每一个都包含一个方法

   public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)
   { 
        return Task.CompletedTask;
   }
注意到什么了吗?没错!它什么也不做。几乎就好像他们注定要被取代。(是的)

这是您可以添加自定义逻辑以拒绝请求的区域。CustomAuthorizationRequestValidationContext包含ClientId和用户声明信息。它还包含一个名为IsError的布尔值。只需将其设置为true和whamy!访问被拒绝。您还可以设置错误消息等。下面是一个实现ICustomAuthorizerRequestValidator inface的示例,它将根据用户Id限制用户

  public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)
    {
        var sub = context.Result.ValidatedRequest.Subject.FindFirst("sub");
        if (sub != null && sub.Value != "88421113")
        {
            context.Result.IsError = true;
            context.Result.Error = "Unauthorized";
            context.Result.ErrorDescription = "You are not authorized for this client";
        }

        return Task.CompletedTask;
    }
可以随意插入一两个dbcontext来读取userclient表。我将子声明检查为null,因为在实际登录发生之前,它会被命中好几次

从我所注意到的情况来看,这三种行为在使用上相似,但在结果上不同。设置错误ICUSTOMAuthorizerRequestValidator将阻止重定向到客户端,而是将您引导到Identity Server错误屏幕。另外两个将重定向回客户端,通常会抛出一些HttpResponse错误。因此,替换ICustomAuthorizerRequestValidator似乎效果最好

因此,只需创建一个实现ICustomAuthorizerRequestValidator的类。然后像这样将其添加到您的身份服务中

services.AddIdentityServer().AddCustomAuthorizeRequestValidator<MyCustomValidator>()
services.AddIdentityServer().addCustomAuthorizationRequestValidator()

完成。

您可以在IdentityServer 4的索赔表中添加一个名为“角色”的索赔,并在应用程序中添加一些UI以通过电子邮件或类似方式授权某人,然后在索赔数据库中设置其角色。您还可以从应用程序中删除授权用户,该应用程序应取消为该特定人员分配角色。因此,他/她虽然已成功通过身份验证,但无法使用您的应用程序,因为您当时已授权。希望这个方法对你有帮助

在我们的企业场景中,我们将其分为几层:

  • 我们引入了一个租户--我们企业的一个客户(组织) 解决方案
  • 然后,我们为客户分配了角色(不超过20个左右) 每个特定用户
IdentityServer从租户和访问API获取用户。它执行的唯一预检查是,请求令牌的特定客户端(应用程序)不受特定租户的限制(客户级许可),否则我们将显示消息并阻止质询响应

然后我们来看一个应用程序。具有有效令牌,其中包含租户和角色。角色到功能的分配在租户中可能是唯一的。因此,应用程序本身使用单独的API执行粒度权限检查。应用程序可以自由启用或禁用某些功能,甚至重定向到IdSrv“拒绝应用程序访问”中的特殊页面


有了这样的方法,我们可以扩展,可以配置,速度可以随心所欲。在上一代中,我们拥有“一体式”身份+访问+许可怪物般的系统,我们决定拆分。如今,我们在增加新客户(租户)方面没有面临任何实际限制,每个新客户平均拥有20000个用户。

另一种方式是,如果用户未被分配到应用程序/客户端,您可以使用
IdentityServer4.Services的
IProfileService
,将用户重定向回相应的客户端登录页面

public async Task IsActiveAsync(IsActiveContext context)
{
   if (!string.Equals("MyAllowedApplicationId", context.Client.ClientId, StringComparison.OrdinalIgnoreCase))
   {
      context.IsActive = false;
   }
 }
您必须设置
IsActive=false
将用户重定向回t