Как выполнить авторизацию через API на основе ролей с помощью Identity Server 4 (JWT) - PullRequest
0 голосов
/ 26 июня 2018

Это все ново для меня, и я все еще пытаюсь обернуть голову вокруг этого. У меня настроен IDP (Identity Server 4), и я смог настроить клиент для аутентификации в нем (приложение Angular 6) и, более того, для аутентификации в API (Asp.Net Core 2.0). Кажется, все работает нормально.

Вот определение клиента в IDP:

new Client
            {
                ClientId = "ZooClient",
                ClientName = "Zoo Client",
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowAccessTokensViaBrowser = true,
                RequireConsent = true,

                RedirectUris           = { "http://localhost:4200/home" },
                PostLogoutRedirectUris = { "http://localhost:4200/home" },
                AllowedCorsOrigins = { "http://localhost:4200" },

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    IdentityServerConstants.StandardScopes.Phone,
                    IdentityServerConstants.StandardScopes.Address,
                    "roles",
                    "ZooWebAPI"
                }
            }

Я запрашиваю следующие области в клиенте: 'почтовые роли openid профиля ZooWebAPI'

WebAPI настроен так:

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddMvcCore()
            .AddJsonFormatters()
            .AddAuthorization();

        services.AddCors();
        services.AddDistributedMemoryCache();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "https://localhost:44317";
                options.RequireHttpsMetadata = false;
                options.ApiName = "ZooWebAPI";    
            });


    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors(policy =>
        {
            policy.WithOrigins("http://localhost:4200");
            policy.AllowAnyHeader();
            policy.AllowAnyMethod();
            policy.AllowCredentials();
            policy.WithExposedHeaders("WWW-Authenticate");
        });

        app.UseAuthentication();
        app.UseMvc();
    }

Используя [Authorize], я успешно смог защитить API:

[Route("api/[controller]")]
    [Authorize]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public ActionResult Get()
        {
            return new JsonResult(User.Claims.Select(
                c => new { c.Type, c.Value }));
        }
    }

Все работает нормально, если клиент не аутентифицирован, браузер переходит на IDP, требует аутентификации, перенаправляет обратно с токеном доступа, токен затем используется для успешно выполненных вызовов API.

Если я посмотрю на Заявления в объекте Пользователь, я смогу увидеть некоторую информацию, но у меня нет никакой пользовательской информации. Я могу видеть области видимости и т. Д., Но не роли, например. Из того, что я прочитал, этого следует ожидать, и API не должно заботиться о том, что пользователь вызывает, но как бы я ограничил вызовы API на основе ролей? Или это будет полностью против спецификаций?

У IDP есть конечная точка userinfo, которая возвращает всю пользовательскую информацию, и я подумал, что она будет использоваться в WebAPI, но, опять же, после некоторого чтения похоже, что намерение состоит в том, чтобы эта конечная точка была вызвана из только клиент.

В любом случае, я хотел бы ограничить вызовы веб-API на основе ролей для конкретного пользователя. У кого-нибудь есть предложения, комментарии? Кроме того, я хотел бы знать, какой пользователь выполняет вызов, как бы я поступил таким образом?

Пример JWT:

enter image description here

Спасибо

1 Ответ

0 голосов
/ 27 июня 2018

Из того, что я могу извлечь из вашей информации, я могу сказать следующее.

Вы входите через внешнего провайдера: Аутентификация Windows. Вы определяете некоторые области для передачи чего-либо токену, который указывает на доступ к определенным ресурсам.

Объект User, о котором вы говорите, - это класс User, который заполняется из маркера доступа. Поскольку токен доступа по умолчанию не включает утверждения профиля пользователя, у вас их нет в объекте User. Это отличается от использования проверки подлинности Windows напрямую, где имя пользователя указано в Принципе пользователя.

Вам необходимо предпринять дополнительные действия для предоставления авторизации на основе входа пользователя в систему. Есть пара моментов, в которые вы можете добавить логику авторизации:

Вы можете определить претензии для пользовательских областей, которые вы определяете в конфигурации Identityserver. ИМХО, это нежелательно, потому что он привязан к методу входа, а не к входу пользователя.

Вы можете использовать ClaimsTransformation (см. Ссылки ниже). Это позволяет вам добавлять претензии в список претензий, доступных в начале ваших методов. Это имеет недостаток (для некоторых людей положительный), что эти дополнительные утверждения не добавляются к самому токену доступа, только на вашем бэкэнде, где токен оценивается, эти утверждения будут добавлены до того, как запрос будет обработан вашим кодом. .

Способ получения этих претензий соответствует требованиям вашего бизнеса.

Если вам нужна информация о пользователе, вам нужно вызвать конечную точку userinfo Identityserver, чтобы узнать хотя бы имя пользователя. Вот для чего предназначена эта конечная точка. Исходя из этого, вы можете использовать свою собственную логику для определения «ролей», которыми обладает этот пользователь.

Например, мы создали отдельную службу, которая может настраивать и возвращать утверждения «Роли» на основе пользователя и областей, включенных в маркер доступа.

Использование претензийПреобразование .NET Core

UseClaimsTransformation .NET Full framework

...