В настоящее время я создаю WebApp с аутентификацией / авторизацией для доступа к нему, а также для доступа к нескольким WebAPI, все из которых указывают на хост Identity Server 4. Я следил за официальной документацией IdentityServer4 и его демонстрациями и для аутентификаций клиентов, поколений токенов, входа пользователей, успешного вызова API с токенами, все работает нормально, но, однако, недавно я заметил, что после некоторого времени бездействия вызов API начинает получать 401, но клиентское приложение все еще работает с тем же маркером.
Это так:
- Запустить браузер с отладкой
- Войти с некоторыми пользователь
- Go для представления, которое вызывает один API для извлечения данных для него
- Продолжайте навигацию и тестирование, а все остальное работает нормально
Теперь проблема (после предыдущего шага 4)
- Прекратить отладку, но оставить браузер включенным и работающим (сохранять куки)
- Изменение кода, внедрение новых вещей (в основном, проходящих некоторое время)
- Запустите отладку снова
- Используя те же сеансы / cook ie в уже открытом браузере, пытаясь перейти на Приложение работает нормально и не требует нового входа в систему
- Переход к представлению, которое будет вызывать API с использованием текущего токена, дает мне 401, когда ранее не было
Что я узнал является то, что токен истек, выход Visual Studio указывает, что (также проверяя токен на https://jwt.io/ я могу подтвердить дату и время). Почему тот же самый токен отлично работает для ClientApp, а вызов API - нет? Требуется ли мне вручную генерировать новый токен из-за вызовов API?
Используемые мной конфигурации:
--- Приложение CLIENT ---
new Client
{
ClientId = "idWebApp",
ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Hybrid,
AllowAccessTokensViaBrowser = false,
EnableLocalLogin = true,
RedirectUris = { "http://localhost:5901/signin-oidc" },
FrontChannelLogoutUri = "http://localhost:5901/signout-oidc",
PostLogoutRedirectUris = { "http://localhost:5901/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
"apiAccess",
},
RequireConsent = false,
}
--- ресурс API ---
(просто используя простой ctor для инициализации с помощью 'Name')
new ApiResource("apiAccess")
--- Custom Claims ---
new IdentityResource()
{
Name = "appCustomClaims",
UserClaims = new List<string>()
{
"customRole"
}
}
--- код запуска ClientApp ---
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "http://localhost:5900";
options.RequireHttpsMetadata = false;
options.ClientId = "idWebApp";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.ClaimActions.MapUniqueJsonKey("offline_access", "offline_access");
options.Scope.Add("appCustomClaims");
options.ClaimActions.MapJsonKey("customRole", "customRole");
options.Scope.Add("apiAccess");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.TokenValidationParameters.RoleClaimType = "customRole";
});