Итак, я создаю новую службу маркеров безопасности, которая заменяет старое решение на основе IdentityServer3. Я хочу пройти аутентификацию в потоке PKCE, и до сих пор я настроил новый сервис с сертификатом, ресурсами идентификации, тестовым пользователем, ресурсом API и клиентом.
Ресурсы идентификации
IEnumerable<IdentityResource> IdentityResources => new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource
{
Name = JwtClaimTypes.Role,
UserClaims = new List<string> { JwtClaimTypes.Role }
}
};
Пользователь
List<TestUser> Users => new List<TestUser>
{
new TestUser
{
SubjectId = "1234",
Username = "asd",
Password = "asd",
Claims = new [] { new Claim(JwtClaimTypes.Role, "super") }
}
};
Ресурс API
IEnumerable<ApiResource> Apis => new List<ApiResource>
{
new ApiResource
{
Name = "api",
UserClaims = new List<string> { JwtClaimTypes.Role },
Scopes = new List<Scope> { new Scope("api") }
}
};
Клиент
IEnumerable<Client> Clients => new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.Code,
AllowAccessTokensViaBrowser = true,
RequirePkce = true,
RequireClientSecret = false,
RequireConsent = false,
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
JwtClaimTypes.Role,
"api"
},
AllowedCorsOrigins = { "http://localhost:3005/" },
RedirectUris = { "http://localhost:3005/callback.html" },
PostLogoutRedirectUris = { "http://localhost:3005/index.html" }
}
};
Клиент AngularJS использует oidc-client.js. Связь между этим и моей службой токенов, кажется, работает нормально. Я получаю действительные токены JWT, возвращенные из IdentityServer4, содержащие ожидаемые данные. Моя цель - передать идентификатор пользователя, содержащийся в маркере доступа, в API, чтобы он мог удостовериться, что пользователь прошел аутентификацию через внешнюю библиотеку, созданную специально для проверки, имеет ли пользователь роль «супер», и выполнять вызовы в БД сID пользователя.
Клиент настраивает OIDC UserManager следующим образом:
return new Oidc.UserManager({
client_id: 'client',
response_type: 'code',
filterProtocolClaims: true,
loadUserInfo: true,
revokeAccessTokenOnSignout: true,
scope: 'openid profile role api',
authority: 'https://localhost:44300/',
redirect_uri: 'http://localhost:3005/callback.html',
post_logout_redirect_uri: 'http://localhost:3005/index.html'
});
Теперь это старая кодовая база - но мне кажется, что когда звонки сделаны из клиента кAPI - маркеры доступа помещаются в заголовок Authorization в вызове push () с использованием $ httpProvider.interceptors, например так:
$httpProvider.interceptors.push(function (apiUrl, oidcManager, currentLanguage) {
return {
'request': function (config) {
if (isApiCall(config, apiUrl, oidcManager)) {
var userManager = oidcManager.getUserManager();
userManager.getUser().then(function (user) {
if (!user) {
userManager.signinRedirect();
}
config.headers.Authorization = 'Bearer ' + user.access_token;
});
}
return config;
}
};
});
При регистрации объекта конфигурации я могу убедиться, что заголовок Authorization действительносодержит токен доступа, который мне нужен. Однако при вызове API с простым GET-запросом без обязательных входных параметров, защищенных атрибутом [Authorize] в методе действия, я получаю ответ 401 Not Authorized. API настроен следующим образом, в классе Startup.
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions {
Authority = "https://localhost:44300/",
RequiredScopes = new[] { "api" }
}
);
Теперь, устанавливая точку останова в конструкторе контроллера для конечной точки, к которой я пытаюсь попасть, я вижу, что нет пользовательских данных, претензийи т. д. подбираются. Я предполагаю, что это связано с тем, как старый клиент AngularJS создает и передает эти запросы, но пока я застрял!
Любое понимание и руководство по этой проблеме будут очень и очень благодарны - и спасибо за чтение моего длинного беспорядка!