Java 使用客户端的服务器端访问控制';s X509证书DN
人民 我使用JAX-RS和Jersey 2.17以及Grizzly作为我的HTTP服务器。我已配置客户端身份验证并正在工作,但是,我正在尝试对客户端的X.509证书DN实施访问控制。这将为我提供与配置ApacheHTTPD和FakeBasicAuth时相同的功能 我曾尝试使用ContainerRequestFilter,但似乎可以找到一种方法来获取对与TLS会话关联的客户端DN的引用。有人能告诉我一种使用ContainerRequestFilter或任何其他机制访问证书的方法,以实现相同的最终目标吗 编辑:在发布之前,我昨晚尝试了“@javax.ws.rs.core.Context HttpServletRequest req;”,但HttpServletRequest上下文始终为空。我正在使用GrizzlyHttpServerFactory,如下所示:Java 使用客户端的服务器端访问控制';s X509证书DN,java,ssl,jersey,grizzly,Java,Ssl,Jersey,Grizzly,人民 我使用JAX-RS和Jersey 2.17以及Grizzly作为我的HTTP服务器。我已配置客户端身份验证并正在工作,但是,我正在尝试对客户端的X.509证书DN实施访问控制。这将为我提供与配置ApacheHTTPD和FakeBasicAuth时相同的功能 我曾尝试使用ContainerRequestFilter,但似乎可以找到一种方法来获取对与TLS会话关联的客户端DN的引用。有人能告诉我一种使用ContainerRequestFilter或任何其他机制访问证书的方法,以实现相同的最终目
GrizzlyHttpServerFactory.createHttpServer(
getServerURI(), getResourceConfig(), true,
new SSLEngineConfigurator(sslContext.get())
.setNeedClientAuth(true).setClientMode(false))
它不是servlet容器,因此不支持HttpServletRequest上下文。我快速查看了GrizzlyWebContainerFactory,但是初始化是完全不同的,我希望避免经历这种痛苦。在“javax.ws.rs.container.ContainerRequestFilter”中,是否有其他方法可以访问用户证书
谢谢大家!
John来自Java Servlet规范: 如果存在与请求关联的SSL证书,则servlet容器必须将其作为
java.security.cert.X509Certificate
类型的对象数组公开给servlet程序员,并通过
javax.servlet.request.X509Certificate的ServletRequest
属性
此数组的顺序定义为信任的升序。第一
链中的证书是由
客户,下一个
是过去的那个吗
对第一个进行身份验证,依此类推
实际上,这意味着:
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
将其纳入服务类的范围:
@javax.ws.rs.core.Context
HttpServletRequest req;
根据Java Servlet规范:
如果存在与请求关联的SSL证书,则servlet容器必须将其作为java.security.cert.X509Certificate
类型的对象数组公开给servlet程序员,并通过
javax.servlet.request.X509Certificate的ServletRequest
属性
此数组的顺序定义为信任的升序。第一
链中的证书是由
客户,下一个
是过去的那个吗
对第一个进行身份验证,依此类推
实际上,这意味着:
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
将其纳入服务类的范围:
@javax.ws.rs.core.Context
HttpServletRequest req;
在泽西岛邮件列表的帮助下,我找到了答案。以下是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());
}
}
}
import javax.ws.rs.container.ContainerRequestContext;
导入javax.ws.rs.container.ContainerRequestFilter;
导入javax.ws.rs.container.prematch;
导入javax.ws.rs.ext.Provider;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
@提供者
@预匹配
公共类SecurityFilter实现ContainerRequestFilter{
私有最终记录器log=LoggerFactory.getLogger(getClass());
@javax.inject.inject
私有javax.inject.Provider请求;
@凌驾
公共无效筛选器(ContainerRequestContext筛选器上下文){
if(请求!=null){
调试(“用户原则:+request.get().getUserPrincipal().getName());
}
}
}
谢谢你的帮助 在泽西岛邮件列表的帮助下,我找到了答案。以下是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());
}
}
}
import javax.ws.rs.container.ContainerRequestContext;
导入javax.ws.rs.container.ContainerRequestFilter;
导入javax.ws.rs.container.prematch;
导入javax.ws.rs.ext.Provider;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
@提供者
@预匹配
公共类SecurityFilter实现ContainerRequestFilter{
私有最终记录器log=LoggerFactory.getLogger(getClass());
@javax.inject.inject
私有javax.inject.Provider请求;
@凌驾
公共无效筛选器(ContainerRequestContext筛选器上下文){
if(请求!=null){
调试(“用户原则:+request.get().getUserPrincipal().getName());
}
}
}
谢谢你的帮助 请参阅Servlet规范。客户端证书可通过请求属性获得。请参阅Servlet规范。客户端证书可通过请求属性获得。感谢您的回复。在发布之前,我昨晚尝试了这个方法,但是HttpServletRequest上下文总是空的,但是现在您明确地将其标识为解决方案,我做了一些额外的挖掘。见上文。感谢您的回复。在发布之前,我昨晚尝试了这个方法,但是HttpServletRequest上下文总是空的,但是现在您明确地将其标识为解决方案,我做了一些额外的挖掘。见上文。