Abp vNext 番外篇-疑难杂症丨nginx反向代理-部署
2021-09-13 13:03
1211 查看
缘起
说明:名字用Abp vNext是因为这属于我Abp vNext系列的文章,该问题其实应该属于ids4的部署问题和abp没啥关系。
问题源于周五晚上在和群友聊的时候聊到使用Nginx反向代理后端来做SSL,本来觉得这个问题很简单我就直接部署了一个没想到这就碰到问题了,我的
ids4的issuer出问题了。
大家可以看下面这幅图,我的Scheme分明是Https但是到了issuer却变成了http。
下面是我的nginx,我把
scheme和
X-Forwarded-For都做了配置,但是后端还是拿不到正确的
scheme。
初步方案
我之前我仔细阅读过老张的ids4系列,我记得他讲过这方面的东西,然后我就去翻阅了他的博客,通过手动修改
IssuerUri来解决。
研究文档
我在官方文档看到了这么一句话(建议不要设置此属性,该属性根据主机名推断颁发者名称),我又加以想想发现这样写会存在一个问题,如果我的项目像被多个域名映射岂不是直接歇菜了(当然这个是可以配置的,但是我的想法是约定大于配置,尽量不要去更改这些东西)。
查找根源
我决定自己从源头来看看到底什么原因,我在
IdentityServer4的源码中找到了下面代码,在此我们知道了为啥设置
IssuerUri会生效,另外我们也看到
GetIdentityServerOrigin中的Http来自于
context.Request.Scheme;
/// <summary> /// Gets the identity server issuer URI. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">context</exception> public static string GetIdentityServerIssuerUri(this HttpContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); // if they've explicitly configured a URI then use it, // otherwise dynamically calculate it var options = context.RequestServices.GetRequiredService<IdentityServerOptions>(); var uri = options.IssuerUri; if (uri.IsMissing()) { uri = context.GetIdentityServerOrigin() + context.GetIdentityServerBasePath(); if (uri.EndsWith("/")) uri = uri.Substring(0, uri.Length - 1); if (options.LowerCaseIssuerUri) { uri = uri.ToLowerInvariant(); } } return uri; } public static string GetIdentityServerOrigin(this HttpContext context) { var options = context.RequestServices.GetRequiredService<IdentityServerOptions>(); var request = context.Request; if (options.MutualTls.Enabled && options.MutualTls.DomainName.IsPresent()) { if (!options.MutualTls.DomainName.Contains(".")) { if (request.Host.Value.StartsWith(options.MutualTls.DomainName, StringComparison.OrdinalIgnoreCase)) { return request.Scheme + "://" + request.Host.Value.Substring(options.MutualTls.DomainName.Length + 1); } } } return request.Scheme + "://" + request.Host.Value; } /// <summary> /// Gets the base path of IdentityServer. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> public static string GetIdentityServerBasePath(this HttpContext context) { return context.Items[Constants.EnvironmentKeys.IdentityServerBasePath] as string; }
寻找方案
我在博客园找到了
LouieGuo的一篇文章,他给出了一个官方issues:https://github.com/dotnet/AspNetCore.Docs/issues/2384
其实主要问题就在于
proxy_pass http://172.17.0.8:8000;我们请求会被转发,这里就变成了http请求了,导致
context.Request.Scheme拿到的就是http,解决方案是配置双方(nginx/kestrel)的 X-Forwarded-Proto 让其正确地识别实际用户发出的协议是 http 还是 https。
代码
在
OnApplicationInitialization方法中加入
var forwardOptions = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, }; forwardOptions.KnownNetworks.Clear(); forwardOptions.KnownProxies.Clear(); app.UseForwardedHeaders(forwardOptions);
反馈
@喝口开水
@MrChuJiu nginx反向代理后,实际取得的request.scheme 确实是难以避免的 官方文档虽然说建议不要修改,我认为,还是要结合的你的实际场景。 另外,如果把宿主程序设为https,nginx反向代理到了https的宿主程序。这样虽然可以解决scheme问题,但是额外就是性能损耗 还要浪费多余的CPU时间去加密、解密、https的握手,也带来了带多的损耗 所以,要么就简单一点,直接改配置 要么就用你最后的那个forward方案
反思
这是目前我的一个解决方案,这个方案说实话不是很好,因为对代码有污染,希望大佬如果有更好的方案给我留言蟹蟹!
也欢迎大家阅读我的Abp vNext系列教程
联系作者:加群:867095512 @MrChuJiu
相关文章推荐
- Abp vNext 番外篇-疑难杂症丨浅谈扩展属性与多用户设计
- abp.io(vNext)部署备忘
- 十一、Abp vNext 基础篇丨测试
- 部署nginx反向代理及缓存
- Nginx反向代理和负载均衡部署指南
- vue前后分离项目部署(不同端口号,nginx反向代理解决跨域问题)
- Nginx反向代理和负载均衡部署指南
- nginx反向代理部署nodejs
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)
- Nginx反向代理和负载均衡部署
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
- Centos 部署nginx反向代理
- Linux部署ASP.NET 5 (vNext)
- 初识ABP vNext(5):ABP扩展实体
- 局域网内部署mesos,marathon,通过nginx反向代理访问
- 基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
- Nginx反向代理和负载均衡部署指南
- Nginx反向代理和负载均衡部署指南
- ABP .Net Core API和Angular前端APP集成部署