...
在Tomcat/conf/server.xml文件中,可以在请求端口的配置中添加relaxedPathChars="|{}[],%"和relaxedQueryChars="|{}[],%" 两个参数同样也可解决该问题,特殊情况下还需要多添加一个URIEncoding="UTF-8" 的参数,避免因为字符集导致的转码异常。
注意:若为window一键安装部署Tomcat,默认情况下这些参数是已经添加过的。注意:若为一键安装部署的Tomcat,默认情况下这些参数是已经添加过的。
测试html文件:open.html (测试资源仅提供测试验证以及参考,实际的集成时请以实际场景为准)
...
代码块 | ||
---|---|---|
| ||
// 1、对参数进行字符串转换,json格式化 let jsonString = JSON.stringify(params); // 2、对字符串的数据转为二进制 let utf8Bytes = new TextEncoder().encode(jsonString); // 3、用二进制的数据转为utf-8之后进行base64编码 let base64Encoded = btoa(String.fromCharCode(...utf8Bytes)); // 4、对base64编码进行url转义 return encodeURIComponent(base64Encoded) |
最终访问地址拼接示例如下:
代码块 |
---|
http://localhost:18080/smartbi/vision/openresource.jsp?resid=I402881e5019608c408c4fb7801960e2ec9b42d3d&W3sibmFtZSI6IuS6p%2BWTgeWQjeensCIsICJ2YWx1ZSI6IuWNjuWMlyIsImRpc3BsYXlWYWx1ZSI6IuWNjuWMlyJ9XQ%3D%3D |
测试页面
base64加密:https://www.bejson.com/enc/base64/
url转码:https://www.sojson.com/encodeurl.html
测试html文件:open.html (测试资源仅提供测试验证以及参考,实际的集成时请以实际场景为准)
...
- param.参数名:参数的真实值
- paramDisplay.参数名:参数的显示值
- 打开自助仪表盘资源时,参数名对应为筛选器组件的标题
实际post请求时的参数负载
...
(4)表单提交
这里form表单提交是通过使用js代码来进行控制,这种提交方式相对于在form表单中添加submit类型的<button>标签的提交按钮更灵活,毕竟在实际的集成场景很难控制让用户点击提交表单的按钮,另外就是使用js代码提交时候还能在提交前去设置form表单的一些属性。
代码块 | ||
---|---|---|
| ||
// 获取form标签
var submitForm = document.getElementById("submitForm");
// 在设置的iframe中打开
submitForm.target = "myFrame"
submitForm.submit(); |
参考示例页面:postHtml.html (测试资源仅提供测试验证以及参考,实际的集成时请以实际场景为准)
使用时请用文本工具打开并修改里面的服务器地址信息以及集成的参数资源。
调优部分
由于form表单本身需要在html页面上创建<form>标签以及传参的<input>标签,在实际基础场景中集成参数不会是一直固定的,所以在实际集成时,可以在html上预留好ifarme标签位置之后,使用js代码根据实际需要来动态创建标签,实际更符合业务需求。
参考示例页面:post.html (测试资源仅提供测试验证以及参考,实际的集成时请以实际场景为准)
二、令牌token单点登录
在Smartbi中使用令牌token进行单点登录的时候,往往会因为在加密时某一个步骤操作不当导致出现各式各样的问题,可能遇到的问题如下:
问题1:令牌token单点登录:解析令牌失败
问题2:其他提示信息,如令牌超时、用户不存在等
问题3:报错自定义的提示信息
如果在系统选项中设置了自定义的异常提示,前台的提示信息就不是很明显,此时可以打开系统监控然后监控日志,就能看到如下日志,可确认是上述问题中的那一个
在使用令牌token的时候要如何避免这些问题,在生成和使用令牌的时候又要注意哪些问题呢?下面我们就用一个代码示例来确认来讲解:
代码块 | ||
---|---|---|
| ||
public class SmartbiToken {
public static void main(String[] args) throws Exception {
// 1、准备加密参数
String secretKey = "12345678";// 密钥
long timestamp = new java.util.Date().getTime();// 必需是毫秒数的时间戳
String userName = "admin"; // 用户名,可基于业务动态获取
String password = "admin"; // 用户密码(可选),可基于业务动态获取
// 准备加密的JSON串,用户密码可选
String loginInfo= "{\"username\":\"" + userName + "\",\"password\":\"" + password + "\",\"timestamp\":" + timestamp + "}";
// 2、进行加密
String token = CryptoUtil.encrypt(AlgorithmType.DES, loginInfo, secretKey);
// 3、链接转码
String encodedToken = java.net.URLEncoder.encode(token, "UTF-8");
// 4、拼接登录链接
String url = "http://localhost:8080/smartbi/vision/loginByToken?smartbiToken=" + encodedToken;
// 5、拼接登录后的跳转请求
String targetPath = "openresource.jsp?resid=I2c94ea86298cbe6c01298cfd9ba900fa";
targetPath = java.net.URLEncoder.encode(targetPath, "UTF-8");
String endUrl = url + "&targetPath=" + targetPath;
System.out.println(endUrl);
}
} |
(1)加密参数部分
加密参数主要由四部分组成
- 秘钥:设置的秘钥要与Smartbi的config界面配置的秘钥一致,不一致则可能会出现问题1“解析令牌失败”的问题。另外令牌一般设置8个字符,否则AES算法时会加密异常。
- 时间戳:时间戳需要获取当前时间,确保第三方系统时间和Smartbi服务器的时间差距不大,否则可能会出现问题2“令牌超时”的问题。
- 用户名:用户名需要传入Smartbi上用户的用户名,同时确保Smartbi上存在对应用户,否则会出现问题2“用户不存在”的问题,需要做好用户同步
- 密码:密码是可选传入,若config上配置了需要传入密码,则一定需要传入。
(2)进行加密
加密部分主要有主要有两种算法DES加密和AES-GCM加密
- DES加密:CryptoUtil.encrypt(AlgorithmType.DES, loginInfo, 密钥)。
- AES-GCM加密:smartbi.crypto.CryptoUtil.encrypt(loginInfo, 密钥) 或 CryptoUtil.encrypt(AlgorithmType.AES_GCM, loginInfo, secretKey)
注意秘钥长度,如果秘钥不是8个字符的,使用AES-GCM加密加密会报错如下:The key length must be 16 bytes
加密注意事项:
- V11版本不同的加密算法得到的结果是不一样的,令牌的前缀一般会表示当前使用的是什么样的加密算法,T1_表示AES算法、T0_表示为DES算法。而V10版本的加密算法是没有前缀的,需要特别注意。
- V11版本使用的加密jar包和V10版本使用的jar包不一致,加密出来的结果也完全不一致参考。
下面使用相同用户、密码、时间戳、令牌,算法不同来加密之后得到的结果参考如下:
代码块 |
---|
// V10版本加密之后的令牌
54f296bd4649b0d44628a5c32faee32b8dcc1603e65f5926bcff5ecd042f5176ebefa28274987245be277798ca3175c6ac93f1e0ae92bd16841e7713b31959e6edf967ea6f13b4bc
// V11版本DES算法加密之后的令牌
T0_VPKWvUZJsNRGKKXDL67jK43MFgPmX1kmvP9ezQQvUXbr76KCdJhyRb4nd5jKMXXGrJPx4K6SvRaEHncTsxlZ5u35Z+pvE7S8
// V11版本AES算法加密之后的令牌
T1_DNEJke1569+HbJtUBb9a4m9l1ZtI4UR4CGUfwn+mMsuuw9PkNKoHAchSpoXDxc0CsFgVwVMlibe9uOa+QliqOrNxg05qz7ZzDlHNLYCsvi6kmliCNBPio2MstouYIw== |
(3)令牌转码
拿到令牌之后我们可以看到如下令牌他是存在特殊字符的,又因为令牌单点一般都是通过get请求来提交令牌参数,此时就可能会出现上一章节的相同问题:2、url转码。此时就需要对令牌进行url转码,如果是Java系统可以使用 java.net.URLEncoder.encode(token, "UTF-8")进行转码,js代码则可以使用encodeURIComponent函数来进行转码。如果说不转码的情况下拼接地址访问之后,同样会出现问题1“解析令牌失败”的问题。
(4)拼接登录链接
拼接的单点地址需要使用loginByToken,然后smartbiToken参数用来指定token:"http://localhost:8080/smartbi/vision/loginByToken?smartbiToken=" + encodedToken;
(5)拼接登录后的跳转请求
登录完成之后,需要使用targetPath参数来指定跳转之后需要拼接的地址,这个地址在拼接到最终请求之前同样需要进行url转码,否则在openresource的请求里,当设置集成报表的参数时,会将集成的参数当成是loginByTokenq请求的参数,导致openresource请求传参失败,具体可以参考如下图中的请求参数信息。
最终拼接访问的请求如下:
代码块 |
---|
http://localhost:18080/smartbi/vision/loginByToken?smartbiToken=T1_DNEJke1569%2BHbJtUBb9a4m9l1ZtI4UR4CGUfwn%2BmMsuuw9PkNKoHAchSpoXDxc0CsFgVwVMlibe9uOa%2BQliqOrNxg05qz7ZzDlHNLYCsvi6kmliCNBPio2MstouYIw%3D%3D&targetPath=openresource.jsp%3Fresid%3D2472fece6b5e9162c5ecf31425ac3b6c%26paramsInfo%3D%255B%257B%2522name%2522%253A%2522%25E5%258F%2591%25E8%25B4%25A7%25E5%258C%25BA%25E5%259F%259F%2522%252C%2522value%2522%253A%2522%25E5%258D%258E%25E5%258C%2597%2522%252C%2522displayValue%2522%253A%2522%25E5%258D%258E%25E5%258C%2597%2522%257D%255D |