Spring引导Spring基于SOAP的Web服务的安全性

问题描述:

对于基于SOAP的Web服务及其安全性,我有以下实现。Spring引导Spring基于SOAP的Web服务的安全性

package com.hcentive.webservice.soap; 

import org.apache.log4j.Logger; 
import org.springframework.boot.context.embedded.ServletRegistrationBean; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.ImportResource; 
import org.springframework.core.io.ClassPathResource; 
import org.springframework.ws.config.annotation.EnableWs; 
import org.springframework.ws.config.annotation.WsConfigurerAdapter; 
import org.springframework.ws.transport.http.MessageDispatcherServlet; 
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; 
import org.springframework.xml.xsd.SimpleXsdSchema; 
import org.springframework.xml.xsd.XsdSchema; 

/** 
* @author Mebin.Jacob 
* Web service configuration class 
* @since 03-Sept-2014 
*/ 
@EnableWs 
@Configuration 
@ImportResource({"classpath:/spring-ws-servlet.xml","classpath:/security.xml"}) 
public class WebServiceConfig extends WsConfigurerAdapter { 

    Logger logger = Logger.getLogger(WebServiceConfig.class); 

    @Bean 
    public ServletRegistrationBean dispatcherServlet(ApplicationContext applicationContext) { 
     MessageDispatcherServlet servlet = new MessageDispatcherServlet(); 
     servlet.setApplicationContext(applicationContext); 
     servlet.setTransformWsdlLocations(true); 
     return new ServletRegistrationBean(servlet, "/ws/*"); 
    } 

    @Bean(name = "coa_application_service") 
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema coa_applicationSchema) { 
     DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); 
     wsdl11Definition.setPortTypeName("FormsPort"); 
     wsdl11Definition.setLocationUri("/ws"); 
     wsdl11Definition.setTargetNamespace("http://hcentive.com/service"); 
     wsdl11Definition.setSchema(coa_applicationSchema); 
     return wsdl11Definition; 
    } 

    /*@Bean 
    public EmbeddedServletContainerFactory servletContainer(){ 
     TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); 
     logger.info("Setting context path "); 
     factory.setContextPath("/spring-ws-servlet.xml"); 
     return factory; 
    } 
*/ 
    @Bean 
    public XsdSchema coa_applicationSchema() { 
     return new SimpleXsdSchema(new ClassPathResource("coa_application_service.xsd")); 
    } 
} 

//spring-ws-servlet.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 


    <bean id="wsSecurityInterceptor" 
     class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor"> 
     <property name="policyConfiguration" value="classpath:securityPolicy.xml" /> 
     <property name="callbackHandlers"> 
      <list> 
       <ref bean="keyStoreHandler" /> 
       <ref bean="springCertificateHandler" /> 
      </list> 
     </property> 
    </bean> 
    <bean id="keyStoreHandler" 
     class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler"> 
     <property name="keyStore" ref="keyStore" /> 
     <property name="privateKeyPassword" value="changeit" /> 
    </bean> 

    <bean id="keyStore" 
     class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean"> 
     <property name="password" value="changeit" /> 
     <property name="location" value="classpath:/keystore.jks" /> 
    </bean> 


    <bean id="springCertificateHandler" 
     class="org.springframework.ws.soap.security.xwss.callback.SpringCertificateValidationCallbackHandler"> 
     <property name="authenticationManager"> 
      <bean class="com.hcentive.security.SimpleAuthenticationManager" /> 
     </property> 
    </bean> 

</beans> 

//security.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
      http://www.springframework.org/schema/security 
      http://www.springframework.org/schema/security/spring-security-3.2.xsd"> 

    <http> 
     <!-- Every user request needs to be authenticated and authorized --> 
     <intercept-url pattern="/**" access="ROLE_USER"/> 

     <!-- x509 Pre authentication - pull username from the Common Name 
      field of the client certificate and extract the last 'word', in our client 
      cert example, 'John Smith jsmith', the username 'jsmith' --> 
     <x509 subject-principal-regex="CN=.*?\s(\w+)," /> 

     <logout /> 
    </http> 

     <authentication-manager> 
     <authentication-provider> 
      <user-service> 
       <user name="Jacob" 
        authorities="ROLE_USER, ROLE_ADMIN" /> 
      </user-service> 
     </authentication-provider> 
    </authentication-manager> 


</beans:beans> 

,这就是我的日志显示: -

Algorithm: [SHA256withRSA] 
    Signature: 
0000: 48 85 7A CA A7 1D DC 13 D1 0D 3D EB 10 20 A8 0E H.z.......=.. .. 
0010: 1D 2A 82 AF 0D 40 04 1A 4F 57 16 AF CF 2A 13 22 .*[email protected]*." 
0020: 79 A4 EB 81 29 13 56 94 78 AF EF D6 BE 3C B2 1B y...).V.x....<.. 
0030: 7C B2 CC B6 69 00 56 41 58 A1 E5 03 5A 27 5B 97 ....i.VAX...Z'[. 
0040: A5 49 8A 71 9C 78 13 0C 2D BC BD AE E5 26 52 9F .I.q.x..-....&R. 
0050: 8B EA 43 91 E0 DA 46 D2 15 C5 8B 23 E2 98 2E 9E ..C...F....#.... 
0060: 67 80 07 C1 94 76 E8 89 8F E6 10 D2 C4 3A 41 80 g....v.......:A. 
0070: A6 CA E9 59 4F A2 3C 6A FB D9 71 C7 29 0A A1 83 ...YO.<j..q.)... 
0080: D9 9E DE 09 F7 AC 18 EE CE B2 A5 07 0C 0F C5 92 ................ 
0090: A8 82 3D 61 10 00 5A EC 90 E9 E7 94 72 CA 93 AA ..=a..Z.....r... 
00A0: 04 C3 83 61 4C 4D AD 08 D2 54 A8 96 58 5A 06 D3 ...aLM...T..XZ.. 
00B0: C2 0F 52 24 B1 7A EF 7C 52 27 92 88 34 EE 44 83 ..R$.z..R'..4.D. 
00C0: E0 88 94 40 03 7A C3 7B C8 D8 51 5A 0B 56 D3 22 [email protected]" 
00D0: 36 11 04 B1 C0 8C F7 B3 B3 7C 4C F1 FF A4 50 41 6.........L...PA 
00E0: 4A EE FC 2D 7C DE F2 54 3F 8A 38 B7 BF E3 6C 89 J..-...T?.8...l. 
00F0: D1 3D 34 55 F5 F9 10 4B 77 A9 36 BF 23 5E 87 B4 .=4U...Kw.6.#^.. 

] 
preAuthenticatedPrincipal = Jacob, trying to authenticate 
Authentication attempt using org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider 
PreAuthenticated authentication request: org.springframework.security[email protected]fbbdfcac: Principal: Jacob; Credentials: [PROTECTED]; Authenticated: false; Details: org.springframework.security.web.authen[email protected]: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities 
Authentication success: org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER 
/at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 
/at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 
/at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 
SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER' 
/at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter' 
Delegating to org.springframework.securi[email protected]11664436 
HttpSession being created as SecurityContext is non-default 
SecurityContext stored to HttpSession: '[email protected]c8a5: Authentication: org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER' 
/at position 9 of 10 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 
/at position 10 of 10 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 
Secure object: FilterInvocation: URL: /; Attributes: [ROLE_USER] 
Previously Authenticated: org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER 
Voter: [email protected], returned: 1 
Authorization successful 
RunAsManager did not change Authentication object 
/reached end of additional filter chain; proceeding with original chain 
SecurityContext stored to HttpSession: '[email protected]c8a5: Authentication: org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER' 
Chain processed normally 
SecurityContextHolder now cleared, as request processing completed 
/error at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 
Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: '[email protected]c8a5: Authentication: org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER' 
/error at position 2 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' 
/error at position 3 of 10 in additional filter chain; firing Filter: 'LogoutFilter' 
/error at position 4 of 10 in additional filter chain; firing Filter: 'X509AuthenticationFilter' 
Checking secure context token: org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER 
/error at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 
/error at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 
/error at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 
SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security[email protected]fcc8a5: Principal: [email protected]: Username: Jacob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER' 
/error at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter' 
/error at position 9 of 10 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 
/error at position 10 of 10 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 
/error reached end of additional filter chain; proceeding with original chain 
Chain processed normally 
SecurityContextHolder now cleared, as request processing completed 

授权和访问似乎很好,或者我错了想知道什么?但是这个请求似乎没有进入我的SOAP端点。我是一名带弹簧的新手,弹簧靴。有一段时间一直坚持这一点。 ...

看起来像在加载过滤器之后不会调用messageDispatcherservlet。任何人都知道为什么没有发生。我没有看到我的日志中有任何错误!

感谢, Mebin

我认为你是两类安全的混合在这里了。在security.xml中,您使用Spring Security启用了基于HTTP的安全性,Spring Security仅在HTTP传输层上运行。在WebServiceConfig中,您已通过Spring Web服务启用了WS-Security,该服务在SOAP消息级别上运行。选择其中之一是明智的选择,您可能希望仅启用WS-Security。

检查here了解在Spring Boot应用程序中使用WS-Security的示例。具体见WebServiceServerConfig