为什么IdentityServer重定向到http而不是https?

时间:2017-09-04 11:03:58

标签: identityserver3 openid-connect appharbor

我有一个非常简单的MVC5网站,我试图使用IdentityServer3保护。

我的网站和IdentityServer实例都作为AppHarbor中的单独站点托管。两者都落后于https。

当我点击我的网站中受[Authorize]属性保护的资源(例如/Home/About)时,我已成功重定向到IdentityServer,我可以成功进行身份验证。

当IdentityServer将其响应发回网站时(通过app.FormPostResponse.js),网站会响应302重定向到所请求的资源 - 正如预期的那样。但是,此重定向是 http ,而不是https(请参阅下面的网络跟踪)。

我确定这只是我的IdentityServer配置有问题,但我很感激任何关于我出错的指示。

(AppHarbor在IIS前面使用反向代理(我相信是nginx),SSL终止 - 所以我根据IdentityServer文档为此方案RequireSsl = false。)

这是我的网站Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            Authority = "https://<my-idsrv3>.apphb.com/identity",

            ClientId = "<my-client-id>",
            Scope = "openid profile roles email",
            RedirectUri = "https://<my-website>.apphb.com",
            ResponseType = "id_token",

            SignInAsAuthenticationType = "Cookies",

            UseTokenLifetime = false
        });

        JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
    }
}

这是我的IdentityServer3实例中的Startup.cs:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Map("/identity", idsrvApp =>
        {
            idsrvApp.UseIdentityServer(new IdentityServerOptions
            {
                SiteName = "My Identity Server",
                SigningCertificate = Certificates.LoadSigningCertificate(),
                RequireSsl = false,
                PublicOrigin = "https://<my-idsrv3>.apphb.com",

                Factory = new IdentityServerServiceFactory()
                    .UseInMemoryUsers(Users.Get())
                    .UseInMemoryClients(Clients.Get())
                    .UseInMemoryScopes(Scopes.Get())
            });
        });
    }
}

以下是我的网站客户端的定义:

new Client
{
    Enabled = true,
    ClientName = "My Website Client",
    ClientId = "<my-client-id>",
    Flow = Flows.Implicit,

    RedirectUris = new List<string>
    {
        "https://<my-website>.apphb.com"
    },

    AllowAccessToAllScopes = true
}

点击&#39;是,允许&#39;来自Chrome的跟踪。在IdentityServer许可屏幕上:

Chrome network trace

2 个答案:

答案 0 :(得分:4)

所以看起来这个问题是由我的客户端网站支持SSL终止nginx前端造成的。

参考this GitHub issue,我在网站的应用配置开头添加了以下内容:

app.Use(async (ctx, next) =>
{
    string proto = ctx.Request.Headers.Get("X-Forwarded-Proto");
    if (!string.IsNullOrEmpty(proto))
    {
        ctx.Request.Scheme = proto;
    }
    await next();
});

这使网站意识到传入的请求超过了https;这反过来似乎确保IdentityServer3中间件生成https uri's。

答案 1 :(得分:1)

在Azure App Service中运行identityserver4时出现相同的问题。即使强制使用https,在.well-known/openid-configuration中生成的网址仍然是http://

使用与其他答案相同的解决方案,但使用AspNetCore ForwardedHeadersExtensions

var forwardOptions = new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
    // Needed because of mixing http and https.
    RequireHeaderSymmetry = false,
};

// Accept X-Forwarded-* headers from all sources.
forwardOptions.KnownNetworks.Clear();
forwardOptions.KnownProxies.Clear();

app.UseForwardedHeaders(forwardOptions);

有关此主题的更多讨论,另请参见https://github.com/IdentityServer/IdentityServer4/issues/1331