IIS反向代理后面的Identityserver4时,不重定向回JsOidc客户端

时间:2018-07-23 11:16:56

标签: reverse-proxy identityserver4 oidc

为什么在IIS反向代理后面时IdentityServer4不重定向回JsOidc客户端,而其他客户端却按预期工作?

测试设置

下载了IdentityServer4.Samples版本

使用\ Quickstarts \ 6_AspNetIdentity在VS2017中进行安装测试

然后从\ Clients \ src \ JsOidc将JsOidc客户端添加到解决方案中

IdentityServer4正常运行(因为我们应该什么都不要更改)

所有客户端(MvcClient,ResourceOwner,Client和JsOidc)均按预期工作,并通过localhost:5000上的IdentityServer4进行身份验证

从IS4到客户端的所有重定向(redirect_uri)正常运行

所有API调用均按预期工作

到目前为止非常好:-)

然后,我们将IIS设置为localhost:5000上具有有效SSL的域名的IIS作为IdentityServer4的反向代理(因此浏览器中没有警告)

已配置IdentityServer4以使用ForwardHeaders中间件-IE应用程序。UseForwardedHeaders(等...)

已配置IIS来设置相关的服务器变量(例如HTTP_X_FORWARDED_HOST,HTTP_X_FORWARDED_PROTO,HTTP_X_FORWARDED_PORT)

web.config中的IIS重写规则(已更新):-

    <rewrite>
        <rules>
            <rule name="ReverseProxyInboundRule1" stopProcessing="true">
                <match url="(.*)" />
                <action type="Rewrite" url="http://localhost:5000/{R:1}" />
                <serverVariables>
                    <set name="HTTP_X_FORWARDED_HOST" value="{HTTP_HOST}" />
                </serverVariables>
            </rule>
        </rules>
        <outboundRules>
            <rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
                <match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:5000/(.*)" />
                <action type="Rewrite" value="http{R:1}://www.wholesalesolar.co.uk/{R:2}" />
            </rule>
            <preConditions>
                <preCondition name="ResponseIsHtml1">
                    <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
                </preCondition>
            </preConditions>
        </outboundRules>
    </rewrite>

在选项中将IdentityServer4配置为使用新域作为PublicOrigin

更新了所有客户端,以使用新的htt ps://mytestdomain.com作为授权

确保迪斯科文档使用新域而不是localhost,并且所有重写均正常工作

这是我的IdentityServer项目的Startup.cs类

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddMvc();

        services.Configure<IISOptions>(iis =>
        {
            iis.AuthenticationDisplayName = "Windows";
            iis.AutomaticAuthentication = false;
        });

        // Changed Builder to idsBuilder
        var ids4Builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
                options.PublicOrigin = "https://www.wholesalesolar.co.uk"; // Added this
            })
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddAspNetIdentity<ApplicationUser>();

        if (Environment.IsDevelopment())
        {
            ids4Builder.AddDeveloperSigningCredential();
        }
        else
        {
            throw new Exception("need to configure key material");
        }

        services.AddAuthentication()
          .AddGoogle(options =>
          {
              options.ClientId = "708996912208-9m4dkjb5hscn7cjrn5u0r4tbgkbj1fko.apps.googleusercontent.com";
              options.ClientSecret = "wdfPY6t8H8cecgjlxud__4Gh";
          });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        // New code
        var forwardedHeadersOptions = new ForwardedHeadersOptions()
        { 
            ForwardedHeaders =
                ForwardedHeaders.XForwardedFor |
                ForwardedHeaders.XForwardedProto |
                ForwardedHeaders.XForwardedHost


        };
        forwardedHeadersOptions.KnownNetworks.Clear();
        forwardedHeadersOptions.KnownProxies.Clear();
        app.UseForwardedHeaders(forwardedHeadersOptions);
        // End new code

        app.UseStaticFiles();
        app.UseIdentityServer();
        app.UseMvcWithDefaultRoute();
    }

现在在IIS反向代理后面添加IdentityServer4:-

在localhost:5002上测试了MvcClient-一切正常

测试了ResourceOwnerClient-一切正常

测试了客户端客户端-一切正常

测试了JsOidc客户端-无法从IdentityServer4重定向回客户端

有关JsOidc的更多测试详细信息

IdentityServer4日志中没有错误或警告

用于测试的浏览器(Chrome,FF,Edge等)中没有控制台错误或警告

使用提琴手,我们比较了反向代理之前和之后的会话。除了主持人,一切看起来都一样

使用提琴手,我们仔细检查了迪斯科文件

要完全确定IIS是否正常工作,我将IIS中的HTTP_X_FORWARDED_HOST更改为:-

HTTP_X_FORWARDED_HOST ='a_domian_that_doesnt_exist.com',并且IdentityServer无法重定向回MvcClient

然后将其更改回HTTP_X_FORWARDED_HOST ='{HTTP_HOST}'并重定向到MvcClient再次正常工作

总而言之

IdentityServer服务器使用正确的网页但使用不正确的主机,而不是重定向回JsOidc客户端主机。

登录URL(IdentityServer MVC应用)如下所示:-

htt ps://mytestdomain.com/account/login?returnUrl = / connect / authorize / callback?client_id = js_oidc&redirect_uri = htt p:// localhost: 7017 / callback.html&response_type = id_token&scope = openid&state = blahblah&nonce = blahblah

错误的重定向网址(成功登录后)如下所示:-

htt ps://mytestdomain.com/callback.html#id_token=eyJhbGciOiJSUzI1NiIsImtpZCIetc ...

URL应为:-

htt p:// localhost:7017 / callback.html#id_token = eyJhbGciOiJSUzI1NiIsImtpZCIetc .....

测试客户端(来自IdentityServer4.Samples-release / Clients / src / JsOidc)使用oidc-client.js库

我们还有一个使用https://github.com/damienbod/angular-auth-oidc-client库的Angular 6客户程序,该库表现出相同的行为

我们仅更改 IdentityServer4。示例发布的项目代码需要绝对的,以便我们可以运行这些测试

在所有头发从我们的头上拔掉之前,任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

解决方案是停止使用IIS,而将Nginx用作反向代理。但是我们从未设法找出在IIS rev proxy和Oidc客户端后面使用IDS4时有什么特别的区别。

有关我们测试的内容的更多详细信息,可以在这里找到:-

https://github.com/IdentityServer/IdentityServer4/issues/2478