Перенаправление URL-адреса с сервера идентификации 4 не работает должным образом и не может передать ошибку Newtonsoft.Json.Linq.JArray to Newtonsoft.Json.Linq.JToken

Примечание. После решения проблемы с перенаправлением у меня возникла другая проблема, связанная с ошибкой «Не удается преобразовать Newtonsoft.Json.Linq.JArray в Newtonsoft.Json.Linq.JToken». Поэтому в своем ответе я предоставил правильное решение для обоих.

У меня есть проект сервера идентификации и клиентский проект, все работает до аутентификации без каких-либо проблем, и даже он перенаправляет на правильный URL-адрес клиента, но URL-адрес ex: "https://localhost:44309/signin-oidc" дает пустую страницу.

Примечание. SSL включен для Identity Server и клиентского приложения.

Он аутентифицирует пользователя, как и ожидалось, как вы можете видеть ниже на снимке экрана. введите здесь описание изображения Сервер My Identity содержит следующие значения конфигурации для клиента.

                // OpenID Connect hybrid flow and client credentials client (MVC)
            new Client
            {
                ClientId = "mvc",
                ClientName = "MVC Client",
                AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                ClientSecrets =
                {
                    new Secret("secret".Sha256())
                },

                RedirectUris = { /*"http://localhost:5002/signin-oidc",*/"https://localhost:44309/signin-oidc" },
                PostLogoutRedirectUris = { /*"http://localhost:5002/signout-callback-oidc",*/"https://localhost:44309/signout-callback-oidc" },

                AllowedScopes = 
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    //"api1"
                },
                AllowOfflineAccess = true
            }

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

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

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

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

            //    options.ClientId = "434483408261-55tc8n0cs4ff1fe21ea8df2o443v2iuc.apps.googleusercontent.com";
            //    options.ClientSecret = "3gcoTrEDPPJ0ukn_aYYT6PWo";
            //})
            .AddOpenIdConnect("oidc", "dataVail Login", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

                options.SignOutScheme = IdentityServerConstants.SignoutScheme;

                options.Authority = "https://login.microsoftonline.com/d0e2ebcc-0961-45b2-afae-b9ed6728ead7";//"https://demo.identityserver.io/";
                options.ClientId = "f08cc131-72da-4831-b19d-e008024645e4";
                options.UseTokenLifetime = true;
                options.CallbackPath = "/signin-oidc";
                options.RequireHttpsMetadata = false;

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

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

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        app.Use(async (context, next) =>
        {
            context.Request.Scheme = "https";
            await next.Invoke();
        });
        app.UseIdentityServer();

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

Вот файл startup.cs для моего клиентского приложения.

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

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";

                options.Authority = "https://localhost:44392/";
                options.RequireHttpsMetadata = false;

                options.ClientId = "mvc";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";

                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                //options.Scope.Add("api1");
                options.Scope.Add("offline_access");

            });
    }

Может кто-нибудь, пожалуйста, попробуйте помочь мне разобраться в этом.


person Arshath Shameer    schedule 21.05.2018    source источник


Ответы (2)


Я мог решить эту проблему с помощью людей Identity Server 4. Если кто-то сталкивался с этой проблемой, вот решение.

Я пропустил добавление «UseAuthentication» в «Настроить клиентский конвейер MVC». Итак, после добавления, что я был перенаправлен, как и ожидалось, а затем у меня возникла другая проблема, как показано ниже.

System.InvalidCastException: Cannot cast Newtonsoft.Json.Linq.JArray to Newtonsoft.Json.Linq.JToken. at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.<Invoke>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

Я получаю это исключение при подключении моего приложения к IdentityServer4 с помощью AzureAD в качестве внешнего поставщика проверки подлинности. Мое приложение использует гибридный поток для подключения к IdentityServer4. Я правильно перенаправляюсь в Azure, логин, код и id_tokens выдаются правильно. Это исключение возникает в моем приложении, когда вызывается конечная точка userInfo.

Чтобы решить эту проблему, мне пришлось дважды удалить претензию с таким именем.

Я подтвердил, что AAD отправляет две заявки на имя. Удаление одного из них решило проблему.

var namesClaim = externalUser.FindFirst(ClaimTypes.Name) ??
                             throw new Exception("Unknown names");

if (namesClaim!=null)
{
    claims.Remove(namesClaim);
}

Надеюсь, это может помочь кому-то.

person Arshath Shameer    schedule 22.05.2018
comment
Не могли бы вы уточнить, где будет подключаться код для удаления дополнительных претензий? - person Ilya; 31.05.2018
comment
@Ilya Если у вас загружен образец IdentityServer 4, вы должны найти место, где должен быть размещен этот код фрагмента, и это место находится в методе Quickstart.Account.AccountController.FindUserFromExternalProvider(). - person Arshath Shameer; 01.06.2018

У меня была такая же проблема с несколькими ролями. Вот решение для него:

.AddOpenIdConnect("oidc", options =>
{
    // ...
    options.Scope.Add("roles");

    // ... using MapJsonKey instead of MapUniqueJsonKey for having 2 or more roles
    options.ClaimActions.MapJsonKey(claimType: "role", jsonKey: "role");
});
person VahidN    schedule 14.03.2019