使用客户端X509证书DN的服务器端访问控制

时间:2015-03-18 04:32:28

标签: java ssl jersey grizzly

人民,

我使用JAX-RS和Jersey 2.17以及Grizzly作为我的HTTP服务器。我已配置客户端身份验证并正常工作,但是,我正在尝试在客户端的X.509证书DN上实现访问控制。这将为我提供与Apache httpd和FakeBasicAuth配置相同的功能。

我试图使用ContainerRequestFilter,但似乎找到了一种方法来获取对与TLS会话相关联的客户端DN的引用。有人可以通过ContainerRequestFilter或任何其他机制向我展示访问证书的方法,以实现相同的最终目标吗?

编辑:我尝试了" @ javax.ws.rs.core.Context HttpServletRequest req;"昨晚发布之前,但HttpServletRequest上下文始终为null。我正在使用GrizzlyHttpServerFactory,如下所示:

GrizzlyHttpServerFactory.createHttpServer(
                getServerURI(), getResourceConfig(), true,
                new SSLEngineConfigurator(sslContext.get())
                    .setNeedClientAuth(true).setClientMode(false))

相信不是servlet容器,因此不支持HttpServletRequest上下文。我很快就看到了GrizzlyWebContainerFactory,但初始化完全不同,并希望避免这种痛苦。是否有其他方法可以访问" javax.ws.rs.container.ContainerRequestFilter"中的用户证书?

谢谢!

约翰

2 个答案:

答案 0 :(得分:3)

来自Java Servlet规范:

  

如果存在与请求关联的SSL证书,则servlet容器必须将其作为java.security.cert.X509Certificate类型的对象数组公开给servlet程序员,并且可以通过   ServletRequest的{​​{1}}属性。

     

此数组的顺序定义为信任的升序。首先   链中的证书是由...设置的   客户,下一个   是以前的人   验证第一个,依此类推。

实际上,这意味着:

javax.servlet.request.X509Certificate

如果您还无法访问X509Certificate[] certs = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate") if (certs != null && certs.length > 0) { X509Certificate cert = certs[0]; // the client certificate // further processing (extract and compare DN, etc) } ,则可以使用ServletRequest将其纳入服务类的范围:

@Context

答案 1 :(得分:1)

在Jersey邮件列表的帮助下,我得出了答案。这是woking RequestFilter示例:

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.ext.Provider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Provider
@PreMatching
public class SecurityFilter implements ContainerRequestFilter {
    private final Logger log = LoggerFactory.getLogger(getClass());

    @javax.inject.Inject
    private javax.inject.Provider<org.glassfish.grizzly.http.server.Request> request;

    @Override
    public void filter(ContainerRequestContext filterContext) {
        if (request != null) {
            log.debug("User principle: " + request.get().getUserPrincipal().getName());
        }
    }
}

感谢您的帮助!

相关问题