Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

Why redirect_uri is not HTTPs while AllowedRedirectUris it is? #2101

Closed
babakarj opened this issue Feb 23, 2018 · 9 comments
Closed

Why redirect_uri is not HTTPs while AllowedRedirectUris it is? #2101

babakarj opened this issue Feb 23, 2018 · 9 comments

Comments

@babakarj
Copy link

babakarj commented Feb 23, 2018

Both https://store.example.com/ and https://auth.example.com/ are hosted on Ubuntu server behind NGINX as a proxy server. While trying to authenticate store application we get this error from auth application.

Why redirect_uri is not in HTTPs?

Things are going fine in the development machines.

Relevant parts of the log file

info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize
fail: IdentityServer4.Validation.AuthorizeRequestValidator[0]
      Invalid redirect_uri: http://store.example.com/signin-oidc
      {
        "ClientId": "ExampleStore",
        "ClientName": "Example Web Store",
        "AllowedRedirectUris": [
          "https://store.example.com/signin-oidc"
        ],
        "SubjectId": "anonymous",
        "RequestedScopes": "",
        "Raw": {
          "client_id": "ExampleStore",
          "redirect_uri": "http://store.example.com/signin-oidc",
          "response_type": "code id_token",
          "scope": "openid profile offline_access",
          "response_mode": "form_post",
          "nonce": "63654994155394........",
          "state": "CfDJ8CYgFY5U.........",
          "x-client-SKU": "ID_NET",
          "x-client-ver": "2.1.4.0"
        }
      }
fail: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      Request validation failed
@chrisowhite
Copy link
Contributor

As far as validation, IdentityServer4 is simply taking the string value of redirect_uri from the request and doing and exact comparison to those registered in the allowed URIs. What does the HTTP request look like going to NGINX?

@babakarj
Copy link
Author

Here is the NGINX log:

in the second line the redirect_uri is not HTTPs!

"GET /User/Login HTTP/1.1" 302 0 "https://store.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
"GET /connect/authorize?client_id=ExampleStore&redirect_uri=http%3A%2F%2Fstore.example.com%2Fsignin-oidc&response_type=code%20id_token&scope=openid%20profile%20offline_access&response_mode=form_post&nonce=636550474179999101.N...&x-client-SKU=ID_NET&x-client-ver=2.1.4.0 HTTP/1.1" 302 0 "https://store.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
"GET /home/error?errorId=CfDJ8CYgFY5UTdRDj_QRgW3... HTTP/1.1" 200 2342 "https://store.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"

And the configuration:

server {
    if ($host = auth.example.com) {
        return 301 https://$host$request_uri;
    }

    listen      80;
    server_name auth.example.com;
    return 404;
}

server {
    if ($host = store.example.com) {
        return 301 https://$host$request_uri;
    }

    listen      80;
    server_name store.example.com;
    return 404;
}

server {
    server_name auth.example.com;

    location / {
		proxy_pass  http://localhost:5000;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_redirect    off;
	}

    listen 443 ssl;
    ssl_certificate ...
    ssl_certificate_key ...
    include ...
    ssl_dhparam ...
}

server {
    server_name store.example.com;

    location / {
		proxy_pass  http://localhost:5001;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_redirect    off;
	}

    listen 443 ssl;
    ssl_certificate ...
    ssl_certificate_key ...
    include ...
    ssl_dhparam ...
}

@chrisowhite
Copy link
Contributor

Then appears your client application at store.example.com is not sending the correct scheme when it redirects the user agent to the authorize endpoint.

See here, and make sure your client application is configured to respect the X-ForwardedProto header.
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?tabs=aspnetcore2x

@babakarj
Copy link
Author

babakarj commented Feb 24, 2018

I just changed these lines:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect    off;

to:

proxy_set_header        Host                    $http_host;
proxy_set_header        X-Real-IP               $remote_addr;
proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Ssl         on;
proxy_set_header        X-Forwarded-Proto       https;
proxy_set_header        X-Forwarded-Host        $host;
proxy_set_header        X-Forwarded-Server      $host;
add_header              Front-End-Https         on;
proxy_redirect          off;

Now, it goes to auth from store and successfully authenticates but the auth app POST to http://store.example.com/signin-oidc instead of https://store.example.com/signin-oidc (mind the s in HTTPs)

Here is the header:

var forwardOptions = new ForwardedHeadersOptions
{
	ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
	RequireHeaderSymmetry = false
};
forwardOptions.KnownNetworks.Clear();
forwardOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardOptions);

What is this, now?! Any idea?

Auth app log:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 117.7292ms 200 text/html; charset=UTF-8
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.0 POST http://auth.example.com/connect/token application/x-www-form-urlencoded 279
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token
info: IdentityServer4.Validation.TokenRequestValidator[0]
      Token request validation success
      {
        "ClientId": "ExampleStore",
        "ClientName": "Example Web Store",
        "GrantType": "authorization_code",
        "AuthorizationCode": "6fab1723...",
        "Raw": {
          "client_id": "ExampleStore",
          "client_secret": "***REDACTED***",
          "code": "6fab1723...",
          "grant_type": "authorization_code",
          "redirect_uri": "https://store.example.com/signin-oidc"
        }
      }
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 182.8022ms 200 application/json; charset=UTF-8
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.0 GET http://auth.example.com/connect/userinfo
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.UserInfoEndpoint for /connect/userinfo
info: IdentityServer4.ResponseHandling.UserInfoResponseGenerator[0]
      Profile service returned to the following claim types: sub preferred_username name
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 57.1394ms 200 application/json; charset=UTF-8

Store app log:

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: (null).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
      Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[12]
      AuthenticationScheme: oidc was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action Nihonto.Web.Store.Controllers.UserController.Login (Nihonto.Web.Store) in 8.1968ms
info: Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware[27]
      The response could not be cached for this request.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 11.2816ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.0 POST http://store.example.com/signin-oidc application/x-www-form-urlencoded 1485
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
      AuthenticationScheme: ExampleCookie signed in.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 301.361ms 302

@chrisowhite
Copy link
Contributor

SSL termination is happening at NGINX. The headers are informing your app that it's behind a proxy using SSL, and should treat the request as such.

@babakarj
Copy link
Author

I'm confused. Would you, please, explain more?
Getting 502 Bad Gateway from NGINX.

@chrisowhite
Copy link
Contributor

This is not an IdentityServer4 issue and really belongs in a different repository. Probably https://github.com/aspnet/KestrelHttpServer

@babakarj
Copy link
Author

The problem has been solved. It wasn't a Kestrel problem, it seems that NGINX doesn't allow a large header. From this help https://medium.com/@mshanak/solve-nginx-error-signin-oidc-502-bad-gateway-dotnet-core-and-identity-serve-bc27920b42d5 , we have set these properties:

nginx.conf

http{
...
proxy_buffer_size   128k;
proxy_buffers   4 256k;
proxy_busy_buffers_size   256k;
large_client_header_buffers 4 16k;
...
}

default.conf

location /{
    ...
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
    ...
}

@chrisowhite , would you tell us more why we have set those properties and there is any way to configure IdentityServer to send much smaller header content?

@lock
Copy link

lock bot commented Jan 13, 2020

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.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants