aspnet / Security

[Archived] Middleware for security and authorization of web apps. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
1.27k stars 600 forks source link

Unable to make external login work #1857

Closed michaelkrog closed 5 years ago

michaelkrog commented 6 years ago

I am unable to get external login to work(Facebook and Google) behind our Edge Proxy. The issue I see is that Google/Facebook says our redirect_uri is wrong.

Our proxy(nginx) terminates the SSL and forwards via HTTP. However, it forwards the X-Forwarded-Proto and original Host header which I understand should be enough for it to generate the correct redirect_uri.

X-Forwarded & Host headers in our Edge Proxy

proxy_set_header Host            $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port 443;

In startup.cs of our Identity Server

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)  {
    .....
    app.UseForwardedHeaders(new ForwardedHeadersOptions {
        ForwardedHeaders = ForwardedHeaders.All
    });
    ....
}

The exception I see from our Identity Server

System.Exception: OAuth token endpoint failure: Status: BadRequest;Headers: Vary: X-Origin, Referer, Origin, Accept-Encoding
Date: Fri, 14 Sep 2018 08:54:54 GMT
Server: ESF
Cache-Control: private
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Alt-Svc: quic=":443"; ma=2592000; v="44,43,39,35"
Accept-Ranges: none
Transfer-Encoding: chunked
;Body: {
  "error": "redirect_uri_mismatch",
  "error_description": "Bad Request"
};
   at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.<HandleRequestAsync>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 IdentityServer4.Hosting.FederatedSignOut.AuthenticationRequestHandlerWrapper.<HandleRequestAsync>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.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.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.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.Server.Kestrel.Core.Internal.Http.Frame`1.<ProcessRequestsAsync>d__2.MoveNext()

Related to https://github.com/aspnet/Security/issues/716.

LindaLawton commented 6 years ago

I can verify that the Redirect URI added in Google is correct for our servers.

We have added both

>http://<our server>/signin-google and https://<our server>/signin-google

When we test with those it fails with the exception my co-worker has posted above.

image

If I remove those from the google developer console. We get the normal Google redirect URI exception.

image

My guess is this is an possibly an internal validation that is throwing the exception. If we send to google that we are sending from https and we get a response back on http then the redirect uri does not match and the internal validation fails.

Identity server 4 start up

 services.AddAuthentication().AddGoogle("Google", options =>
                {
                    options.ClientId = _settings.ThirdPartyLogin.GoogleClientId;
                    options.ClientSecret = _settings.ThirdPartyLogin.GoogleClientSecret;
                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                })
                .AddFacebook("Facebook", facebookOptions =>
                {
                    facebookOptions.SignInScheme = IdentityConstants.ExternalScheme;
                    facebookOptions.AppId = _settings.ThirdPartyLogin.FacebookAppId;
                    facebookOptions.AppSecret = _settings.ThirdPartyLogin.FacebookAppSecret;
                });
Tratcher commented 6 years ago

Side notes:

Can you share a Fiddler trace of the login flow?

Here are some troubleshooting steps for reverse proxies: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1#troubleshoot

LindaLawton commented 6 years ago

@Tratcher thanks for the response.

was a desperate guess on my part as as @michaelkrog said that it was turned into HTTP.

The code I have been using comes directly from Identity server 4 documentation I assumed that it was best practice Adding Support for External Authentication if you have another suggestion i would be happy to give that a try.

Tratcher commented 5 years ago

I'd expect the SignInScheme to be the same for Google and Facebook (ExternalCookieAuthenticationScheme). I don't see anything in the Identity Server docs that says otherwise.

LindaLawton commented 5 years ago

@Tratcher I have changed the code to

services.AddAuthentication()
                    .AddGoogle("Google", options =>
                    {
                        options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                        options.ClientId = _settings.ThirdPartyLogin.GoogleClientId;
                        options.ClientSecret = _settings.ThirdPartyLogin.GoogleClientSecret;
                    })
                    .AddFacebook("Facebook", facebookOptions =>
                    {
                        facebookOptions.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                        facebookOptions.AppId = _settings.ThirdPartyLogin.FacebookAppId;
                        facebookOptions.AppSecret = _settings.ThirdPartyLogin.FacebookAppSecret;
                    });

There is no change. I have mostly been testing with Google and nothing on that has changed.

I have also tried to add troubleshoot to the startup.cs. I was unable to get this to work. I tried running the code ad written and it just loads the following quoted text (running locally) which is not something that I can use to test as we never see the google sign-in button or put up on the server as it will block all users.

Request Method: GET Request Scheme: http Request Path: /UserProfile/index Request Headers: Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9,da;q=0.8 Host: localhost:5000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 Upgrade-Insecure-Requests: 1

Request RemoteIp: 127.0.0.1

I tried to edit it to write to logging

 app.Run(async (context) =>
            {
                //context.Response.ContentType = "text/plain";

                // Request method, scheme, and path
                _logger.LogDebug("Request Method: {context.Request.Method}", context.Request.Method);
                _logger.LogDebug("Request Scheme: {context.Request.Scheme}", context.Request.Scheme);
                _logger.LogDebug("Request Path: {context.Request.Path}", context.Request.Path);

                // Headers
                _logger.LogDebug("Request Headers: ");

                foreach (var header in context.Request.Headers)
                {
                    _logger.LogDebug("{header.Key}: {header.Value}", header.Key, header.Value);
                }

                _logger.LogDebug(Environment.NewLine);

                // Connection: RemoteIp
                _logger.LogDebug("Request RemoteIp: {context.Connection.RemoteIpAddress}");
            });

This blocks the whole site so there will be no way to test anything as it only loads a blank page.

Is there anyway to debug the exception that is being thrown in Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler?

Tratcher commented 5 years ago

If you change app.Run(async (context) => to app.Use(async (context, next) => and then call await next(); at the end then the middleware will not block requests from running.

LindaLawton commented 5 years ago
app.Use(async (context, next) =>
            {
                context.Response.ContentType = "text/plain";

                // Request method, scheme, and path
                await context.Response.WriteAsync($"Request Method: {context.Request.Method}{Environment.NewLine}");
                await context.Response.WriteAsync($"Request Scheme: {context.Request.Scheme}{Environment.NewLine}");
                await context.Response.WriteAsync($"Request Path: {context.Request.Path}{Environment.NewLine}");

                // Headers
                await context.Response.WriteAsync($"Request Headers:{Environment.NewLine}");

                foreach (var header in context.Request.Headers)
                {
                    await context.Response.WriteAsync($"{header.Key}: " +
                                                      $"{header.Value}{Environment.NewLine}");
                }

                await context.Response.WriteAsync(Environment.NewLine);

                // Connection: RemoteIp
                await context.Response.WriteAsync($"Request RemoteIp: {context.Connection.RemoteIpAddress}");
                await next();
            });

Results in

fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HLGUNTSMMTCR", Request id "0HLGUNTSMMTCR:00000001": An unhandled exception was thrown by the application.
System.InvalidOperationException: OnStarting cannot be set because the response has already started.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame.ThrowResponseAlreadyStartedException(String value)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame.OnStarting(Func`2 callback, Object state)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.OnStarting(Func`2 callback, Object state)
   at Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.OnStarting(Func`2 callback, Object state)
   at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.InitializeHandlerAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.<InitializeAsync>d__42.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.Authentication.AuthenticationHandlerProvider.<GetHandlerAsync>d__5.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 IdentityServer4.Hosting.FederatedSignOut.FederatedSignoutAuthenticationHandlerProvider.<GetHandlerAsync>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\FederatedSignOut\FederatedSignoutAuthenticationHandlerProvider.cs:line 33
--- 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.TaskAwaiter`1.GetResult()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.<AuthenticateAsync>d__10.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.TaskAwaiter`1.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 Xena.IdentityServer.Startup.<>c.<<Configure>b__10_0>d.MoveNext() in C:\Development\Xena\xena-identityserver\src\Xena.IdentityServer\Startup.cs:line 342
--- 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.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.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.Server.Kestrel.Core.Internal.Http.Frame`1.<ProcessRequestsAsync>d__2.MoveNext()
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]

I have also added some events to the Google third party settings. Note: I have copied this from a tutorial. I just wanted to see if i could catch what it was doing wrong. As i have still not found a way to debug the exception that is being thrown in Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.

authencationBuilder.AddGoogle("Google", options =>
                    {
                        options.ClientId = _settings.ThirdPartyLogin.GoogleClientId;
                        options.ClientSecret = _settings.ThirdPartyLogin.GoogleClientSecret;
                        // Register to events
                        options.Events = new OAuthEvents
                        {
                            // After OAuth2 has authenticated the user
                            OnCreatingTicket = async context =>
                            {
                                // Create the request message to get user data via the backchannel
                                var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);

                                // Additional header if needed. Here's an example to go through Azure API Management 
                                //request.Headers.Add("Ocp-Apim-Subscription-Key", "<given key>");

                                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                                // Query for user data via backchannel
                                var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted);
                                response.EnsureSuccessStatusCode();

                                // Parse user data into an object
                                var user = JObject.Parse(await response.Content.ReadAsStringAsync());

                                // Store the received authentication token somewhere. In a cookie for example
                                context.HttpContext.Response.Cookies.Append("token", context.AccessToken);

                                // Execute defined mapping action to create the claims from the received user object
                                context.RunClaimActions(JObject.FromObject(user));
                            },
                            OnRemoteFailure = context =>
                            {
                                context.HandleResponse();
                                context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
                                _logger.LogError("OnRemoteFailure {context.Failure.Message}", context.Failure.Message);
                                return Task.FromResult(0);
                            }
                        };
                    })
                    .AddFacebook("Facebook", facebookOptions =>
                    {
                        facebookOptions.AppId = _settings.ThirdPartyLogin.FacebookAppId;
                        facebookOptions.AppSecret = _settings.ThirdPartyLogin.FacebookAppSecret;
                    });

I appreciate your assistance with this i have never had to debug something so deep in the middleware before. The only other idea i have had was to fork it and add some logging and release the forked version to the test server but this seams to be a bit over kill. There must be a way to debug it.

Tratcher commented 5 years ago

I'd meant that app.Use to be combined with your modified version that logged instead of wrote to the response.

LindaLawton commented 5 years ago

The logging isnt telling me much

September 20th 2018, 14:16:20.865   Request Scheme: http    DEBUG   1005
    September 20th 2018, 14:16:20.865   Request Path: /account/login    DEBUG   1005
    September 20th 2018, 14:16:20.865   Request Method: OPTIONS DEBUG   1005
    September 20th 2018, 14:16:20.727   Request RemoteIp: 10.0.0.114    DEBUG   1005
    September 20th 2018, 14:16:20.710   upgrade-insecure-requests: 1    DEBUG   1005
    September 20th 2018, 14:16:20.704   X-Forwarded-Port: 443   DEBUG   1005
    September 20th 2018, 14:16:20.704   X-B3-TraceId: 3e5e32349707677795661b93a9603d9e  DEBUG   1005
    September 20th 2018, 14:16:20.703   X-Forwarded-For: 10.255.0.3 DEBUG   1005
    September 20th 2018, 14:16:20.703   Cookie: .AspNetCore.Correlation.Google.PSOJIhGdQ3Dzg4kuN0cDWyF3wnzUtddwYPFfebMeQ5o=N; _ga=GA1.2.1288449813.1537274158; _gid=GA1.2.679763371.1537274158; lc_sso2129931=1537344285321; XSID=3ktnnrchmzknmvmp30jhvh0n; idsrv.session=3c40a01c3c7002a62d4762bb781728fe; .AspNetCore.Identity.Application=CfDJ8GaVgAXSkP9GgYkQao78wUaI2ZvpRREPyNi0Cv3QHVW_n4Dcb6eSLquRIgmR_8RbEWxPOHJ3XkoT6SauZppqznl1eip5hpT1V-LYHR1htFd2nW4EmB2tN4E4_Y6cT24OjEH14FxtNW58TlGeHYSK3BwwVsY_L2OxdUVYBnRDhnJ7rBuXMla-t5v-B9UtQtc_8i62HzRox9WzUuNWzFoTFG5caFnmm2B6USTbML-wc6RAgjR0dw4cSSWCBuXpLBL33lXyRLml_ql5ZJv_Fiiq_CwNAntVWXbFKZD3NXPWutoVRY__TjfXJ6p9nGMVeswNa10H5F7hqDnmRD1NwLGyDKrEXxdbQpnKzgCQG90WUhdI   DEBUG   1005
    September 20th 2018, 14:16:20.703   Host: logintest.XXXX.biz    DEBUG   1005
    September 20th 2018, 14:16:20.703   X-Forwarded-Proto: https    DEBUG   1005
    September 20th 2018, 14:16:20.703   Referer: https://accounts.google.com/signin/oauth/oauthchooseaccount?client_id=906760000402-jvu30c2n19thoqimd97b4jk1r2poh17p.apps.googleusercontent.com&as=a5faZQYEJ01trnVFan8w9w&destination=https%3A%2F%2Flogintest.xena.biz&approval_state=!ChQ5SGpFbHg3Tzd6LWtOZDNqSjg2ehIfQTE1YWVvWVhrZllhY0t0V0xtY192ZHFZeTR4dVh4WQ%E2%88%99ANKMe1QAAAAAW6ThEJ-OxvvcUDKcZXXV5hojuRkhnRTn&oauthgdpr=1&xsrfsig=AHgIfE8N3YKq9wDWrDAG0h1f0MokjT5AKw&flowName=GeneralOAuthFlow DEBUG   1005
    September 20th 2018, 14:16:20.703   Accept-Language: en-US,en;q=0.9,da;q=0.8    DEBUG   1005
    September 20th 2018, 14:16:20.703   User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 DEBUG   1005
    September 20th 2018, 14:16:20.701   Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8   DEBUG   1005
    September 20th 2018, 14:16:20.701   Accept-Encoding: gzip, deflate, br  DEBUG   1005
    September 20th 2018, 14:16:20.700   Request Headers:    DEBUG   1005
    September 20th 2018, 14:16:20.700   Connection: close

September 20th 2018, 14:16:20.700   Request Scheme: http    DEBUG   1005
    September 20th 2018, 14:16:20.700   Request Path: /signin-google    DEBUG   1005
    September 20th 2018, 14:16:20.700   Request Method: GET DEBUG   1005
    September 20th 2018, 14:16:20.625   Request RemoteIp: 10.0.0.126    DEBUG   1005
    September 20th 2018, 14:16:20.624   X-Forwarded-Proto: https    DEBUG   1005
    September 20th 2018, 14:16:20.624   X-B3-TraceId: 880adf99ad3e35a9c8744af3e896986d  DEBUG   1005
    September 20th 2018, 14:16:20.624   X-Forwarded-Port: 443   DEBUG   1005
    September 20th 2018, 14:16:20.622   Access-Control-Request-Headers: authorization   DEBUG   1005
    September 20th 2018, 14:16:20.622   Access-Control-Request-Method: GET  DEBUG   1005
    September 20th 2018, 14:16:20.622   X-Forwarded-For: 10.255.0.2 DEBUG   1005
    September 20th 2018, 14:16:20.621   Origin: null    DEBUG   1005
    September 20th 2018, 14:16:20.618   Accept-Language: en-US,en;q=0.9 DEBUG   1005
    September 20th 2018, 14:16:20.618   Host: logintest.XXX.biz DEBUG   1005
    September 20th 2018, 14:16:20.618   User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 DEBUG   1005
    September 20th 2018, 14:16:20.617   Accept: */* DEBUG   1005
    September 20th 2018, 14:16:20.617   Accept-Encoding: gzip, deflate, br  DEBUG   1005
    September 20th 2018, 14:16:20.617   Connection: close   DEBUG   1005
    September 20th 2018, 14:16:20.615   Request Method: OPTIONS
Tratcher commented 5 years ago

Was that logging collected before or after UseForwardedHeaders? If it was after then UseForwardedHeaders isn't working at all.

Also, it's very odd that the first request is an OPTIONS request.

LindaLawton commented 5 years ago
 app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.All
        });

Has been part of the application for months so these logs are from today

This is the code i am using for logging exactly

 app.Use(async (context, next) =>
            {
                //context.Response.ContentType = "text/plain";

                // Request method, scheme, and path
                _logger.LogDebug(LoggingEvents.StartupDebugHeaders, "Request Method: {context.Request.Method}", context.Request.Method);
                _logger.LogDebug(LoggingEvents.StartupDebugHeaders, "Request Scheme: {context.Request.Scheme}", context.Request.Scheme);
                _logger.LogDebug(LoggingEvents.StartupDebugHeaders, "Request Path: {context.Request.Path}", context.Request.Path);

                // Headers
                _logger.LogDebug(LoggingEvents.StartupDebugHeaders, "Request Headers:");

                foreach (var header in context.Request.Headers)
                {
                    _logger.LogDebug(LoggingEvents.StartupDebugHeaders, "{header.Key}: {header.Value}", header.Key, header.Value);
                }

                // Connection: RemoteIp
                _logger.LogDebug(LoggingEvents.StartupDebugHeaders, "Request RemoteIp: {context.Connection.RemoteIpAddress}", context.Connection.RemoteIpAddress);
                await next();
            });

I have been told that our logging may not be in the correct order.

Tratcher commented 5 years ago

Right, I was asking about the ordering in Startup. Put your logging after UseForwardedHeaders and before UseAuthentication.

LindaLawton commented 5 years ago

Right we are pushing a new version now with UseForwardedHeaders popped to the top.

LindaLawton commented 5 years ago

This is the best i can find right now. There are to many users on the system and to much logs I cant catch it. I will try and login tonight when most of the users should be gone see if i can catch the other line if this doesnt help

September 20th 2018, 15:34:33.783   Request Method: GET
    September 20th 2018, 15:34:33.782   X-Forwarded-Proto: https
    September 20th 2018, 15:34:33.782   X-Forwarded-Port: 443
    September 20th 2018, 15:34:33.782   User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
    September 20th 2018, 15:34:33.782   Request RemoteIp: 10.0.0.114
    September 20th 2018, 15:34:33.782   X-B3-TraceId: 6c4f54f5fd21a6a0e372b523b54f1ff8
    September 20th 2018, 15:34:33.782   upgrade-insecure-requests: 1
    September 20th 2018, 15:34:33.782   X-Forwarded-For: 10.255.0.7
    September 20th 2018, 15:34:33.780   Host: logintest.xena.biz
    September 20th 2018, 15:34:33.780   Cookie: .AspNetCore.Correlation.Google.hMRoK5ZYSpu-ANl_agUkjAayjImuTFXMqRPPD8OMp7k=N; _ga=GA1.2.1288449813.1537274158; _gid=GA1.2.679763371.1537274158; XSID=3ktnnrchmzknmvmp30jhvh0n; idsrv.session=3c40a01c3c7002a62d4762bb781728fe; lc_sso2129931=1537449987254; .AspNetCore.Identity.Application=CfDJ8GaVgAXSkP9GgYkQao78wUboBtqcIfP0DzXF6SQGfKI6fEa9piQnpbRBUClWmklV25D6FH1CRXLs4skIrafRGjbLeUIRqazSblLO2aC36FHOmZC4HmHGnFu1XysXjnG62zXUf-4H_822HtRQEr6WQ58Bo7XtG-Ju4KC1tENnS35WTbJni8dlu8jzqCo1ySUifks_iTfd-sHiupE3XpNEiIQXkvkpgL9ed2NaYItFB6TffGMdptR0o5TDze3wjhFdwqYqgtoODTGRtcXAPHlXkYXeCIMLCHb45WUyYMQ2vx_RBttL01JRcoVEDuPY3huEr-1ItLuE_DHLd2CqahX9zZ8Dz1DWfaZ-Vw7kz3f8sODi
    September 20th 2018, 15:34:33.780   Referer: https://accounts.google.com/signin/oauth/oauthchooseaccount?client_id=906760000402-jvu30c2n19thoqimd97b4jk1r2poh17p.apps.googleusercontent.com&as=a08wwMPRIQr9R3cgBdQHNw&destination=https%3A%2F%2Flogintest.xena.biz&approval_state=!ChRYaDdERG5KdXdJMWRlRFp6RDVHSxIfUXptcHJZZ0hzalFiY0t0V0xtY192ZHBvRkFkelh4WQ%E2%88%99ANKMe1QAAAAAW6TzZ1IAW8ZQN22_ilI0SjzRd30Keknq&oauthgdpr=1&xsrfsig=AHgIfE-0LXFDvgLXPiiYqJSQah0MR9K3_A&flowName=GeneralOAuthFlow

Would you mind telling me what you are seeing? I was told by our sysadmin that the last set of logs looked fine. Yet you say it doesn't. What are you seeing that we are not?

I am seeing

  September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.114:46004

just before

September 20th 2018, 15:49:44.426  OAuth token endpoint failure: Status: BadRequest;Headers: Vary: X-Origin, Referer, Origin, Accept-Encoding
Date: Thu, 20 Sep 2018 13:49:44 GMT
Server: ESF
Cache-Control: private
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Alt-Svc: quic=":443"; ma=2592000; v="44,43,39,35"
Accept-Ranges: none
Transfer-Encoding: chunked
;Body: {
  "error": "redirect_uri_mismatch",
  "error_description": "Bad Request"
};
Tratcher commented 5 years ago

Ah, yes, that log explains it. You didn't add 10.0.0.114 as a KnownProxies

When forwarders are working then X-Forwarded-Proto: https gets removed and Scheme gets updated to https.

Tratcher commented 5 years ago

@guardrex can you add KnownProxies to the nginx & apache docs. Anybody not using nginx over loopback would have to set that.

guardrex commented 5 years ago

btw - We have a (weak) statement for it in both topics ...

Additional configuration might be required for apps hosted behind proxy servers and load balancers. For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.

I'll have a PR up shortly that will strengthen that remark and call out KnownProxies and KnownNetworks. I'll also make improvements to the Forwarded Headers topic troubleshooting.

I'll ping u on the PR shortly.

michaelkrog commented 5 years ago

I did ponder over that when you linked to the trouble shooting page, but it specifically states the X-FORWARDED-FOR as the only header with that limit. :)

The request's original remote IP must match an entry in the KnownProxies or KnownNetworks lists before X-Forwarded-For is processed. This limits header spoofing by not accepting forwarders from untrusted proxies.

Thanks for the help.

guardrex commented 5 years ago

The preceding line to that one tried to cover it ...

Ensure that the X-Forwarded-* headers are received by the server with the expected values.

... with the asterisk there. I just fleshed that out on the PR.

Ensure that the X-Forwarded-{For|Proto|Host} headers are received by the server with the expected values.

I'll ping u soon on the PR ... almost done, and then you can give me feedback on all of the changes. We want to see if the revisions would have saved you.

Eilon commented 5 years ago

Closing because it seems like the main issue is solved. Thanx!

LindaLawton commented 5 years ago

I added the following at the top of ConfigureServices.

 services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.KnownProxies.Add(IPAddress.Any);
        });

No change

Unknown proxy: 10.0.0.114:34360

Note: There is no way of knowing what the ip address is apparently we have to just allow everything.

Tratcher commented 5 years ago

You don't even know the range so you could set KnownNetworks instead?

Call Clear on KnownProxies and KnownNetworks rather than adding Any.

LindaLawton commented 5 years ago

I asked the system admin he said it could be anything. There is no way of knowing the range. This is actually causing a lot of issues. with antiforgery tokens and its now requiring that we enable dataprotection. Redis appears to no logger be able to run multiple instances.