问题描述
我想使用客户端凭据对 API 资源进行身份验证。
我已经能够成功生成令牌。
2021-06-10T00:47:19.1953056+05:45 [ERR] (OpenIddict.Validation.OpenIddictValidationdispatcher) The authentication demand was rejected because the token had no audience attached.
2021-06-10T00:47:19.1954307+05:45 [INF] (OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandler) "OpenIddict.Validation.AspNetCore" was not authenticated. Failure message: "An error occurred while authenticating the current request."
2021-06-10T00:47:19.1960031+05:45 [INF] (OpenIddict.Validation.OpenIddictValidationdispatcher) The response was successfully returned as a challenge response: "{
\"error\": \"invalid_token\",\"error_description\": \"The specified token doesn't contain any audience.\",\"error_uri\": \"https://documentation.openiddict.com/errors/ID2093\"
}".
2021-06-10T00:47:19.1960852+05:45 [INF] (OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandler) AuthenticationScheme: "OpenIddict.Validation.AspNetCore" was challenged.
我的配置中缺少什么?使用客户端凭据授予类型通过 openiddict 保护 API 资源的正确方法是什么?
资源服务器启动配置:
public static IServiceCollection AddInfrastructure(this IServiceCollection services,IConfiguration configuration)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
});
services.AddOpenIddict()
.AddValidation(options =>
{
options.SetIssuer("https://localhost:44301/");
options.AddAudiences("signal_system_web_resource");
options.UseIntrospection()
.SetClientId("signal_system_web_resource")
.SetClientSecret("846B62D0-DEF9-4215-A99D-86E6B8DAB342");
options.UseSystemNetHttp();
options.UseAspNetCore();
});
services.AddHttpClient();
return services;
}
客户端配置:
if (await manager.FindByClientIdAsync("nj-client") == null)
{
await manager.CreateAsync(new OpenIddictApplicationDescriptor
{
ClientId = "nj-client",ClientSecret = "C4Bbed05-A7C1-4759-99B5-0F84A29F0E08",displayName = "Ninja Client Application",Permissions =
{
Permissions.Endpoints.Token,Permissions.GrantTypes.ClientCredentials
}
});
}
if (await manager.FindByClientIdAsync("signal_system_web_resource") == null)
{
var descriptor = new OpenIddictApplicationDescriptor
{
ClientId = "signal_system_web_resource",ClientSecret = "846B62D0-DEF9-4215-A99D-86E6B8DAB342",Permissions =
{
Permissions.Endpoints.Introspection
}
};
await manager.CreateAsync(descriptor);
}
OpenIddictScopeDescriptor
var descriptor = new OpenIddictScopeDescriptor
{
Name = "signal.system.web",Resources =
{
"signal_system_web_resource"
}
};
资源服务器 API 控制器
[Authorize]
[HttpGet("message")]
public async Task<IActionResult> GetMessage()
{
var identity = User.Identity as ClaimsIdentity;
if (identity == null)
{
return BadRequest();
}
return Content($"Signal System Web says that you have authorized access to resources belonging to {identity.Name}.");
}
解决方法
我可以通过在生成令牌的同时添加资源来解决这个问题。
var principal = new ClaimsPrincipal(identity);
principal.SetResources("signal_system_web_resource");
return SignIn(principal,OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);