JBoss 项目修复笔记:绕开 iframe 安全问题,JSF 与 Angular 最小代价共存方案

JBoss 项目修复笔记:绕开 iframe 安全问题,JSF 与 Angular 最小代价共存方案

本篇笔记衔接的内容为:JBoss + WildFly 本地开发环境完全指南,里面简单的描述了一下怎么配置 docker,在本地启动一个可以运行的 JBoss 和 WildFly 服务器,接下来就简单描述一下想要解决的问题,以及目前看来比较可靠的解决方法

前言- 背景介绍 & 目标

简单的 recap 一下,我们现在的问题是:

  • 前端还在使用 JSF
    毕竟这是一个老项目了,还在 active support 这个项目的那段时光里,JSF 毕竟还是主流
  • 前端尝试使用 AngularJS
    是 AngularJS,不是 Angular;是 1.x 的版本,不是 2.0+。当时的开发大概是感受到了 JSF 混合 xhtml 的问题——冗长、结构特别复杂、沉重并难以增添新的功能。再搭配上 AngularJS 的确是有 Google 背书,也出现了不少社区支持的 packages,比如说 ng-grid,ng-table 之类,实现起来比春写 JSF 要容易不少
    目前来说我并没有打算深挖 AngularJS 的打算,毕竟我开始做的时候就做 SPA 了,虽然简单的碰过一点 Angular 的内容,也写了点笔记,不过毕竟不是主营
  • 使用 iframe 导入 AngularJS 实现的页面
    这里主要的问题在于,主 xhtml 和使用 iframe 导入的 AngularJS 页面并不分享一个共同的 context,session id 需要通过 URL 明文传到 AngularJS 页面中,最终也是导致了 InfoSec team 给我们好多个 tickets,不能搞定这些安全隐患,那么也就影响现在的生产环境
    当然,这里也有其他的问题,比如说导入非常的散乱,控制器(angular controller)也散的到处都是。不过因为业务相对简单,这种问题还是可以解决的,而且也不是 red flag 🚩,暂时睁一只眼闭一只眼就可以了

鉴于当前的项目也快进入 EOL 了 这种项目提了多少年 EOL 了,什么时候真的 EOL 也不知道,因此当前的目标就是:

  • 最小规模的修改代码,即不动原有的框架结构、文件路径等
    这也可以保证不需要动其他的 xml 文件和 pom 文件,复用原本的 build process
  • 顺利移除 iframe
    这里最大的问题在于 iframe 和主 xhtml 不分享一个 context,那么,如果可以把原本 iframe 运行的内容,放到 xhtml 中,原本的 session 就可以共享,剩下的生命周期流程也可以交给 java 去管理
  • 直接在 xhtml 文件里运行 angular
    这里其实有蛮多的问题的

项目复刻

首先看一下现在的结构:

这里主要修改的就是 webapp/webapp 下面的内容, app 中的是 angular.html 运行的 controller, lib/angular 下面是 angular 官方的 js 和 css 文档, index.xhtml 是 entry point, original.xhtml 是使用 iframe 的 copy,大体结构如此

具体的代码如下:

  • main.controller.js
    这里的代码比较短,主要内容如下:

    (function () {"use strict";angular.module("demoApp", []).controller("MainController", ["$scope",function ($scope) {$scope.title = "🚀 AngularJS 1.3.17 Demo Page";$scope.userInput = "";$scope.items = ["banana", "apple", "mongo"];$scope.addItem = function () {$scope.items.push("new item " + ($scope.items.length + 1));};},]);
    })();
    

    这个写过 Angular 的人多多少少会有点眼熟,Angular 的实现——尽管内部完全不同,但是从实用的角度上来说,还是比较相似的:

    • module 就是新建一个 module,后面的 array 与依赖有关,大体对标的是 NgModule
    • controller 对标的大体就是 controller 中的内容,里面的实现大体对标的事 @Component 中的实现
    • $scope 中可以绑定的就是各种的变量和方法
      整体上可以看出来,AngularJS → Angular 虽然实现方法是完全推翻了,但是核心的实现概念还是一致的。2+比起 1 来说更加的类型安全——感谢 TypeScript 带来的安全感,使用起来也更加的灵活,毕竟:
    • 2+使用的是 TS,而且在编译时进行变量和方法的校验;1 则是使用 JS,运行时动态绑定
    • 2+使用的是 class+decorator 的方法;1 使用的是 controller+scope 的方法
    • 2+默认的是单向绑定,双向绑定需要使用 [(ngModel)];1 默认开启双向绑定,没有什么特别好的选择
    • 2+模板需要 controller 和 view 进行 MVVM 的交流;1 基本在 HTML 中写 template
      我个人感觉,小范围内的项目,1 的写法可能会更方便一些,但是一代码量比较大,或者是陌生的代码,那么 1 找对应的逻辑就比较头疼
      2+的写法虽然相对而言更麻烦一点,不过基于 TS 的检查,以及现代编辑器/IDE 对于 Angular 项目的良好支持,通过查找使用的 reference,和直接点击变量,在 controller 和 view 层来回切换,查找逻辑反而没有那么的困难
  • lib
    这里的内容可以从官方文档里找:https://code.angularjs.org/
    按需下载即可

  • angular.html
    一个简单的 demo,作为 iframe 的导入对象使用,代码如下:

    <!DOCTYPE html>
    <html lang="en" ng-app="demoApp"><head><meta charset="UTF-8" /><title>AngularJS 1.3 Demo</title><link rel="stylesheet" href="lib/angular/angular-csp.css" /><script src="lib/angular/angular.js"></script><script src="app/main.controller.js"></script></head><body ng-controller="MainController"><div style="padding: 2em; font-family: sans-serif;"><h1>{{ title }}</h1><p>🔁 double binding Test:</p><inputtype="text"ng-model="userInput"placeholder="Enter something here..."/><p>You have entered: <strong>{{ userInput }}</strong></p><hr /><p>📋 ng-repeat list rendering:</p><ul><li ng-repeat="item in items track by $index">{{ $index + 1 }}. {{ item }}</li></ul><button ng-click="addItem()">Add more item</button><hr /><p>🎯 ng-if:</p><p ng-if="items.length > 3" style="color: green;">Contrags, you have added more than 3 items!</p></div></body>
    </html>
    

    本质上就是一个比较简单的逻辑,用来确认 AngularJS 的双向绑定、方法、参数等都能在 View 和 Controller 中来回正常交流

  • original.xhtml
    这里就是比较暴力的检验方法了:

    <!DOCTYPE html>
    <htmlxmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://xmlns.jcp.org/jsf/html"
    ><h:head><title>Mock JSF App</title></h:head><h:body><h1>Hello from JSF!</h1><iframesrc="angular/angular.html"style="width: 100%; height: 80vh; border: none"></iframe></h:body>
    </html>
    

    通过导入 iframe 确认 html 文件中的内容可以正常的渲染

最终渲染和现实的结果如下:

WildFly 那边的我就不放了,我已经重新部署了,iframe 的东西是显示不出来了,除非 revert changes

补充代码

这里写了一个小的脚本,因为每次跑完 mvn clean install 都会重新打包 war 和 ear 文件,这也会导致本来的 dorelase 文件被删除,让项目没办法正常部署,还得重新跑一下 docker 的指令,稍微有点麻烦

#!/bin/bashset -eecho "🧨 Step 1: Shutting down any existing containers..."
docker compose downecho "🔧 Step 2: Building jboss-mock module with Maven..."
cd jboss-mock
mvn clean install
cd ..echo "✅ Maven build completed. Artifacts generated in: deployments/"WAR_PATH="./deployments/jboss-mock/webapp-1.0.0.war"
if [ -f "$WAR_PATH" ]; thenecho "📦 Detected .war file. Creating .dodeploy marker to trigger JBoss deployment..."touch "${WAR_PATH}.dodeploy"
elseecho "❌ webapp-1.0.0.war not found! Please check if Maven build succeeded."exit 1
fiecho "🚀 Step 3: Starting container services..."
./start.shecho ""
echo "🎉 Done! You can now visit your app at:"
echo "🔗 http://localhost:8080/webapp-1.0.0/"
echo "🔗 http://localhost:8180/webapp-1.0.0/"

问题定位 & 修复过程

问题定位

其实问题主要出现在这个 <iframe src="angular/angular.html" style="width: 100%; height: 80vh; border: none"></iframe> 这里。前面提到过了,因为 context 没有办法共享的关系,所以在我们实际的生产环境,就需要使用 <iframe src="angular/angular.html?sessionId={someJavaMethod()}" style="width: 100%; height: 80vh; border: none"></iframe> 的方法去调用

明文的 session id 主要有这么几个问题:

  • 容易被截获,也会被 bookmark
  • 暴露于 iframe,可以被 js 文件读取
  • 容易引发 XSS 攻击
  • 无法自动过期

总体来说,我是能理解 InfoSec 为什么会 flag 这个实现的,不过实现起来确实有点头疼……

修复过程

目前来说找到的实现方法是使用放在 panelGroup 里,让 AngularJS 在浏览器中继续执行操作,修改的代码如下:

<!DOCTYPE html>
<htmlxmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://xmlns.jcp.org/jsf/html"
><h:head><title>JSF + AngularJS</title><script src="angular/lib/angular/angular.js"></script><script>angular.module("myApp", []).controller("MainCtrl", function ($scope) {$scope.message = "Hello from Angular 1.3!";$scope.items = ["Item A", "Item B", "Item C"];$scope.addItem = function () {$scope.items.push("Item " + ($scope.items.length + 1));};});</script></h:head><h:body><h:panelGroup layout="block"><!-- JSF will ignore {{ }} as long as it's not within EL context --><div ng-app="myApp" ng-controller="MainCtrl"><h2>{{ message }}</h2><input type="text" ng-model="userInput" /><p>You typed: {{ userInput }}</p><ul><li ng-repeat="item in items">{{ item }}</li></ul><button ng-click="addItem()">Add</button></div></h:panelGroup></h:body>
</html>

因为移除了 iframe,所以不会导入 angular.html 了,渲染结果为:


当然,如果要换成动态导入 JS 文件,也是可以实现的:

<!DOCTYPE html>
<htmlxmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://xmlns.jcp.org/jsf/html"
><h:head><title>JSF + AngularJS</title><script src="angular/lib/angular/angular.js"></script></h:head><h:body><h:panelGroup layout="block"><!-- JSF will ignore {{ }} as long as it's not within EL context --><script src="angular/app/main.controller.js"></script><div ng-app="demoApp" ng-controller="MainController"><h2>{{ message }}</h2><input type="text" ng-model="userInput" /><p>You typed: {{ userInput }}</p><ul><li ng-repeat="item in items">{{ item }}</li></ul><button ng-click="addItem()">Add</button></div></h:panelGroup></h:body>
</html>

效果如下:

⚠️:我 debug 的时候眼瘸, ng-app="demoApp" ng-controller="MainController 没有保证一致,所以 debug 的时候搞了好久都失败,然后重新过了一遍 html 才发现是名字的问题

没有继续尝试的方案

如果还失败,我打算试试 <h:outputText escape="false" />,这个 tag 可以让里面的内容不被转译。目前来说,上面使用 panelGroup 是够了,如果实际运行环境中,用 panelGroup 还不行,那么这个就是我最后的救命稻草了……

失败的尝试方案

这里也简单的说一下一些失败的尝试方案吧……如果有需求也可以试试看,说不定是我漏了什么……

  • 没有移除 iframe,但是移除了 session id
    渲染的页面直接因为没有 session id 拒绝访问

  • 没有用 panelGroup ,直接使用了 HTML tag,但是将 Angular 的所有 attributes 修改为以 data-* 开头的格式
    这里的想法是 xhtml 的检查比较严格,担心可能没办法认出 customized 的 Angular 属性,所以导致直接跳过,因此用 data-* 的方法让 AngularJS 可以识别

    还是没有办法解决 JSF 的转译问题

小结

目前来说这个方法只是延长一下当前项目的生命周期,作为一个 patch 尚可,作为长期的 solution 就有点力有不怠。真正能够解决方法的还是停用 JSF——WildFly/JBoss 官方其实已经不推荐继续用 JSF 了,尽管因为 legacy code 的问题还是继续提供支持,不过也停止了对 JSF3.0 的原生支持

有条件的话还是得往现在主流的 SPA 迁徙,前端御三家选哪个都行……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/76609.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux文件时间戳详解:Access、Modify、Change时间的区别与作用

在 Linux 系统中&#xff0c;文件的这三个时间戳&#xff08;Access、Modify、Change&#xff09;分别表示不同的文件状态变更时间&#xff0c;具体含义如下&#xff1a; 1. Access Time (Access) 含义&#xff1a;文件最后一次被访问的时间&#xff08;读取内容或执行&#xf…

SpringBoot项目打包为window安装包

SpringBoot项目打包为window安装包 通过jpackage及maven插件的方式将springboot项目打包为exe或msi pom.xml 添加插件 <plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>3.1.0</vers…

pip永久换镜像地址

要将 pip 永久设置为阿里云镜像源&#xff0c;可以通过修改 pip 的全局配置文件来实现。以下是具体步骤&#xff1a; 步骤 1&#xff1a;创建或修改 pip 配置文件 根据你的操作系统&#xff0c;配置文件的路径略有不同&#xff1a; Linux/macOS 配置文件路径&#xff1a;~/.…

PI0 Openpi 部署(仅测试虚拟环境)

https://github.com/Physical-Intelligence/openpi/tree/main 我使用4070tisuper, 14900k,完全使用官方默认设置&#xff0c;没有出现其他问题。 目前只对examples/aloha_sim进行测试&#xff0c;使用docker进行部署, 默认使用pi0_aloha_sim模型(但是文档上没找到对应的&…

XAttention

XAttention: Block Sparse Attention with Antidiagonal Scoring 革新Transformer推理的高效注意力机制资源​​ ​​论文链接​​&#xff1a;XAttention: Block Sparse Attention with Antidiagonal Scoring ​​代码开源​​&#xff1a;GitHub仓库 XAttention是韩松团队提…

前端中的浮动、定位与布局

在前端开发中&#xff0c;布局是构建网页结构的基础。而浮动&#xff08;float&#xff09;、定位&#xff08;position&#xff09;以及各种布局方法则是实现网页布局的关键工具。 一、浮动&#xff08;Float&#xff09; 浮动是CSS中用于控制元素在页面中排列方式的一种属性…

Linux 动、静态库的实现

前言&#xff1a;当我们写了一段代码实现了一个方法&#xff0c;如果我们不想把方法的实现过程暴露给别人看&#xff0c;可以把代码打包成一个库&#xff0c;其中形成后缀为.a的是静态库&#xff0c;后缀为.so的为动态库&#xff1b;当别人想使用你的方法时&#xff0c;把打包好…

ubuntu--字体设置

样式和字体大小 在终端右键-->选择"Preferences"-->勾选"Custom font": 选择自己喜欢的样式&#xff0c;然后通过size滑动条调整字体大小&#xff0c;选择即可&#xff1a;

Qt核心知识总结

Qt核心知识总结 Qt 是一个功能强大、跨平台的 C 应用程序开发框架&#xff0c;广泛应用于图形用户界面&#xff08;GUI&#xff09;应用程序的开发&#xff0c;同时也支持非 GUI 应用程序的开发。本文将从入门到精通的角度&#xff0c;详细解析 Qt 的核心知识点&#xff0c;帮…

Linux 进程概念补充 (自用)

进程概念 内核进程进程状态内存泄漏进程调度。Linux真实调度算法环境变量 内核 狭义上的操作系统指的是 内核就是进程管理进程调度&#xff0c;文件系统等等。 广义上的操作系统其实在外壳指令这些。封装了系统调用的东西。 进程 课本概念程序的一个基本实例 内核观点&#…

【dify实战】agent结合deepseek实现基于自然语言的数据库问答、Echarts可视化展示、Excel报表下载

使用dify agent实现数据库智能问答&#xff0c;echarts可视化展示&#xff0c;excel报表下载 观看视频&#xff0c;您将学会 在dify下如何快速的构建一个agent&#xff0c;来完成数据分析工作&#xff1b;如何在AI的回复中展示可视化的图表&#xff1b;如何在AI 的回复中加入E…

macos下 ~/.zshrc~ 和 ~/.zshrc

macos下 ~/.zshrc~ 和 ~/.zshrc ~/.zshrc通常是备份文件或临时文件&#xff0c;可能由编辑器&#xff08;如vim&#xff09;创建&#xff0c;通常可以安全删除&#xff0c;不会影响系统运行。 在Mac下&#xff0c;这种带~后缀的备份文件通常是由以下情况产生&#xff1a; 常…

位运算---总结

位运算 基础 1. & 运算符 : 有 0 就是 0 2. | 运算符 : 有 1 就是 1 3. ^ 运算符 : 相同为0 相异为1 and 无进位相加位运算的优选级 不用在意优先级,能加括号就加括号给一个数 n ,确定它的二进制位中第 x 位是 0 还是 1? 规定: 题中所说的第x位指:int 在32位机器下4个…

Java SpringBoot的自定义配置

一&#xff0c;一个类多个属性的情况 application.properties配置文件写法 my.config.ip127.0.0.1 my.config.port8080自定义配置类&#xff1a;MyTestConfig import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties…

Matlab FCM模糊聚类

1、内容简介 Matlab 211-FCM模糊聚类 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略

C++项目 —— 基于多设计模式下的同步异步日志系统(4)(双缓冲区异步任务处理器(AsyncLooper)设计)

C项目 —— 基于多设计模式下的同步&异步日志系统&#xff08;4&#xff09;&#xff08;双缓冲区异步任务处理器&#xff08;AsyncLooper&#xff09;设计&#xff09; 异步线程什么是异步线程&#xff1f;C 异步线程简单例子代码解释程序输出关键点总结扩展&#xff1a;使…

C# 使用 BinaryFormatter 和相关类型时的反序列化风险

C# 使用 BinaryFormatter 和相关类型时的反序列化风险 由来&#xff1a;在项目使用.NET Reactor 混淆 C# 的序列化和反序列化发现存在的问题&#xff0c;读取文件时&#xff0c;转化为对应的类数据有时候为空&#xff0c;所以就在网上搜索了相关知识&#xff0c;在此做个笔记以…

OpenCv高阶(四)——角点检测

一、角点检测 在计算机视觉中&#xff0c;角点检测是识别图像中局部区域&#xff08;角点&#xff09;的关键技术&#xff0c;这些区域通常是两条或多条边缘的交点&#xff0c;具有丰富的结构信息&#xff0c;常用于图像匹配、跟踪、三维重建等任务。 Harris角点检测算法是一…

Conda 入门指令教程

Conda 入门指令教程 Conda 是一个强大的包和环境管理工具&#xff0c;广泛应用于数据科学和机器学习项目中。本文将介绍 Conda 的常用指令&#xff0c;帮助你快速上手。 1. Conda 基础操作 查看 Conda 版本 conda --version显示当前安装的 Conda 版本。 更新 Conda conda…

Unity ShaderLab引用HLSL文件找不到其中函数

在写Unity Shader的过程中&#xff0c;常常需要将方法封装到HLSL文件中&#xff0c;今天遇到一个这样的报错&#xff0c; 明明hlsl文件路径引用没问题&#xff0c;却引用不到方法 并且将分散文件中的函数复制过来一切正常&#xff0c;最终定位到HLSL的预编译指令中 这指令的…