我正在使用IdentityModel.AspNetCore
和.AddClientAccessTokenHandler()
扩展来自HttpClient
动向 API 提供访问令牌(至少我理解我可以使用它)。一些 API 端点是基于角色授权的。但是由于某种原因,添加到请求中的访问令牌不包含角色声明。如果我不使用.AddClientAccessTokenHandler()
并手动检索令牌并使用它进行设置,SetBearerToken(accessTone)
那么我可以到达我的角色授权端点。
我的启动是:
services.AddAccessTokenManagement(options =>
{
options.Client.Clients.Add("auth", new ClientCredentialsTokenRequest
{
Address = "https://localhost:44358/connect/token",
ClientId = "clientId",
ClientSecret = "clientSecret",
});
});
WebApi 调用:
var response = await _httpClient.GetAsync("api/WeatherForecast/SecretRole");
身份服务器配置:
public static IEnumerable<ApiResource> GetApis() =>
new List<ApiResource>
{
new ApiResource("WebApi", new string[] { "role" })
{ Scopes = { "WebApi.All" }}
};
public static IEnumerable<ApiScope> GetApiScopes() =>
new List<ApiScope>
{ new ApiScope("WebApi.All") };
public static IEnumerable<IdentityResource> GetIdentityResources() =>
new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource
{
Name = "roles",
UserClaims = { "role" }
}
};
public static IEnumerable<Client> GetClients() =>
new List<Client>
{
new Client
{
ClientId = "clientId",
ClientSecrets = { new Secret("clientSecret".ToSha256()) },
AllowedGrantTypes =
{
GrantType.AuthorizationCode,
GrantType.ClientCredentials
},
AllowedScopes =
{
"WebApi.All",
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"roles"
},
RedirectUris = { "https://localhost:44305/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:44305/Home/Index" },
AlwaysIncludeUserClaimsInIdToken = false,
AllowOfflineAccess = true,
}
};
出于测试目的,我从 Program.cs 手动添加用户
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
AddUsers(userManager).GetAwaiter().GetResult();
}
host.Run();
}
private static async Task AddUsers(UserManager<IdentityUser> userManager)
{
var adminClaim = new Claim("role", "Admin");
var visitorClaim = new Claim("role", "Visitor");
var user = new IdentityUser("Admin");
await userManager.CreateAsync(user, user.UserName);
await userManager.AddClaimAsync(user, adminClaim);
user = new IdentityUser("Visitor");
await userManager.CreateAsync(user, user.UserName);
await userManager.AddClaimAsync(user, visitorClaim);
}
因此,如果我使用手动访问令牌检索并将其自己添加到 HttpClient 标头中,则会到达我的端点并返回预期的响应。如果我使用.AddClientAccessTokenHandler()
,我会得到 403 - Forbidden。我错过了什么?