您的位置:首页 > 其它

单点登录判断后乱码问题

2015-11-13 11:52 387 查看
刚才是 处理一个XSS漏洞问题:在提交表单的时候输入框中包含<script>alert("123")</script>等敏感高危字符串需要url转码。

这本是比较简单的事情,本来转码数据一样会存储到后台,只是显示数据的时候会出错,需要对<script>alert("123")</script>进行html转码再保存。
html 转码方式如下:
public static String HTMLEncode(String aTagFragment){
final StringBuffer result = new StringBuffer();
final StringCharacterIterator iterator = new StringCharacterIterator(aTagFragment);
char character = iterator.current();
while (character != StringCharacterIterator.DONE ){
if (character = = '<') {
result.append("<");
}
else if (character = = '>') {
result.append(">");
}
else if (character = = '\"') {
result.append(""");
}
else if (character = = '\") {
result.append("'");
}
else if (character = = '\\') {
result.append("\");
}
else if (character = = '&') {
result.append("&");
}
else {
//the char is not a special one
//add it to the result as is
result.append(character);
}

在修改前,我自己先测试以前的功能:结果发现输入中文会乱码。
难道项目以前都中文乱码?纠结郁闷开始测试调试开始了。
最后发现访问不要登录的地址,比如搜索模块,中文传输正常;需要登录的地址,比如保存纠错记录。
判定估计是登录拦截器有问题。
我们现在用的是单点登录。

过滤器中代码:

/**
* 从请求中获得参数值,而后去除掉一个参数后,组装成新的字符串返回。
*
* @param request
* 请求
* @param exceptParm
* 要去除掉的参数名。
* @return String 返回字符串
* */
public static String getParms(HttpServletRequest request) {
StringBuffer result = new StringBuffer();
Enumeration enumeration = request.getParameterNames();
String parmName = null;
while (enumeration.hasMoreElements()) {
parmName = enumeration.nextElement().toString();

if (!"sticket".equalsIgnoreCase(parmName)) {
result.append("&").append(parmName).append("=")
.append(request.getParameter(parmName));
}
}
if (request.getRequestURL().toString().indexOf("portaltype") == -1
&& result.toString().indexOf("portaltype") == -1) {
result.append("&").append("portaltype").append("=")
.append(request.getAttribute("portaltype"));
result.append("&").append("version").append("=")
.append(request.getAttribute("version"));
result.append("&").append("areacode").append("=")
.append(request.getAttribute("areacode"));
}
return result.toString();
}

public static String getDirectURL(String ssoserverURL,HttpServletRequest request) {
//ssoserverURL 为单点登录地址
String url = null;
if (ssoserverURL.indexOf('?') > 0) {
url = ssoserverURL + "backurl=" + request.getRequestURL()
+ getParms(request);
} else {
url = ssoserverURL + '?' + "backurl=" + request.getRequestURL()
+ getParms(request);
}
return url;
}
String redirectUrl = getDirectURL(ssomap.get("ssoserverURL"), request);
response.sendRedirect(redirectUrl);

从上面代码看出来,拦截器对request中参数都拼接成字符串传递给服务器。
如果单点服务器接收中文参数乱码或者登录回调后传递中文参数乱码;那么最终得到的结果肯定乱码。
得到结论:访问地址 需要单点登录判断的则不能传递中文参数。

最终解决方法:
页面form表单需要 uri编码:
orgstr=encodeURI(encodeURI(orgstr));
后台处理
orgstr=URLDecoder.decode(orgstr, "utf-8");

最后进行html编码:
orgstr=HTMLEncode(orgstr);

orgstr被保存到数据库。

测试:页面输入:<script>alert("你")</script>

保存数据的数据为:<script>alert("你")</script>

取出显示到页面显示为:<script>alert("你")</script>

输入和显示一致。perfect!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单点登录乱码