-6ren">
gpt4 book ai didi

c# - 当授予类型为 ClientCredentialsFlow 时,MockIdentityServer 客户端声明不包含在访问 token 中

转载 作者:太空宇宙 更新时间:2023-11-03 11:57:28 26 4
gpt4 key购买 nike

我有受政策保护的 API Controller 。此策略在 Startup.cs 中配置,如

 options.AddPolicy("InternalClient", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
(c.Type == "client_id" && c.Value == "installation-logic-client-id"))));

而 Controller 方法是:

    [HttpGet("{familyId}/versions/{version}/infos")]
[Authorize(Policy = "InternalClient")]
public IActionResult GetTestInfo(Guid testFamilyId, string version)
{
..............................
}

并测试上述方法,我从 MockIdentityServer 获取 token 。在那里我正在配置客户端

       yield return new Client
{
ClientId = "installation-logic-client-id",
ClientSecrets = new[] {new Secret("installation-logic-client-secret".Sha256())},
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = new[] {"installation-logic-scope"},
AllowOfflineAccess = true,
AccessTokenType = AccessTokenType.Jwt,
RefreshTokenUsage = TokenUsage.OneTimeOnly,
RefreshTokenExpiration = TokenExpiration.Sliding,

Claims = new List<Claim>() // I want these claims to be added in the access_token so that they can be verified while making the request.
{
new Claim("client_id", "installation-logic-client-id")
},
AlwaysSendClientClaims = true,
AlwaysIncludeUserClaimsInIdToken = true,
};

我总是能成功获得 token ,但不幸的是,该 token 不包含我正在测试和正在为其设置策略的声明信息。以下是调用..

            private async Task<string> GetTokenForInternalClient()
{
var tokenRequest = new ClientCredentialsTokenRequest()
{
Address = await GetTokenEndpoint(),
ClientId = MockConstants.TokenInstallationLogicClientId,
ClientSecret = MockConstants.TokenInstallationLogicClientSecret,
Scope = MockConstants.TokenInstallationLogicScope
};

var tokenResponse = await
_identityServerClient.RequestClientCredentialsTokenAsync(tokenRequest);
if (tokenResponse.IsError) throw new MockIdentityServerException(tokenResponse);

return tokenResponse.AccessToken; // Here I see very short token. Clearly it doesn't contains the claims.
}

目前,我收到“未经授权” 请求。因为由于 claim 不可用,它没有通过政策。任何人都可以告诉我我做错了什么吗?是否有特定的方法来获取所有声明的 access_token

在 Client 对象内的策略级别将 client_id 更改为 id 之后,还将 TokenType 更改为“Jwt”而不是 opf Reference,我得到了以下 Payload。

    {
"nbf": 1574191641,
"exp": 1574195241,
"iss": "http://localhost:5000",
"aud": "installation-logic-scope",
"client_id": "installation-logic-client-id",
"scope": [
"installation-logic-scope"
]
}

更新声明(有效载荷主体)

{
"nbf": 1574198669,
"exp": 1574202269,
"iss": "http://localhost:5000",
"aud": "installation-logic-client-id",
"client_id": "installation-logic-client-id",
"scope": [
"installation-logic-scope"
]
}

Startup.cs

private static void ConfigureAuthorization(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("admin", pb => pb.RequireClaim("Role", "admin", "orgadmin"));
options.AddPolicy("InternalClient", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
((c.Type == "Role" && (c.Value == "admin" || c.Value == "orgadmin")) ||
(c.Type == "id" && c.Value == "installation-logic-client-id")))));
});
}

private void ConfigureDbContexts(IServiceCollection services)
{
........................
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
[UsedImplicitly]
public void Configure(IApplicationBuilder app, PackageHandlingContext dbContext)
{
// middlewares: order is important
app.UseRouting();
app.UseCors("AnyOrigin");
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();

app.UseEndpoints(endpoints => endpoints.MapControllers());

dbContext.Database.EnsureCreated();
}

最佳答案

我想通了整个故事中的所有问题。

首先在memoy ApiResources中构建时,scopes还应该包含“client_id”。

Scopes = new List<Scope>
{
new Scope(MockConstants.PackageHandlingScope, new[] {"Role", "client_id"})
},

其次,构建测试客户端,只需要使用"id"作为声明类型,因为client_已经带有声明类型前缀。

更新后的客户端是

yield return new Client
{
ClientId = MockConstants.TokenInstallationLogicClientId,
ClientSecrets = new[] {new Secret(MockConstants.TokenInstallationLogicClientSecret.Sha256())},
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = new[] {MockConstants.PackageHandlingScope},
AllowOfflineAccess = true,
AccessTokenType = AccessTokenType.Jwt,
RefreshTokenUsage = TokenUsage.OneTimeOnly,
RefreshTokenExpiration = TokenExpiration.Sliding,

Claims = new List<Claim>
{
new Claim("id", "installation-logic-client-id")
}
};

其他都很好。

@Ruard van Elburg 非常感谢您的评论,您指出了构建测试客户端时必需的“id”内容。因为客户声称 alwazs 在通过网络传输到应用程序时会得到前缀。

谢谢

关于c# - 当授予类型为 ClientCredentialsFlow 时,MockIdentityServer 客户端声明不包含在访问 token 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58939442/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com