【发布时间】:2019-11-19 17:09:53
【问题描述】:
我有受政策保护的 API 控制器。此策略在 Startup.cs 中配置,如
options.AddPolicy("InternalClient", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
(c.Type == "client_id" && c.Value == "installation-logic-client-id"))));
而控制器方法是:
[HttpGet("{familyId}/versions/{version}/infos")]
[Authorize(Policy = "InternalClient")]
public IActionResult GetTestInfo(Guid testFamilyId, string version)
{
..............................
}
并测试上述方法,我从 MockIdentityServer 获取令牌。在那里我正在配置客户端
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,
};
我总是成功获得令牌,但不幸的是,该令牌不包含我正在测试的声明信息以及正在为其设置的策略。 以下是电话..
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.
}
目前,我收到 'Unauthorized' 请求。因为由于索赔不可用,它没有通过政策。 任何人都可以告诉我我做错了什么吗?是否有特定的方法来获取所有声明的 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();
}
【问题讨论】:
-
编辑并显示了有效载荷。
-
用 Startup.cs 更新了问题
-
我刚刚更正了 ApiScope 并使用了您的建议。在构建客户端时,我使用的是“id”。在此之后,它开始在令牌内返回正确的 clims。所以我收到了 7 个声明,通过反省,我也验证了这一点。但是在提出请求时我仍然未经授权,因为配置的策略在某种程度上无法被这些声明识别
-
获得了更新的声明。 { “nbf”:1574198669,“exp”:1574202269,“iss”:“localhost:5000”,“aud”:“安装逻辑客户端 ID”,“客户端 ID”:“安装逻辑客户端 ID” , "范围": [ "安装逻辑范围" ] }
标签: c# mocking integration-testing identityserver4