У нас есть одно приложение, которое использует схему авторизации файлов cookie IdentityServer4 для входа в систему, например:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = <local IDP server with IdentityServer4>;
options.ClientId = <ClientId>;
options.ClientSecret = <secret>
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("offline_access");
})
Клиент в IDP выглядит так:
new Client
{
ClientId = <ClientID>,
ClientName = <ClientName>,
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = true,
ClientSecrets = { new Secret(<secret>.Sha256()) },
AllowOfflineAccess = true,
RedirectUris = { "http://" + ip + "/signin-oidc" },
PostLogoutRedirectUris = { "http://" + ip + "/signout-callback-oidc" },
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
}
};
У нас также есть WebAPI, расположенный по адресу /api/...
Цель состоит в том, чтобы добавить авторизацию JWT Bearer Token в API. Для этого я добавил следующий код:
.AddJwtBearer(jwtOptions =>
{
jwtOptions.Authority = <local IDP server with IdentityServer4>;
jwtOptions.Audience = <ClientID>
jwtOptions.SaveToken = true;
})
API защищен
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
После входа в систему я получаю токен с
await HttpContext.GetTokenAsync("access_token");
Однако, когда я пытаюсь использовать этот токен для доступа к API, я получаю следующую ошибку:
AuthenticationFailed: IDX10214: Ошибка проверки аудитории. Аудитории: 'http://localhost:50059/resources'. Не соответствует: validationParameters.ValidAudience: ClientID или validationParameters.ValidAudiences:' null '.
И действительно, когда я декодирую токен с помощью jwt.io, aud
устанавливается на http://localhost:50059/resources
, а ClientID появляется в виде нового поля 'client_id': '<ClientID>'
.
То, что я обнаружил до сих пор, предполагает, что для aud
всегда установлено значение <idp>/resources
для токенов доступа, и что доступ к API обрабатывается с помощью утверждений области действия внутри токена. Однако я не понимаю, как правильно это настроить.
Кто-нибудь знает, где проблема и как я могу ее исправить? Я был бы очень признателен.