Построение STS с IdentityServer4, предоставление токенов JWT клиенту AngularJS, защита API .NET;почему авторизация не удалась? - PullRequest
0 голосов
/ 01 ноября 2019

Итак, я создаю новую службу маркеров безопасности, которая заменяет старое решение на основе 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 создает и передает эти запросы, но пока я застрял!

Любое понимание и руководство по этой проблеме будут очень и очень благодарны - и спасибо за чтение моего длинного беспорядка!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...