Azure中的Spring Boot-请求标头中的客户端证书

当前,我们在Spring Boot" title="Spring Boot">Spring Boot应用程序中实现了相互身份验证,需要将其部署在Azure中。Azure的负载平衡器在请求标头字段“ X-ARR-

ClientCert”中重定向客户端证书(Base64编码),而Spring无法在该位置找到它。=>身份验证失败

微软文档显示了如何在.NET应用程序中处理此问题:https :

//docs.microsoft.com/zh-cn/azure/app-service-web/app-service-web-configure-

tls-mutual-auth

我试图从OncePerRequestFilter的标头中提取证书,并将其设置为如下所示的请求:

public class AzureCertificateFilter extends OncePerRequestFilter {

private static final Logger LOG = LoggerFactory.getLogger(AzureCertifacteFilter.class);

private static final String AZURE_CLIENT_CERTIFICATE_HEADER = "X-ARR-ClientCert";

private static final String JAVAX_SERVLET_REQUEST_X509_CERTIFICATE = "javax.servlet.request.X509Certificate";

private static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----\n";

private static final String END_CERT = "\n-----END CERTIFICATE-----";

@Override

protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {

X509Certificate x509Certificate = extractClientCertificate(httpServletRequest);

// azure redirects the certificate in a header field

if (x509Certificate == null && StringUtils.isNotBlank(httpServletRequest.getHeader(AZURE_CLIENT_CERTIFICATE_HEADER))) {

String x509CertHeader = BEGIN_CERT + httpServletRequest.getHeader(AZURE_CLIENT_CERTIFICATE_HEADER) + END_CERT;

try (ByteArrayInputStream certificateStream = new ByteArrayInputStream(x509CertHeader.getBytes())) {

X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certificateStream);

httpServletRequest.setAttribute(JAVAX_SERVLET_REQUEST_X509_CERTIFICATE, certificate);

} catch (CertificateException e) {

LOG.error("X.509 certificate could not be created out of the header field {}. Exception: {}", AZURE_CLIENT_CERTIFICATE_HEADER, e.getMessage());

}

}

filterChain.doFilter(httpServletRequest, httpServletResponse);

}

private X509Certificate extractClientCertificate(HttpServletRequest request) {

X509Certificate[] certs = (X509Certificate[]) request.getAttribute(JAVAX_SERVLET_REQUEST_X509_CERTIFICATE);

if (certs != null && certs.length > 0) {

LOG.debug("X.509 client authentication certificate:" + certs[0]);

return certs[0];

}

LOG.debug("No client certificate found in request.");

return null;

}

}

但这在Spring过滤器链中稍后会失败,但有以下异常:

sun.security.x509.X509CertImpl cannot be cast to [Ljava.security.cert.X509Certificate; /oaa/v1/spaces

配置如下所示:

@Override

public void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()

.antMatchers("**/docs/restapi/**").permitAll()

.anyRequest().authenticated()

.and()

.httpBasic()

.disable()

.addFilterBefore(new AzureCertificateFilter(), X509AuthenticationFilter.class)

.x509()

.subjectPrincipalRegex("CN=(.*?)(?:,|$)")

.userDetailsService(userDetailsService());

}

回答:

我应该更仔细地阅读该异常:

sun.security.x509.X509CertImpl cannot be cast to [Ljava.security.cert.X509Certificate; /oaa/v1/spaces

我必须设置这样的证书数组:

httpServletRequest.setAttribute(JAVAX_SERVLET_REQUEST_X509_CERTIFICATE, new X509Certificate[]{x509Certificate});

以上是 Azure中的Spring Boot-请求标头中的客户端证书 的全部内容, 来源链接: utcz.com/qa/410455.html

回到顶部