Получить UserInfo из токена доступа - «Запрещено» - PullRequest
0 голосов
/ 11 января 2019

Я хочу получить заявки на токен доступа, но когда я пытаюсь получить UserInfo, ответ возвращает ошибку «Запрещено». Почему это и как мне это исправить? Конечная точка userinfo - https://localhost:44307/connect/userinfo Код ниже будет переработан, как только он заработает. Поле response1 содержит сообщение об ошибке;

    var client = new HttpClient();
    var disco = await client.GetDiscoveryDocumentAsync(Settings.AuthorityUrl);
    if (disco.IsError)
    {
        throw new Exception(disco.Error);
    }
    var tokenRequest = new ClientCredentialsTokenRequest
    {
        Address = Settings.AuthorityUrl + "connect/token",
        ClientId = Settings.ClientId,
        ClientSecret = "secret",
        Scope = "SIR"
    };

    var response = await client.RequestClientCredentialsTokenAsync(tokenRequest);
    var token = response.AccessToken;
    var response1 = await client.GetUserInfoAsync(new UserInfoRequest
    {
        Address = disco.UserInfoEndpoint,
        Token = token
    });

    if (response1.IsError) throw new Exception(response1.Error);

    var claims = response1.Claims;

В моем IDP мой конфигурационный файл

using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic;
using System.Security.Claims;

namespace QuickstartIdentityServer
{
    public class Config
    {
        // scopes define the resources in your system
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Address()
            };
        }

        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("SIR", "Service Inspection Report")
            };
        }

        // clients want to access resources (aka scopes)
        public static IEnumerable<Client> GetClients()
        {
            var baseUri = "http://localhost:53200/";
            // client credentials client
            return new List<Client>
            {

                // OpenID Connect hybrid flow and client credentials client (MVC)
                new Client
                {
                    ClientId = "SIR",
                    ClientName = "SIR",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },

                    RedirectUris = { $"{baseUri}signin-oidc" },
                    PostLogoutRedirectUris = { $"{baseUri}signout-callback-oidc" },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Address,
                        "SIR"
                    },
                    AllowOfflineAccess = true,
                    AlwaysIncludeUserClaimsInIdToken = true
                }
            };
        }

        public static List<TestUser> GetUsers()
        {
            return new List<TestUser>
            {
                new TestUser
                {
                    SubjectId = "1",
                    Username = "alice",
                    Password = "password",

                    Claims = new List<Claim>
                    {
                        new Claim("name", "Alice"),
                        new Claim("website", "https://alice.com"),
                        new Claim("address", "1a The Street")
                    }
                },
                new TestUser
                {
                    SubjectId = "2",
                    Username = "bob",
                    Password = "password",

                    Claims = new List<Claim>
                    {
                        new Claim("name", "Bob"),
                        new Claim("website", "https://bob.com"),
                        new Claim("address", "2a The Street")
                    }
                }
            };
        }
    }
}

И запуск есть;

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // configure identity server with in-memory stores, keys, clients and scopes
        services.AddIdentityServer()
            .AddSigningCredential(new X509Certificate2(Settings.CertPath, Settings.Password))
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddTestUsers(Config.GetUsers());

        services.AddAuthentication()
            .AddGoogle("Google", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

                // register your IdentityServer with Google at https://console.developers.google.com
                // enable the Google+ API
                // set the redirect URI to http://localhost:port/signin-google
                options.ClientId = "copy client ID from Google here";
                options.ClientSecret = "copy client secret from Google here";
            })
            .AddOpenIdConnect("oidc", "OpenID Connect", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                options.SignOutScheme = IdentityServerConstants.SignoutScheme;

                options.Authority = "https://demo.identityserver.io/";
                options.ClientId = "implicit";

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };
            });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMiddleware<StackifyMiddleware.RequestTracerMiddleware>();
        app.UseIdentityServer();
        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();
    }
}

1 Ответ

0 голосов
/ 14 января 2019

Вы используете клиентские полномочия , определенные OAuth 2.0.

В вашем коде RequestClientCredentialsTokenAsync обозначает запрос токена с использованием этого типа предоставления. Обратите внимание, что когда вы получаете токен доступа через этот грант, конечный пользователь не участвует. Это не OpenID Connect (без аутентификации конечного пользователя), он просто работает с учетными данными клиента, позволяя иметь только токен доступа.

Теперь, когда вы используете этот токен доступа для запроса UserInfo , сервер идентификации обнаруживает, что у него нет коррелированного конечного пользователя. Следовательно, он возвращает запрещенный ответ, чтобы сообщить вам, что у вас нет разрешения на доступ к конечной точке.

Смотрите точную информацию из документации,

Конечная точка UserInfo может использоваться для получения идентификационной информации о пользователе (см. spec ).

Абонент должен отправить действительный токен доступа, представляющий пользователя .

Если вы хотите получить информацию о пользователе, используйте разрешение кода авторизации или гибридный поток со значением области openid, чтобы включить запрос OpenID Connect. Вы можете прочитать больше здесь для различных типов грантов.

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