Spring boot hessian 通讯加密验证
编程教程
>
Java
>
Spring
(3002)
2024-11-26 14:39:04
引言
前面写了一篇
Spring boot RPC 框架 Hessian。讲解了spring boot整合hessian的基本使用。这里主要围绕上一篇讲解的内容进行扩展讲解,hessian通讯的验证/加密实现安全的RPC访问。
一.自定义一个HessianServiceExporter
从上一篇博客
Spring boot RPC 框架 Hessian中我们可以发现,hessian的server端是通过HessianServiceExporter发布hessian接口服务的。
目前hessian的server端项目结构图:

与上一篇对比,项目结构中多了一个类HessianServerProxyExporter。这个类主要是继承了HessianServiceExporter类并重写了handleRequest方法:
package net.xqlee.project;
import java.io.IOException;
import java.util.Base64;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.remoting.caucho.HessianServiceExporter;
import org.springframework.util.StringUtils;
import org.springframework.web.util.NestedServletException;
/**
* 自定义hessian服务发布,可用于自定义验证服务
*
* @author xqlee
*
*/
public class HessianServerProxyExporter extends HessianServiceExporter {
private static final Logger log = LoggerFactory.getLogger(HessianServerProxyExporter.class);
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String authorization = request.getHeader("authorization");
if (StringUtils.isEmpty(authorization)) {
throw new NestedServletException("Auth Is Empty!");
}
log.info(authorization);
String[] authArr = authorization.trim().split(" ");
String auth = authArr[1];
auth = new String(Base64.getDecoder().decode(auth));
String[] namePwdArr = auth.split(":");
String pwd = namePwdArr[1];
// 验证密码
if (!"123456".equals(pwd)) {
throw new NestedServletException("Auth Fail!");
}
super.handleRequest(request, response);
}
}
验证的核心代码就在重写的方法里面,这里只是简单的进行了密码的认证。
为了使验证生效,我们需要重写类DemoSpringbootRpcHessianApplication:
package net.xqlee.project;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.remoting.caucho.HessianServiceExporter;
import net.xqlee.project.service.HelloWorldService;
@SpringBootApplication
public class DemoSpringbootRpcHessianApplication {
@Autowired
private HelloWorldService helloWorldService;
public static void main(String[] args) {
SpringApplication.run(DemoSpringbootRpcHessianApplication.class, args);
}
// 发布服务
@Bean(name = "/HelloWorldService")
public HessianServiceExporter accountService() {
// HessianServiceExporter exporter = new HessianServiceExporter();
HessianServerProxyExporter exporter=new HessianServerProxyExporter();
exporter.setService(helloWorldService);
exporter.setServiceInterface(HelloWorldService.class);
return exporter;
}
}
可以看到只是进行了简单修改,使用我们自己定义的HessianServerProxyExporter 来发布hessian服务,而不是默认的HessianServiceExporter。
二.hessian客户端设置用户密码
客户端的项目结构图没变,如下:

客户端比之前只是在访问hessian接口的时候多设置了用户名和密码:
package net.xqlee.project;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;
import net.xqlee.project.service.HelloWorldService;
@SpringBootApplication
public class DemoSpringbootRpcHessianClientApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSpringbootRpcHessianClientApplication.class, args);
}
@Bean
public HessianProxyFactoryBean helloClient() {
HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
factory.setServiceUrl("http://localhost:8083/HelloWorldService");
factory.setServiceInterface(HelloWorldService.class);
factory.setPassword("123456");
factory.setUsername("download");
return factory;
}
}
注意:HessianProxyFactoryBean中必须同时设置用户名和密码才能生效。 通过访问客户端的服务,通过断点到hessian的服务端HessianServerProxyExporter类,我们可以看到是如何传递用户名和密码参数的:

可以看到传递到服务端是通过HTTP协议的header传递的。并且传递的Basic认证头。这个头后面跟的字符串就是用户名:密码的Base64字符串,通过base64解密我们可以得到:

用户名:密码已经显示出来。同样后面的判断也能实现我们的通讯验证。
提示:
实际使用中,传递的密码或者用户请通过其他非对称加密方式加密后传输,服务端进行解密更为安全。
http://blog.xqlee.com/article/337.html