Identity Server 4 не перенаправляет в приложение Angular после входа в систему - PullRequest
1 голос
/ 07 марта 2019

сильный текст Я использую 'oidc-client' в угловых. после этого урока

https://www.scottbrady91.com/Angular/SPA-Authentiction-using-OpenID-Connect-Angular-CLI-and-oidc-client

import { UserManager, UserManagerSettings, User } from 'oidc-client';

и настройки моего клиента выглядят так

export function getClientSettings(): UserManagerSettings {
return {
authority: 'https://localhost:44305/',
client_id: 'angular_spa',
redirect_uri: 'http://localhost:4200/auth-callback',
post_logout_redirect_uri: 'http://localhost:4200/',
response_type: 'id_token token',
scope: 'openid profile api1',
filterProtocolClaims: true,
loadUserInfo: true,
automaticSilentRenew: false 
 // silent_redirect_uri: 'http://localhost:4200/silent-refresh.html',
//metadataUrl: 'http://localhost:44305/.well-known/openid-configuration'
};

на сервере идентификации я использую Assembly Microsoft.AspNetCore.Identity.UI, версия = 2.1.3.0

Я добавляю идентификатор по умолчанию, как это

[assembly: 
HostingStartup(typeof(WebApp.Areas.Identity.IdentityHostingStartup))]
namespace WebApp.Areas.Identity {
public class IdentityHostingStartup: IHostingStartup {
public void Configure(IWebHostBuilder builder) {
builder.ConfigureServices((context, services) => {
services.AddDbContext < WebAppContext > (options =>
 options.UseSqlite(
  context.Configuration.GetConnectionString("WebAppContextConnection")));

services.AddDefaultIdentity < WebAppUser > ()
 .AddEntityFrameworkStores < WebAppContext > ();
 });
}
}
}

WebAppUser является производным от IdentityUser

класс запуска выглядит следующим образом.

   public class Startup
{

    private ILogger<DefaultCorsPolicyService> _logger;
    private IHostingEnvironment _env;

    public Startup(ILoggerFactory loggerFactory, IHostingEnvironment env)
    {
        _logger = loggerFactory.CreateLogger<DefaultCorsPolicyService>();
        _env = env;
    }
    private static void SetupIdentityServer(IdentityServerOptions identityServerOptions)
    {
        identityServerOptions.UserInteraction.LoginUrl = new PathString("/Identity/Account/Login");
        //  identityServerOptions.Cors.CorsPolicyName = "CorsPolicy";
    }
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
        {
            builder
             .WithOrigins("https://localhost:44305")
            .AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));

        //  services.AddMvc();
        var cors = new DefaultCorsPolicyService(_logger)
        {
            AllowAll = true
        };

        var cert = new X509Certificate2(Path.Combine(_env.ContentRootPath, "mycert.pfx"), "xxxxx");
        services.AddIdentityServer(SetupIdentityServer)//SetupIdentityServer
                 .AddSigningCredential(cert)
                 .AddInMemoryApiResources(Config.GetApiResources())
                 .AddInMemoryClients(Config.GetClients())
                 // .AddTestUsers(TestUsers.Users)
                 .AddInMemoryIdentityResources(Config.GetIdentityResources());
                 services.AddSingleton<ICorsPolicyService>(cors);

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

        app.Map("/api", api =>
        {
            api.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
            api.UseAuthentication();

            api.Run(async context =>
            {
                var result = await context.AuthenticateAsync("api");
                if (!result.Succeeded)
                {
                    context.Response.StatusCode = 401;
                    return;
                }

                context.Response.ContentType = "application/json";
                await context.Response.WriteAsync(JsonConvert.SerializeObject("API Response!"));
            });
        });

        app.UseIdentityServer();

        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();

        //Run these PMC commands after this.
        //Add - Migration CreateIdentitySchema
        //Update - Database

    }
}

на сервере идентификации 4 я включил https. Так что проблема в том, что из моего приложения Angular, если я пытаюсь использовать защищенный URL-адрес, я перехожу на страницу входа в систему. Похоже, что он аутентифицируется должным образом против пользователя в базе данных. но затем он просто обновляет страницу входа и не перенаправляет на URL обратного вызова.

вот несколько журналов, которые могут помочь

2019 - 03 - 07 01: 19: 30.553 - 06: 00 [INF] Запуск IdentityServer4 версии 2.3 .2 .0 2019 - 03 - 07 01: 19: 30.632 - 06: 00 [INF] Вы используете встроенную память постоянного хранилища грантов. Она будет хранить решения о согласии, коды авторизации, обновления и маркеры ссылок только в памяти. используете какие-либо из этих функций в производстве, вы хотите переключиться на другую реализацию магазина. 2019 - 03 - 07 01: 19: 30.643 - 06: 00 [INF] Использование схема аутентификации по умолчанию idsrv для IdentityServer 2019 - 03 - 07 01: 19: 30.644 - 06: 00 [DBG] Использование idsrv в качестве стандартная схема ASP.NET Core для аутентификации 2019 - 03 - 07 01: 19: 30.644 - 06: 00 [DBG] Использование Identity.External as стандартная схема ASP.NET Core для входа 2019 - 03 - 07 01: 19: 30.645 - 06: 00 [DBG] Использование Identity.External as стандартная схема ASP.NET Core для выхода 2019 - 03 - 07 01: 19: 30.645 - 06: 00 [DBG] Использование idsrv в качестве стандартная схема ASP.NET Core для вызова 2019 - 03 - 07 01: 19: 30.645 - 06: 00 [DBG] Использование idsrv в качестве стандартная схема ASP.NET Core за запрет 2019 - 03 - 07 01: 19: 31.463 - 06: 00 [DBG] Выполнен запрос CORS для пути: /.well-known/openid - конфигурация из источника: http: // localhost: 4200 2019 - 03 - 07 01: 19: 31.468 - 06: 00 [DBG] AllowAll true, поэтому источник: http: // localhost: 4200 разрешен 2019 - 03 - 07 01: 19: 31.468 - 06: 00 [DBG] CorsPolicyService разрешен источник: http: // localhost: 4200 2019 - 03 - 07 01: 19: 31.482 - 06: 00 [DBG] URL для входа в систему: / Личность / Учетная запись / Логин 2019 - 03 - 07 01: 19: 31.482 - 06: 00 [DBG] Login Return Url Параметр: ReturnUrl 2019 - 03 - 07 01: 19: 31.482 - 06: 00 [DBG] URL выхода: / Учетная запись / Выход 2019 - 03 - 07 01: 19: 31.482 - 06: 00 [DBG] ConsentUrl URL: / согласие 2019 - 03 - 07 01: 19: 31.482 - 06: 00 [DBG] URL-адрес возврата согласия: returnUrl 2019 - 03 - 07 01: 19: 31.482 - 06: 00 [DBG] Ошибка URL: / home / error 2019 - 03 - 07 01: 19: 31.482 - 06: 00 [DBG] Error Id Параметр: errorId 2019 - 03 - 07 01: 19: 31.497 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой при снятии защиты с билета 2019 - 03 - 07 01: 19: 31.550 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой при снятии защиты 2019 - 03 - 07 01: 19: 31.553 - 06: 00 [DBG] Путь запроса / .well - известный / openid - конфигурация соответствует типу конечной точки Обнаружение 2019 - 03 - 07 01: 19: 31.569 - 06: 00 Конечная точка [DBG] включена: обнаружение, успешно созданный обработчик: IdentityServer4.Endpoints.DiscoveryEndpoint 2019 - 03 - 07 01: 19: 31.569 - 06: 00 [INF] Вызов конечной точки IdentityServer: IdentityServer4.Endpoints.DiscoveryEndpoint для / .well - известная / openid - конфигурация 2019 - 03 - 07 01: 19: 31.576 - 06: 00 [DBG] Запустить запрос на обнаружение 2019 - 03 - 07 01: 19: 31.885 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение о сбое: сбой при снятии защиты 2019 - 03 - 07 01: 19: 31.885 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение о сбое: сбой при снятии защиты 2019 - 03 - 07 01: 19: 31.885 - 06: 00 [DBG] Запросить путь / подключиться / авторизоваться в соответствии с типом конечной точки Авторизоваться2019 - 03 - 07 01: 19: 31.893 - 06: 00 Конечная точка [DBG] включена: авторизация, успешно созданный обработчик: IdentityServer4.Endpoints.AuthorizeEndpoint 2019 - 03 - 07 01: 19: 31.893 - 06: 00 [INF] Вызов конечной точки IdentityServer: IdentityServer4.Endpoints.AuthorizeEndpoint для / подключения / авторизации 2019 - 03 - 07 01: 19: 31.904 - 06: 00 [DBG] Запустить запрос на авторизацию 2019 - 03 - 07 01: 19: 31.919 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой снятия защиты с билета 2019 - 03 - 07 01: 19: 31.935 - 06: 00 [DBG] В запросе на авторизацию пользователя нет 2019 - 03 - 07 01: 19: 31.945 - 06: 00 [DBG] Начало проверки протокола запроса авторизации 2019 - 03 - 07 01: 19: 31.983 - 06: 00 [DBG] проверка конфигурации клиента для клиента angular_spa удалось. 2019 - 03 - 07 01: 19: 32.069 - 06: 00 [DBG] Вызов в пользовательский валидатор: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019 - 03 - 07 01: 19: 32.099 - 06: 00 [INF] ValidatedAuthorizeRequest { "ClientId": "angular_spa", «ClientName»: «Angular 4 Client», "RedirectUri": "http://localhost:4200/auth-callback", "AllowedRedirectUris": ["http://localhost:4200/auth-callback"," http://localhost:4200/silent-refresh.html"], "SubjectId": "анонимный", "ResponseType": "токен id_token", "ResponseMode": "фрагмент", "GrantType": "неявный", "RequestedScopes": "openid profile api1", "State": "cd6df66e397546d3aab62533de28a2d2", "UiLocales": ноль, «Nonce»: «8b3af6331d784e9a9cad076555f16174», «AuthenticationContextReferenceClasses»: ноль, "DisplayMode": ноль, "PromptMode": ноль, "MaxAge": ноль, "LoginHint": ноль, "SessionId": ноль, "Raw": { "client_id": "angular_spa", "redirect_uri": "http://localhost:4200/auth-callback", "response_type": "id_token token", "scope": "openid profile api1", "state": "cd6df66e397546d3aab62533de28a2d2", "nonce": "8b3af6331d784e9a9cad076555f16174" }, "$ type": "AuthorizeRequestValidationLog" } 2019 - 03 - 07 01: 19: 32.126 - 06: 00 [INF] Отображение логина: пользователь не аутентифицирован 2019 - 03 - 07 01: 19: 32.154 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой снятия защиты с билета 2019 - 03 - 07 01: 19: 32.155 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой снятия защиты с билета 2019 - 03 - 07 01: 19: 32.628 - 06: 00 [INF] Схема аутентификации: Identity.External вышла из системы. 2019 - 03 - 07 01: 19: 40.844 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой снятия защиты с билета 2019 - 03 - 07 01: 19: 40.844 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой снятия защиты с билета 2019 - 03 - 07 01: 19: 41.517 - 06: 00 [INF] AuthenticationScheme: Identity.Application вошел в систему. 2019 - 03 - 07 01: 19: 41.518 - 06: 00 [INF] Пользователь вошел в систему. 2019 - 03 - 07 01: 19: 41.528 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой при снятии защиты 2019 - 03 - 07 01: 19: 41.528 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой при снятии защиты 2019 - 03 - 07 01: 19: 41.528 - 06: 00 [DBG] Путь запроса / подключение / авторизация / обратный вызов, сопоставленный с типом конечной точки Авторизация 2019 - 03 - 07 01: 19: 41.529 - 06: 00 Конечная точка [DBG] включена: авторизация, успешно созданный обработчик: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint 2019 - 03 - 07 01: 19: 41.529 - 06: 00 [INF] Вызов конечной точки IdentityServer: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint для / подключения / авторизации / обратного вызова 2019 - 03 - 07 01: 19: 41.535 - 06: 00 [DBG] Запустить авторизацию обратного вызова 2019 - 03 - 07 01: 19: 41.536 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой при снятии защиты 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [DBG] В запросе на авторизацию пользователя нет 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [DBG] Начало проверки протокола запроса авторизации 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [DBG] проверка конфигурации клиента для клиента angular_spa удалось.2019 - 03 - 07 01: 19: 41.541 - 06: 00 [DBG] Вызов в пользовательский валидатор: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [INF] ValidatedAuthorizeRequest { "ClientId": "angular_spa", «ClientName»: «Angular 4 Client», "RedirectUri": "http://localhost:4200/auth-callback", "AllowedRedirectUris": ["http://localhost:4200/auth-callback"," http://localhost:4200/silent-refresh.html"], "SubjectId": "анонимный", "ResponseType": "токен id_token", "ResponseMode": "фрагмент", "GrantType": "неявный", "RequestedScopes": "openid profile api1", "State": "cd6df66e397546d3aab62533de28a2d2", "UiLocales": ноль, «Nonce»: «8b3af6331d784e9a9cad076555f16174», «AuthenticationContextReferenceClasses»: ноль, "DisplayMode": ноль, "PromptMode": ноль, "MaxAge": ноль, "LoginHint": ноль, "SessionId": ноль, "Raw": { "client_id": "angular_spa", "redirect_uri": "http://localhost:4200/auth-callback", "response_type": "id_token token", "scope": "openid profile api1", "state": "cd6df66e397546d3aab62533de28a2d2", "nonce": "8b3af6331d784e9a9cad076555f16174" }, "$ type": "AuthorizeRequestValidationLog" } 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [INF] Отображение логина: пользователь не аутентифицирован 2019 - 03 - 07 01: 19: 41.552 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой при снятии защиты с билета 2019 - 03 - 07 01: 19: 41.553 - 06: 00 [INF] idsrv не был аутентифицирован. Сообщение об ошибке: сбой при снятии защиты с билета 2019 - 03 - 07 01: 19: 41.553 - 06: 00 [INF] Схема аутентификации: Identity.External вышла из системы.

извините, я попытался правильно отформатировать журналы, но не сработал.

UPDATE

мой серверный конфиг выглядит так

 public class Config
{
    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
{
    new ApiResource("api1", "My API")
};
    }

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
{
    new Client
    {

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


            ClientId = "angular_spa",
            ClientName = "Angular 4 Client",
            AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials ,  //implicit
            AllowedScopes = new List<string> { "openid", "profile", "userInfo", "api1" },

            //AllowedScopes = new List<string> { StandardScopes.OpenId, StandardScopes.Profile, StandardScopes.Email },
     RedirectUris = new List<string> {"http://localhost:4200/auth-callback", "http://localhost:4200/silent-refresh.html"},
            PostLogoutRedirectUris = new List<string> { "http://localhost:4200/" },
            AllowedCorsOrigins = new List<string> { "http://localhost:4200" },
            AllowAccessTokensViaBrowser = true,
            Enabled = true,
            AllowOfflineAccess = true
    }
};
    }
    public static List<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
{
    new IdentityResources.OpenId(),
    new IdentityResources.Profile() // <-- usefull
};
    }
}

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

enter image description here

у него нет контроллеров. Должен ли он иметь?

ОБНОВЛЕНИЕ 2 Похоже, я понял, что не так.

returnUrl не разрешается должным образом в методе POST. это идет как полный URL. если я принудительно верну URL, он будет работать

enter image description here

           var redirect_uri =  HttpUtility.ParseQueryString(returnUrl).Get("redirect_uri");

Я сделал, как указано выше, и использовал переменную 'redirect_uri' в функции Redirect. это работает, но выглядит как взломать. Должен ли он автоматически получить нужную вещь?

с этим я получаю ошибку «Нет состояния в ответе» на угловой стороне, и у oidc-клиента нет пользователя после перенаправления.

UPDATE

похоже, что я использую какой-то другой пакет nuget. HttpContext.SignInAsync имеет следующие конструкторы.

Кажется, мой HttpContext определен в

Microsoft.AspNetCore.Mvc.RazorPages

похоже, что у меня неправильный Nugets или что-то в этом роде. я пытаюсь предоставить правильный ClaimsPrincipal, но не работает.

enter image description here

Ответы [ 2 ]

1 голос
/ 10 марта 2019

Я вижу, что есть некоторая путаница относительно разницы между returnUrl и redirect_uri.Хотя конечной целью является перенаправление на клиентский redirect_uri, после аутентификации клиент должен фактически перенаправить на конечную точку авторизации для дальнейшей обработки (отсюда и причина, по которой URL-адрес другой).Вам вообще не нужно менять returnUrl, и вы можете оставить все как есть.

Проблема, с которой вы сейчас сталкиваетесь, заключается в том, что вы не звоните HttpContext.SignInAsync послеуспешная аутентификация.Метод SignInAsync используется для администрирования куки-файла с информацией пользователя, которая сообщает конечной точке returnUrl, что пользователь был успешно аутентифицирован, и можно вернуть токен в redirect_uri.Для SignInAsync существует множество перегрузок , но я считаю, что проще всего использовать HttpContext.SignInAsync(string subject, params Claim[] claims).После этого вы сможете завершить аутентификацию.

0 голосов
/ 12 марта 2019

Конфигурация сервера идентификации

Установите для RedirectUris URL-адрес вашего углового приложения.

Угловое приложение

openIDImplicitFlowConfiguration.redirect_url= this.oidcConfigService.clientConfiguration.redirect_url;

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