简体   繁体   中英

How do I make my OpenId Connect redirect URI HTTPS on Azure?

I have created 2 web apps that are being hosted in Azure. One app (A) is an IdentityServer4 provider and the other (B) is an app that uses A as an external login provider via OpenId Connect. In the code for A, I configured IdentityServer4 to require a specific redirect URI for B's sign-in calls:

namespace A.IdentityServer4Config
{
    public static class Clients
    {
        public static IEnumerable<Client> GetClients(IConfiguration configuration)
        {
            return new List<Client>
            {
                new Client
                {
                    ClientId = "B",
                    ClientSecrets = {new Secret("hashed secret for B")},
                    AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
                    AllowedScopes = {"openid", "profile", ...},
                    RedirectUris = {"https://B.azurewebsites.net/Account/oidc-callback"},
                    RequireConsent = false,
                    AccessTokenLifetime = 10 * 60,
                },
            };
        }
    }
}

Within Startup.ConfigureServices:

var identityServerBuilder = services
    .AddIdentityServer(options => {...})
    ...
    .AddInMemoryClients(Clients.GetClients(configuration))
    ...;

Notice that the redirect URI I specified is an HTTPS URI.

In the code for B, I used one of the AddOpenIdConnect() overloads in Microsoft.Extensions.DependencyInjection.OpenIdConnectExtensions to configure how the sign-in call should proceed:

services.AddAuthentication(options => {...})
    ...
    .AddOpenIdConnect(
        "oidc",
        options =>
        {
            ...

            options.Authority = "https://A.azurewebsites.net";
            options.RequireHttpsMetadata = true;

            options.ClientId = "B";
            options.ClientSecret = "secret for B";
            options.ResponseType = "code";
            options.CallbackPath = "/Account/oidc-callback"; // !!!

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

            ...
        }
    );

The line commented with "!!!" is where the redirect URI for the sign-in request is configured. Notice that it is required to be a path relative to the application's domain. You cannot specify the URI in full (I tried; if you do this, then the application crashes when it starts up). Since you cannot specify the URI in full, this property cannot be used to require that the redirect URI be HTTPS. (RemoteAuthenticationOptions.CallbackPath is a Microsoft.AspNetCore.Http.PathString. It is described in official documentation as follows: "The request path within the application's base path where the user-agent will be returned. The middleware will process this request when it arrives.")

When I try to log in at B, I am taken to an error page on A. When I look at the logs generated by IdentityServer4 on A, it is clear that the reason for the error is that the redirect URI requested by B does not match the expected one. The only difference between the two URIs is that the one A is expecting to see is an HTTPS URI and the one B is specifying is an HTTP (no "S") URI:

2018-08-16 15:20:41.307 +00:00 [Error] IdentityServer4.Endpoints.AuthorizeEndpoint: Request validation failed
2018-08-16 15:20:41.307 +00:00 [Information] IdentityServer4.Endpoints.AuthorizeEndpoint: {
"ClientId": "B",
"AllowedRedirectUris": [
    "https://B.azurewebsites.net/Account/oidc-callback"
],
"SubjectId": "anonymous",
"RequestedScopes": "",
"Raw": {
    "client_id": "B",
    "redirect_uri": "http://B.azurewebsites.net/Account/oidc-callback",
    "response_type": "code",
    "scope": "openid profile ...",
    "response_mode": "form_post",
    "nonce": "[omitted]",
    "state": "[omitted]",
    "x-client-SKU": "ID_NETSTANDARD1_4",
    "x-client-ver": "5.2.0.0"
}
}
2018-08-16 15:20:41.307 +00:00 [Information] IdentityServer4.Events.DefaultEventService: {
"Name": "Token Issued Failure",
"Category": "Token",
"EventType": "Failure",
"Id": 2001,
"ClientId": "B",
"Endpoint": "Authorize",
"Scopes": "",
"Error": "unauthorized_client",
"ErrorDescription": "Invalid redirect_uri",
"ActivityId": "[omitted]",
"TimeStamp": "2018-08-16T15:20:41Z",
"ProcessId": 10408,
"LocalIpAddress": "[omitted]",
"RemoteIpAddress": "[omitted]"
}

I do not know why B's request to A defaults to HTTP for the redirect URI. I do not know how to make it HTTPS instead. I could relax the requirement that the redirect URI be HTTPS, but this seems like the wrong thing to do. I would like to know how to get B to specify an HTTPS URI in its request to A. From the description of RemoteAuthenticationOptions.CallbackPath in the documentation, I would suppose that this should be achieved by making sure "the application's base path" is HTTPS; however, I have no idea how to do this and have had no success searching the internet.

When I run these applications locally, everything works correctly, because when B is running locally, the requests it makes specify an HTTPS redirect URI (as I wish them to). I do not know why it behaves differently when running locally and when running on Azure.

What I have tried

As mentioned above, I tried specifying the redirect URI fully (instead of in relative terms). This did not work - it causes the application to crash when it starts up.

I also tried setting the CallbackPath type to a PathString constructed using PathString.FromUriComponent() (using a variety of absolute URIs). This did not work. The protocol and domain parts of the URI were discarded and replaced with what they would have been (ie "http" and the appropriate domain) if I had passed a relative URI as a string.

I looked through the Startup classes in the various example MVC clients found at https://github.com/IdentityServer/IdentityServer4.Samples . I did not see anything that was obviously a solution to this problem.

It turns out that on Azure, whether the redirect URI generated is HTTP or HTTPS is determined by the "HTTPS Only" setting in the SSL configuration "blade".

In the Azure web portal, select the app service (B). Under "Settings", select "SSL settings". The SSL configuration "blade" opens. The first option that appears is "HTTPS Only". It defaults to "off". Change it to "on".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM