IdentityServer / IdentityServer4

OpenID Connect and OAuth 2.0 Framework for ASP.NET Core
https://identityserver.io
Apache License 2.0
9.22k stars 4.01k forks source link

signin-oidc 500 error #3097

Closed hasmyr closed 5 years ago

hasmyr commented 5 years ago

I am having an issue when redirecting to signin-oidc after the consent page. Locally I have no issues I can Login -> Consent -> signin-oidc -> redirected to landing page no problem with all cookies updated properly.

However, when the server is deployed in AWS Fargate it does not work. I am not sure if this is middleware related or IS4 related, but I can connect to the test IS4 server https://demo.identityserver.io/ without issue.

I am using the same Config and TestUsers with InMemory settings from https://github.com/IdentityServer/IdentityServer4.Demo.

Here is the startup on my IS4 server:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<IdentityContext>(options => options.UseNpgsql(Configuration.GetConnectionString("IdentityContext")));
        services.AddDbContext<MultitenancyContext>(options => options.UseNpgsql(Configuration.GetConnectionString("MultitenancyContext")));

        // Add identity services to handle user login
        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<IdentityContext>()
            .AddDefaultTokenProviders();

        if (!HostingEnvironment.IsDevelopment())
        {
            services.AddSingleton<IAmazonS3>(new AmazonS3Client(RegionEndpoint.USEast1));
            services.AddSingleton<IAmazonKeyManagementService>(new AmazonKeyManagementServiceClient(RegionEndpoint.USEast1));
            services.AddDataProtection()
                .SetApplicationName("accunet-web")
                .ProtectKeysWithAwsKms(Configuration.GetSection("DataProtectionKms"))
                .PersistKeysToAwsS3(Configuration.GetSection("DataProtectionS3"));
        }

        services.AddOptions();

        services.AddMvc();

        services.AddTransient<IUnitOfWork, UnitOfWork>();

        services.AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents = true;
            options.Events.RaiseFailureEvents = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseSuccessEvents = true;
        })
            .AddInMemoryApiResources(Config.GetApis())
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryClients(Config.GetClients())
            .AddTestUsers(TestUsers.Users)
            .AddDeveloperSigningCredential(persistKey: false);
    }

And the startup from my test client website, which I have deployed to Azure along with localhost testing:

public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>()
            .AddDefaultUI(UIFramework.Bootstrap4)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookie";
                options.DefaultChallengeScheme = "challenge";
            })
            .AddCookie("Cookie")
            .AddOpenIdConnect("challenge", options =>
            {
                options.Authority = "http://auth.is4server.com";
                options.SignInScheme = "Cookie";
                options.RequireHttpsMetadata = false;
                options.ClientId = "server.hybrid";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;
                options.Scope.Add("offline_access");
                options.Scope.Add("profile");
                options.Scope.Add("openid");
            });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

These two systems work fine locally, but when deployed I get the error:

System.Exception: An error was encountered while handling the remote login. ---> Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_request', error_description: 'error_description is null', error_uri: 'error_uri is null'.
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RedeemAuthorizationCodeAsync(OpenIdConnectMessage tokenEndpointRequest)
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

The only difference I can see is locally it is redirecting to signin-oidc with Type : x-www-form-urlencoded, which works properly.

But on the depolyed IS4 server it redirects with Type : document and gets a 500 error. But the headers still have all of the information I need, but signin-oidc does not accept the form and fails. I am looking into having my own signin-oidc endpoint instead of using the middleware but I want this to be easily adaptable for my clients to use my IS4 server.

Any help would be much appreciated as I have been struggling with this for a couple days.

hasmyr commented 5 years ago

My .well-known/openid-connect settings for my page all have addresses that start with http. However, my website on AWS redirects all http requests to https. Could this be causing an issue with the middleware?

thiagomoisespass commented 5 years ago

Did you solve it? I have the same problem

hasmyr commented 5 years ago

Yes, I set the PublicOrigin to the https address, this prevented the redirect in AWS and solved the issue.

thiagomoisespass commented 5 years ago

It worked. Thank you very much. I was fighting with this two days ago.

dfernandez9857 commented 5 years ago

I add this code in my Identity Server, but I have the same problem.

 services.AddIdentityServer(options =>
            {
                options.PublicOrigin = "https://xx.xx.com";
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseSuccessEvents = true;
            })

Do I have to make another change in my client?

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.