Web API не перенаправляет на страницу входа на сервер идентификации - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь реализовать единый вход с использованием сервера идентификации и Web Api

До сих пор я создал проект сервера идентификации и один проект Web Api и настроил их в соответствии с курсом Pluralsight Я следую.Кажется, с тех пор, как был создан этот курс, произошли некоторые изменения, поэтому часть того, что я должен был сделать, не соответствует учебнику (это может быть причиной моей болевой точки, но я не думаю, что это так).

Я ожидаю, что произойдет то, что я попаду на контроллер, требующий авторизации, и при необходимости я перенаправлюсь на страницу входа на сервер идентификации.В настоящее время я получаю 401. Я посмотрел примеры github для неявного потока здесь и кажется, что я поступаю правильно.

Может кто-нибудь помочь мне найти то, что мне не хватает?

Сервер идентификации

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddIdentityServer()
                .AddSigningCredential(new X509Certificate2(@"cert.pfx", "password"))
                .AddInMemoryApiResources(Resources.GetApiResources())
                .AddInMemoryIdentityResources(Resources.GetIdentityResources())
                .AddInMemoryClients(Clients.Get())
                .AddTestUsers(Users.Get())
                .AddDeveloperSigningCredential();

        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();

        app.UseDeveloperExceptionPage();//todo: add if debug

        app.UseIdentityServer();

        app.UseStaticFiles();

        app.UseMvcWithDefaultRoute();
    }
}

internal class Resources
{
    public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource> {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile()
        };
    }

    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource> {
            new ApiResource("gateway", "Gateway Service")
        };
    }
}

internal class Clients
{
    public static IEnumerable<Client> Get()
    {
        return new List<Client> {
            new Client {
                ClientId = "gatewayClient",
                ClientSecrets = new List<Secret> { new Secret("password".Sha256())},//todo:secure password
                AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                AllowedScopes = new List<string> { "gateway" }
            },
            new Client {
                ClientId = "gateway_implicitClient",
                ClientSecrets = new List<Secret> { new Secret("password".Sha256())},//todo:secure password
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowedScopes = new List<string> {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "gateway"
                },
                RedirectUris = new [] { "http://localhost:49942/signin-oidc" },
                PostLogoutRedirectUris = new [] { "http://localhost:49942/signout-callback-oidc" }
            }
        };
    }
}

internal class Users
{
    public static List<TestUser> Get()
    {
        return new List<TestUser> {
            new TestUser {
                SubjectId = "5BE86359-073C-434B-AD2D-A3932222DABE",
                Username = "scott",
                Password = "password"
            }
        };
    }
}

Веб-интерфейс

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
        Configuration = builder.Build();

        _container = new Container();
    }

    public IConfigurationRoot Configuration { get; }
    private Container _container;

    public void ConfigureServices(IServiceCollection services)
    {
        AddAuthentication(services);
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAntiforgery antiforgery)
    {
        app.UseAuthentication();
        app.UseMvc();
    }

    private void AddAuthentication(IServiceCollection services)
    {
        new IdentityServerConfig(services, Configuration);
    }
}

public class IdentityServerConfig
{
    public IdentityServerConfig(IServiceCollection services, IConfigurationRoot configuration)
    {
        services.AddMvcCore()
                .AddAuthorization()
                .AddJsonFormatters();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication(options =>
                {
                    options.RequireHttpsMetadata = false;
                    options.Authority = "http://localhost:5000";
                    options.ApiName = "gateway_implicit";
                })
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    options.ClientId = "gateway_implicitClient";
                    options.SaveTokens = true;
                });
    }
}


[Produces("application/json")]
[Route("api/properties")]
public class PropertiesController : AuthController
{
    [HttpGet]
    [Route("GetProperty/{agentId}/{propertyId}")]
    public async Task<IActionResult> GetProperty(int agentId, Guid propertyId)
    {            
        return Ok(property);
    }
}

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace MyNameSpace.Controllers
{
    [Route("api/[controller]")]
    [Authorize]
    public class AuthController : ControllerBase
    {

    }
}

, когда я звоню http://localhost:49942/api/properties/GetPropertySummaries/1, я вижуниже выводится в VS

Microsoft.AspNetCore.Hosting.Internal.WebHost: Информация: Запрос запуска HTTP / 1.1 GET http://localhost:49942/api/properties/GetPropertySummaries/1
'dotnet.exe' (CoreCLR: clrhost): Loaded'C: \ Users \ me.nuget \ пакеты \ microsoft.aspnetcore.http.extensions \ 2.1.1 \ Lib \ netstandard2.0 \ Microsoft.AspNetCore.Http.Extensions.dll'.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».'dotnet.exe' (CoreCLR: clrhost): загружен 'C: \ Program Files \ dotnet \ shared \ Microsoft.NETCore.App \ 2.1.6 \ System.ComponentModel.Annotations.dll'.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Информация: авторизация не пройдена.Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Информация: авторизация не выполнена для запроса в фильтре «Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter».Microsoft.AspNetCore.Mvc.ChallengeResult: Информация: Выполнение ChallengeResult со схемами аутентификации ().'dotnet.exe' (CoreCLR: clrhost): загружен 'C: \ Program Files \ dotnet \ sdk \ NuGetFallbackFolder \ microsoft.identitymodel.tokens \ 5.2.0 \ lib \ netstandard1.4 \ Microsoft.IdentityModel.Tokens.dll'.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».'dotnet.exe' (CoreCLR: clrhost): загружен 'C: \ Program Files \ dotnet \ sdk \ NuGetFallbackFolder \ system.identitymodel.tokens.jwt \ 5.2.0 \ lib \ netstandard1.4 \ System.IdentityModel.Tokens.Jwt.dll.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».'dotnet.exe' (CoreCLR: clrhost): загружен 'C: \ Program Files \ dotnet \ shared \ Microsoft.NETCore.App \ 2.1.6 \ System.Xml.ReaderWriter.dll'.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».'dotnet.exe' (CoreCLR: clrhost): загружен 'C: \ Program Files \ dotnet \ sdk \ NuGetFallbackFolder \ microsoft.identitymodel.logging \ 5.2.0 \ lib \ netstandard1.4 \ Microsoft.IdentityModel.Logging.dll'.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».'dotnet.exe' (CoreCLR: clrhost): загружен 'C: \ Program Files \ dotnet \ sdk \ NuGetFallbackFolder \ microsoft.identitymodel.protocols \ 5.2.0 \ lib \ netstandard1.4 \ Microsoft.IdentityModel.Protocols.dll'.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».'dotnet.exe' (CoreCLR: clrhost): загружен 'C: \ Program Files \ dotnet \ sdk \ NuGetFallbackFolder \ microsoft.identitymodel.protocols.openidconnect \ 5.2.0 \ lib \ netstandard1.4 \ Microsoft.IdentityModel.Protocols.OpenIdConnect.dll.Пропущены символы загрузки.Модуль оптимизирован и включена опция отладчика «Просто мой код».Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Информация: Схема аутентификации: BearerIdentityServerAuthenticationJwt была оспорена.IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler: Информация: AuthenticationScheme: вызов был предъявлен.Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Информация: выполненное действие MyNamespace.PropertiesController.GetPropertySummaries (MyService.Gateway.Service) в 142,4256 мс

1 Ответ

0 голосов
/ 01 декабря 2018

Для API (а не для веб-приложения на стороне сервера, обслуживающего HTML) возвращение 401 является правильным поведением.Это будет сигнализировать клиенту (например, клиентскому приложению javascript), что ему нужно получить новый токен.Т.е. именно клиент указанного API отвечает за инициирование неявного / гибридного / какого-либо входа в поток для получения подходящего токена на предъявителя.

Если вы используете OpenID Connect / OAuth2, то вы APIне будет использовать куки для аутентификации вообще и будет использовать только аутентификацию токена на предъявителя через промежуточное ПО AddIdentityServerAuthentication ().

...