class HandlerExecutionChainWrapper extends HandlerExecutionChain {
private BeanFactory beanFactory;
private HandlerMethod handlerWrapper;
private byte[] lock = new byte[0];
public HandlerExecutionChainWrapper(HandlerExecutionChain chain, HttpServletRequest request,
BeanFactory beanFactory) {
super(chain.getHandler(), chain.getInterceptors());
this.beanFactory = beanFactory;
}
@Override
public Object getHandler() {
if (this.handlerWrapper != null) {
return this.handlerWrapper;
}
synchronized (this.lock) {
if (this.handlerWrapper != null) {
return this.handlerWrapper;
}
HandlerMethod superMethodHandler = (HandlerMethod) super.getHandler();
Object proxyBean = createProxyBean(superMethodHandler);
this.handlerWrapper = new HandlerMethod(proxyBean, superMethodHandler.getMethod());
return this.handlerWrapper;
}
}
private Object createProxyBean(HandlerMethod handler) {
try {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(handler.getBeanType());
Object bean = handler.getBean();
if ((bean instanceof String)) {
bean = this.beanFactory.getBean((String) bean);
}
ControllerXssInterceptor xss = new ControllerXssInterceptor(bean);
enhancer.setCallback(xss);
return enhancer.create();
} catch (Exception e) {
throw new IllegalStateException("为Controller创建代理失败:" + e.getMessage(), e);
}
}
public static class ControllerXssInterceptor implements MethodInterceptor {
private Object target;
private List<String> objectMatchPackages;
public ControllerXssInterceptor(Object target) {
this.target = target;
this.objectMatchPackages = new ArrayList<String>();
this.objectMatchPackages.add("cn.com.linkwidejc.bi.entity");
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
String methodName = method.getName();
if (("print".equals(methodName)) || ("export".equals(methodName)) || ("viewAppTable".equals(methodName))
|| ("viewAppChart".equals(methodName))) {
return method.invoke(this.target, args);
}
if (args != null) {
for (int i = 0; i < args.length; i++) {
if (args[i] != null) {
if ((args[i] instanceof String)) {
args[i] = stringXssReplace((String) args[i]);
} else {
for (String pk : this.objectMatchPackages) {
if (args[i].getClass().getName().startsWith(pk)) {
objectXssReplace(args[i]);
break;
}
}
}
}
}
}
return method.invoke(this.target, args);
}
private String stringXssReplace(String argument) {
return RSBIUtils.htmlEscape(argument);
}
// 对象过滤
private void objectXssReplace(Object argument) throws IllegalAccessException {
if (argument == null) {
return;
}
for(Field f : argument.getClass().getDeclaredFields()){
f.setAccessible(true);
if (String.valueOf(f.getType()).equals("class java.lang.String") &&
f.get(argument) != null && !StringUtil.isEmpty(String.valueOf(f.get(argument)))) { // 如果type是类类型,则前面包含"class ",后面跟类名
f.set(argument,RSBIUtils.htmlEscape(f.get(argument).toString()));
}
}
}
}
}
java拦截器处理过滤对象中属性的特殊字符
最新推荐文章于 2023-09-05 11:03:50 发布
本文介绍了一种在Spring MVC中增强HandlerExecutionChain的方法,通过创建代理Bean实现对Controller请求的预处理,特别针对XSS攻击进行防御。文章详细展示了如何利用CGLIB动态代理拦截并修改Controller参数,实现字符串及对象级的XSS过滤。
827

被折叠的 条评论
为什么被折叠?



