Не удается защитить внутренний API с помощью IdentityServer 4 (ошибка 500) - PullRequest
0 голосов
/ 25 октября 2018

Немного предыстории, у меня есть проект IdenityServer 4, который я использую для защиты доступа к имеющемуся у меня проекту MVC (с использованием удостоверения ASP.NET).

Теперь, что я также хотел, это API, который защищен через учетные данные клиента, который возвращает некоторую информацию.

Что я сделал, так это сделал новый основной проект API, и это работало нормально с защитой клиента, однако я хотел переместить API, чтобы он был внутри IdenityServer.

например localhost: 5000 / api / info / getinfo

Теперь, когда я переместил код, я получаю ошибку 500 при использовании атрибута [Authorize (AuthenticationSchemes = "Bearer")]

Я могу использовать DiscoveryClient для получения успешного токена с использованием учетных данных, но не могу с любым запросом, если они не авторизованы.

Поэтому в ID я настроил свой запуск так:

        services.AddMvc();

        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();

        // Configure identity server with in-memory stores, keys, clients and scopes
        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryPersistedGrants()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryClients(Config.GetClients(Configuration))
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddAspNetIdentity<ApplicationUser>();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = Configuration.GetSection("Authority").Value;
                options.RequireHttpsMetadata = false;

                options.ApiName = "IdentityInfoApi";
            });

А затем для моего защищенного вызова API я помечаю его следующим образом: [Authorize (AuthenticationSchemes = "Bearer")]

, но это возвращает ошибку 500, теперь, когда я используютег: [Авторизовать] это работает, но это потому, что пользователь вошел в приложение mvc, и ответом является html-страница, а не объект json, который я хочу.

В настоящее время я использую модульный тест для определения API, и код выглядит так:

var client = new HttpClient();

        var disco = DiscoveryClient.GetAsync("https://localhost:5000").Result;

        var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
        var tokenResponse = tokenClient.RequestClientCredentialsAsync("IdentityInfoApi").Result;
        client.SetBearerToken(tokenResponse.AccessToken);

        var response = client.GetAsync("https://localhost:5000/api/info/getinfo").Result;
        if (!response.IsSuccessStatusCode)
        {
            var userResult = response.Content.ReadAsStringAsync().Result;

            var result = JsonConvert.DeserializeObject<PagedUserList>(userResult);

            Assert.NotNull(result);
        }

Что-то не так с моей настройкой идентификатора, кода клиента илиВы не можете использовать ID таким образом?

Спасибо за вашу помощь

1 Ответ

0 голосов
/ 25 октября 2018

После долгой игры я думаю, что нашел решение.

Вы должны определить AddAuthentication () перед AddIdentity (), или, другими словами, вы должны настроить API перед Identity Server

Это нормально сделать в любом случае, если ваш API внешний, но не еслион находится внутри приложения Identity Server.

Мой новый код выглядит следующим образом:

  //Configure api
        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();

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

                options.ApiName = "IdentityInfoApi";
            });
        //end

        services.AddIdentity<ApplicationUser, IdentityRole>(config =>
        {
            config.SignIn.RequireConfirmedEmail = true;
        })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        // Add application services.
        services.AddTransient<IEmailSender, EmailSender>();
        services.Configure<AuthMessageSenderOptions>(Configuration.GetSection("SMTP"));

        services.AddMvc();

        // Configure identity server with in-memory stores, keys, clients and scopes
        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryPersistedGrants()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryClients(Config.GetClients(Configuration))
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddAspNetIdentity<ApplicationUser>();

Надеюсь, это кому-нибудь еще поможет

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