简体   繁体   English

Spring Boot中具有SSL身份验证的SOAP Web服务

[英]SOAP Web Service with SSL authentication in Spring Boot

I made 2 SOAP web services in java using Metro stack. 我使用Metro堆栈在Java中制作了2个SOAP Web服务。 To prevent undesired requests, they can only be made as long as the requester owns a client certificate. 为了防止不希望的请求,只有在请求者拥有客户证书的情况下,才可以进行请求。 To do so, the web.xml looked like the following piece of code: 为此,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>

Recently I've developed a brand-new soap ws, but I wanted to try Spring Boot. 最近,我开发了一种全新的肥皂水,但是我想尝试Spring Boot。 I started using Spring Initializr. 我开始使用Spring Initializr。 The web service is entirely coded, finished, but it lacks the part of SSL authentication/authorization. 该Web服务已完全编码,完成,但缺少SSL身份验证/授权的一部分。

Edit : 编辑

I've come up with a possible solution, but I've something missing. 我想出了一个可能的解决方案,但我缺少一些东西。 this is so far what I've been able to write: 到目前为止,这是我能够写的:

@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();
    }
}

Unfortunately, when running into my app server (Tomcat 8.5 with SSL/TLS enabled), you can run it without owning the client certificate. 不幸的是,当运行我的应用服务器(启用了SSL / TLS的Tomcat 8.5)时,无需拥有客户端证书就可以运行它。 As requested, here you're my Tomcat's connector config: 根据要求,这里是我的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" />

Am I missing something within my WebSecurityConfigurerAdapter ? 我是否在WebSecurityConfigurerAdapter丢失了某些WebSecurityConfigurerAdapter Thank you 谢谢

You first say that you have a working example without Spring, but looking at the Tomcat configuration it seems that is missing some parts (for example truststorefile with the client certificate authority) 首先,您说有一个不带Spring的有效示例,但查看Tomcat配置,似乎缺少了某些部分(例如,具有客户端证书颁发机构的truststorefile)

Follow the steps provided in here Mutual authentication with Tomcat 7 请遵循Tomcat 7相互认证中提供的步骤。

For example to generate a server and client certificate: 例如,生成服务器和客户端证书:

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

And then configure server.xml: 然后配置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"/> 

With Tomcat configured and the client certificate in your browser, it should ask for it, but the app will fail with a HTTP403 error because your spring configuration requires HTTPS but it doesn't specify that it needs client certification (as you are doing in web.xml without spring). 在配置了Tomcat和浏览器中的客户端证书的情况下,它应该提出要求,但该应用程序将失败并显示HTTP403错误,因为您的春季配置需要HTTPS,但未指定需要客户端证书(就像您在网络中所做的那样) .xml(没有Spring)。

Yo need to specify in SecurityConfigurerAdapter: 您需要在SecurityConfigurerAdapter中指定:

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

And it should finally work. 它最终应该可以工作。

If you want to execute it as a standalone spring-boot outside Tomcat, you should also configure in application.properties 如果要将其作为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

Edit: The truststore in Tomcat should contain only the root certificate used by clients, not the actual client certificate 编辑:Tomcat中的信任库应仅包含客户端使用的根证书,而不包含实际的客户端证书

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM