Redirecting url from Identity server 4 is not beha

2020-03-27 05:13发布

Note : After resolving the redirection issue i had an another issue that is getting an error "Cannot cast Newtonsoft.Json.Linq.JArray to Newtonsoft.Json.Linq.JToken". So in my answer I have provided the correct solution for both.

I have identity server project and the client project, everything works up to authentication without any issues and even it redirects to the correct client url but the url ex : "https://localhost:44309/signin-oidc" gives the blank page.

Note : SSl enabled for Identity Server and Client application.

It is authenticating the user as expected as you can see below in the screen shot. enter image description here My Identity server contains the following config values for client.

                // 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
            }

The startup.cs is as follows.

        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();
    }

Here is the startup.cs for my client app

        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");

            });
    }

Can anyone please try helping me to sort this out.

2条回答
够拽才男人
2楼-- · 2020-03-27 05:45

I had the same problem with having multiple roles. Here is the solution for it:

.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");
});
查看更多
我想做一个坏孩纸
3楼-- · 2020-03-27 05:57

I could resolved this with the help of Identity Server 4 folks. If any one come across this problem here is the solution.

I missed adding "UseAuthentication" in Configure the client MVC pipeline. So after adding that i was redirected as expected and then I had another issue as shown below.

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()

I'm getting this exception while connecting my application to IdentityServer4 with AzureAD as external authentication provider. My application is using Hybrid flow to connect to IdentityServer4. I get properly redirected to Azure, login, and code and id_tokens are properly issued. This exception is raised in my application when userInfo endpoint is invoked.

In order resolve this I had to remove the claim which has the name twice.

I confirmed that AAD sends two name claims. Removing one of them resolved the problem.

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

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

Hope this may help someone.

查看更多
登录 后发表回答