我使用 Metro 堆栈在 Java 中制作了 2 个 SOAP Web 服务。为防止不受欢迎的请求,只有请求者拥有客户端证书才能发出请求。为此,web.xml 类似于以下代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>PadronExterno</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>
com.sun.xml.ws.transport.http.servlet.WSServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>WebServicePort</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>TomcatStartupServlet</servlet-name>
<servlet-class>com.company.TomcatStartupServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WebServicePort</servlet-name>
<url-pattern>/theWebService</url-pattern>
</servlet-mapping>
<security-constraint>
<display-name>Constraint1</display-name>
<web-resource-collection>
<web-resource-name>theWebService</web-resource-name>
<description></description>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<description></description>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
</web-app>
最近开发了一个全新的soap ws,但是想试试Spring Boot。我开始使用 Spring Initializr。 Web 服务已经完全编码,完成,但它缺少 SSL 身份验证/授权的部分。
编辑:
我想出了一个可能的解决方案,但我缺少一些东西。到目前为止,这是我能写的:
@Configuration
@EnableWebSecurity
public class SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private Configuracion config;
@Override
protected void configure(HttpSecurity http) throws Exception {
// Add support for HSTS
http
.headers()
.httpStrictTransportSecurity()
.includeSubDomains(true)
.maxAgeInSeconds(31536000);
// Disable HTTP
http.httpBasic().disable();
Integer httpPuerto = config.getHttpPuerto();
Integer httpsPuerto = config.getHttpsPuerto();
http
.portMapper()
.http(httpPuerto)
.mapsTo(httpsPuerto);
http.requiresChannel().anyRequest().requiresSecure();
}
}
不幸的是,当运行到我的应用程序服务器(启用了 SSL/TLS 的 Tomcat 8.5)时,您可以在没有客户端证书的情况下运行它。根据要求,这是我的 Tomcat 的连接器配置:
<Connector
connectionTimeout="20000"
port="9090"
protocol="HTTP/1.1"
redirectPort="9443"/>
<Connector
SSLEnabled="true"
keystorePass="***d"
keystoreType="JKS"
maxThreads="200"
port="9443"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
scheme="https"
secure="true"
sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
sslProtocol="TLSv1.2"
clientAuth="want"
keystoreFile="D:\apache\Tomcat8.5\certs\tomcat.jks"
<Connector port="9009" protocol="AJP/1.3" redirectPort="9443"/>
ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA" />
我是否在我的 WebSecurityConfigurerAdapter
中遗漏了什么?谢谢
最佳答案
您首先说您有一个没有 Spring 的工作示例,但是查看 Tomcat 配置似乎缺少某些部分(例如带有客户端证书颁发机构的 truststorefile)
按照此处提供的步骤操作 Mutual authentication with Tomcat 7
例如生成服务器和客户端证书:
keytool -genkeypair -alias tomcat -keyalg RSA -dname "CN=tomcat.com" -keystore tomcat.keystore -keypass tomcat -storepass tomcat
keytool -genkeypair -alias user -keyalg RSA -dname "CN=user" -keypass usertomcat -keystore client.keystore -storepass usertomcat
keytool -exportcert -rfc -alias user -file client.cer -keypass usertomcat -keystore client.keystore -storepass usertomcat
keytool -importcert -alias user -file client.cer -keystore tomcat.keystore -storepass tomcat -noprompt
keytool -importkeystore -srckeystore client.keystore -destkeystore client.p12 -deststoretype PKCS12 -srcalias user -deststorepass usertomcat -destkeypass usertomcat
然后配置server.xml:
<!-- remove AprLifecycleListener!! -->
<Connector port="9443"
maxThreads="150"
scheme="https"
secure="true"
SSLEnabled="true"
truststoreFile="/path-to/tomcat.keystore"
truststorePass="tomcat"
keystoreFile="/path-to/tomcat.keystore"
keystorePass="tomcat"
clientAuth="true"
keyAlias="tomcat"
sslProtocol="TLS"/>
配置了 Tomcat 并在您的浏览器中设置了客户端证书,它应该会要求它,但是应用程序将失败并出现 HTTP403 错误,因为您的 spring 配置需要 HTTPS 但它没有指定它需要客户端证书(因为您是在没有 spring 的情况下在 web.xml 中执行)。
你需要在SecurityConfigurerAdapter中指定:
http.x509().subjectPrincipalRegex("CN=(.*?)(?:,|$)");
它最终应该会起作用。
如果想在Tomcat外作为独立的spring-boot执行,还应该在application.properties中配置
server.port: 8443
server.ssl.key-store: tomcat.keystore
server.ssl.key-store-password: tomcat
server.ssl.keyStoreType: JKS
server.ssl.keyAlias: tomcat
server.ssl.trust-store=tomcat.keystore
server.ssl.trust-store-password=tomcat
server.ssl.client-auth:need
编辑:Tomcat 中的信任库应该只包含客户端使用的根证书,而不是实际的客户端证书
关于java - 在 Spring Boot 中使用 SSL 身份验证的 SOAP Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43673906/