为什么在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。示例发布的项目代码需要绝对的,以便我们可以运行这些测试
在所有头发从我们的头上拔掉之前,任何帮助将不胜感激!
答案 0 :(得分:1)
解决方案是停止使用IIS,而将Nginx用作反向代理。但是我们从未设法找出在IIS rev proxy和Oidc客户端后面使用IDS4时有什么特别的区别。
有关我们测试的内容的更多详细信息,可以在这里找到:-
https://github.com/IdentityServer/IdentityServer4/issues/2478