我有一个Java EE服务器/客户端架构,它使用SSL连接相互通信。建立连接后,客户端可以查询服务器Web服务。我的问题是如何访问服务器Web服务中的客户端证书信息?我的服务器控制器如下:
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("mycontroller")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class Controller {
@GET
@Path("dosomething")
public Response doSomething() {
// How can I have access to certificate information here ?
return Response.ok().build();
}
}
答案 0 :(得分:3)
我找到了一种方法来做我想做的事。
首先,必须配置服务器以要求客户端证书身份验证。在我的情况下,我使用JBoss服务器,并且必须在standalone.xml文件中添加它:
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.servlet.http.HttpServletRequest;
import java.security.cert.X509Certificate;
@Path("mycontroller")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class Controller {
@Context
private HttpServletRequest request;
@GET
@Path("dosomething")
public Response doSomething() {
X509Certificate[] certChain = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
X509Certificate certificate = certChain[0];
return Response.ok().build();
}
}
然后在我的控制器中我必须注入HttpServletRequest,最后我可以获得一个包含证书信息的X509Certificate实例:
{{1}}
答案 1 :(得分:0)
如果要查找可在HTTP标头和HTTP Servlet Reqeust对象中找到的标准证书信息,例如来自Apache HTTP反向代理的客户端证书信息。你可以注入这些
例如:
@Context private HttpServletRequest servletRequest; @Context private HttpServletContext servletContext;
(请参阅Get HttpServletRequest in Jax Rs / Appfuse application?或Java EE tutorial)
如果您希望访问密钥库文件并加载证书的私钥,则应通过JNDI文件资源或JCA适配器进行文件访问。
但我建议谨慎,应用服务器应该处理所有SSL / TLS连接安全性,WAR组件只是声明它希望连接在web.xml文件中是“机密”的。将消息级安全性和身份验证与应用程序或传输协议安全性混合可以打破关注点的分离。即在总线或集线器场景中保持身份验证的附加信息。