记一次内跨外网部署 Vue.js+ABP 系统

类别:技术 日期:2023-10-25 评论:5

最近研发的一套系统需要跨网络部署,后台(服务器端)部署在局域网内网,而前端(用户界面端)部署在互联网服务器上。内网通过网络地址转换(NAT)技术接收互联网的请求返回数据。

以往部署过几次类似的项目,都是在一个网络环境下,最多遇到一个跨越问题,这次跨网络部署着实让我折腾了好久。

放在互联网服务器上的前端方面的部署是轻车熟路,Vue.js 项目中通过 npm run build 命令打包好放到服务器指定路径下,再到 IIS 中创建一个网站,分配端口指向它即可。

放在内网基于ABP开发的服务器端程序在部署遇到一些问题。

内网服务器操作系统是 Windows Server 2012 R2 , 而我的服务器端的应用是基于比较新的 .Net Core 的 Abp 框架开发的,部署之前就感觉服务器版本较老,可能会有问题,实际操作中确实遇到了。

第一步,安装 IIS,服务器系统默认是没有安装IIS 的,在“打开或者关闭 Windows 功能”的地方安装 IIS ,安装的时候要勾选 ASP.NET 。

第二步,安装好 .Net Core 程序托管捆绑包 dotnet-hosting ,然后在 IIS 中创建一个网站,分配端口,指向部署文件夹,同时将同名应用程序池的 .NET CLR 版本修改为“无托管代码,正常情况下,在浏览器中输入地址应该能打开 swagger 页面了。

结果当时未能显示 swagger 页面,在 IIS 中发现应用程序池总是会自动停掉,通过查阅服务器的事件查看器查看系统日志,发现其中的报错 aspnetcorev2.dll 未能加载,于是网上搜索得知 .Net Core 运行时和托管捆绑包依赖于 Microsoft Visual C ++ 2015 Redistributable ,搜索下载安装得以可以看到swagger页面了。

要插一句,Windows 系统的事件查看器真是个好东西,以前都不知道到这里查找一些程序出错的原因。

第三步,在修改发布文件夹中 appsetting.json 中的数据库连接参数和 App.SelfUrl ,还要将前端的访问地址加到 CorsOrigins 中,以免发生跨越问题。

第四步,处理Token 验证问题,也是折腾我最长时间的问题。

前后台配置好之后,登录界面正常打开了,点击登录,系统没有反应,没有像预期一样跳转到内部页面,也不报错。通过F12开发者工具查看,用户名密码正常提交了,token也正常获取了,一时间我无从下手。

我早先以为是内网向外网网络地址转换给互联网访问的时候,被防火墙拦截了,因为服务器运维人员沟通也不方便,而且目前token已经能获取到了,说明网络已经是畅通的了,于是我决定还是先在程序这里排查。

通过查看系统日志,发现了下面的报错信息:

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10205: Issuer validation failed. Issuer: 'System.String'. Did not match: validationParameters.ValidIssuer: 'System.String' or validationParameters.ValidIssuers: 'System.String'.


似乎是提示Token的issuer验证出问题了。

通过搜索发现这篇文章时候,终于找到了问题所在。

AbpVnext IdentityServer issusr验证失败 - 虎王天下 (xiaowanghu.com)

我这里内网服务器在NAT的时候,给出了一个对外服务的IP,而Abp框架的权限管理组件 IdentityServer 4 在验证token的时候,因为没有手动指定IdentityServer4 IssuerUri 值那么它默认会取访问 IdentityServer4 时的 Host,(一般是localhost),这和这个内网服务器向外服务的的Issuer(对外服务IP)不一致,导致校验不通过。

这里有篇文章讲的很详细,给我解决问题提供了思路:

这种情况一般出现在 IdentityServer4 经过了一层或多层代理,比如 Nginx反代、网关等,外网地址经过代理传递到了 IdentityServer4,如果直接通过外网请求的 Token Endpoint(/connect/token) 生成的 Token,那么这个 Token 携带的 iss 地址将会是外网地址

来源:IdentityServer4实战 - JWT Issuer 详解 - 晓晨Master - 博客园 (cnblogs.com)

解决方法有两个:

方法一:在系统代码中配置不要验证Issuer,这个比较好处理,但是可能安全性有问题,酌情选用。

在 ConfigureAuthentication 方法中的 AddJwtBearer 里面加入下面的语句即可:

options.TokenValidationParameters.ValidateIssuer = false;


方法二:代码中设置 IssuerUri 的值,确保和 token 中解析出来的一致即可,比如:

context.Services.AddIdentityServer(option=>option.IssuerUri="https//6.6.6.6")

到这里,解决了全部的问题,系统得以正常使用。

留言评论

  1. 老张博客 @ 2023-10-27 14:11:43 回复
    你还真的能折腾。
    1. 河边的飞刀 @ 2023-10-28 08:20:16 回复
      工作需求啊~~
  2. 夏日博客 @ 2023-10-29 20:31:25 回复
    看来现在还在用win服务器的不在少数嘛。
  3. hedp @ 2023-10-31 17:21:30 回复
    字都认识,但是不懂。
  4. ccbbp @ 2023-11-02 12:28:57 回复
    这个需求太折腾了

天上的神明和星辰,人间的艺术与真纯,
我们所敬畏和景仰的,莫过于此。

推荐文章
软件作品
微信公号
  • 足球Plus微信公众号
最新留言
友情链接
推荐文章

天上的神明和星辰,人间的艺术与真纯,
我们所敬畏和景仰的,莫过于此。

软件作品
最新留言