【问题标题】:How do I customize /connect/token to take custom parameters?如何自定义 /connect/token 以获取自定义参数?
【发布时间】:2019-12-01 14:14:57
【问题描述】:

要通过客户端凭据流获取 access_token,您可以像这样调用 /connect/token

curl -X POST https://<identityserver>/connect/token 
-H 'Content-Type: application/x-www-form-urlencoded' 
-d 'grant_type=client_credentials&scope=myscope1'

我好像不能自定义 /connect/token 来获取自定义参数?我想从 api 中获取自定义值并通过 ICustomTokenRequestValidator (https://stackoverflow.com/a/43930786/103264) 将它们添加到我的自定义声明中

【问题讨论】:

    标签: c# asp.net-core .net-core identityserver4


    【解决方案1】:

    这也适用于 Raw.get(int index)。使用能够从表单 urlencoded 参数中检索自定义值作为原始值的索引

    context.Result.ValidatedRequest.Raw.Get(4);
    

    【讨论】:

      【解决方案2】:

      您可以使用acr_values 参数自定义您的呼叫。例如,下面我们将tenantId 值作为参数,对其进行验证并将其作为声明放入令牌中。 调用看起来像:

      curl -d "grant_type=client_credentials&client_id=the-svc-client&client_secret=the-secret&acr_values=tenant:DevStable" https://login.my.site/connect/token
      

      以及 vlidator(部分复制并粘贴自 AuthRequestValidator):

      public Task ValidateAsync(CustomTokenRequestValidationContext context)
      {
          var request = context.Result.ValidatedRequest;
      
          if (request.GrantType == OidcConstants.GrantTypes.ClientCredentials)
          {
              //////////////////////////////////////////////////////////
              // check acr_values
              //////////////////////////////////////////////////////////
              var acrValues = request.Raw.Get(OidcConstants.AuthorizeRequest.AcrValues);
              if (acrValues.IsPresent())
              {
                  if (acrValues.Length > context.Result.ValidatedRequest.Options
                          .InputLengthRestrictions.AcrValues)
                  {
                      _logger.LogError("Acr values too long", request);
                      context.Result.Error = "Acr values too long";
                      context.Result.ErrorDescription = "Invalid acr_values";
                      context.Result.IsError = true;
                      return Task.CompletedTask;
                  }
      
                  var acr = acrValues.FromSpaceSeparatedString().Distinct().ToList();
      
      
                  //////////////////////////////////////////////////////////
                  // check custom acr_values: tenant
                  //////////////////////////////////////////////////////////
      
                  string tenant = acr.FirstOrDefault(x => x.StartsWith(nameof(tenant)));
      
                  tenant = tenant?.Substring(nameof(tenant).Length+1);
      
                  if (!tenant.IsNullOrEmpty())
                  {
                      var tenantInfo = _tenantService.GetTenantInfoAsync(tenant).Result;
                      // if tenant is present in request but not in the list, raise error!
                      if (tenantInfo == null)
                      {
                          _logger.LogError("Requested tenant not found", request);
                          context.Result.Error = "Requested tenant not found";
                          context.Result.ErrorDescription = "Invalid tenant";
                          context.Result.IsError = true;
                      }
      
                      context.Result.ValidatedRequest.ClientClaims.Add(
                          new Claim(Constants.TenantIdClaimType, tenant));            
                  }
              }
          }
          return Task.CompletedTask;
      }
      

      【讨论】:

      • 我最终添加了额外的输入参数,然后我通过 context.Result.ValidatedRequest.Raw 读取了输入参数。但你的方式是正确的方式:)
      • 如何将 2 个或更多值添加到 acr_values?
      • var acr = acrValues.FromSpaceSeparatedString().Distinct().ToList(); 所以:acr_values=tenant:DevStable nextParam:value
      • here 是规范。这是用于身份验证请求,但无论如何
      • 您是否知道如何通过 IProfileService 、 ProfileDataRequestContext 的授权类型代码传递输入参数?
      猜你喜欢
      • 1970-01-01
      • 2021-12-12
      • 2015-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      相关资源
      最近更新 更多