2015-09-24 1 views
1

У меня есть несколько рабочих SOAP-сервисов SOAP в приложении Spring, используя проверку подлинности httpBasic, и мне нужно использовать WS-Security вместо этого на одном из них, чтобы разрешить аутентификацию с помощью следующего Soap Заголовок.Spring WS: Как применить перехватчик к определенной конечной точке

<soap:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1"> 
    <wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1"> 
    <wsse:Username>username</wsse:Username> 
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password> 
    </wsse:UsernameToken> 
</wsse:Security></soap:Header> 

Текущий WSConfiguration было сделано в соответствии с https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-ws/ давая что-то вроде

@EnableWs 
@Configuration 
public class WebServiceConfig extends WsConfigurerAdapter { 

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

    @Bean(name = "SOAP1") 
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema soap1) { 
     DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); 
     wsdl11Definition.setPortTypeName("Soap1"); 
     wsdl11Definition.setLocationUri("/soap1/"); 
     wsdl11Definition.setTargetNamespace("http://mycompany.com/hr/definitions"); 
     wsdl11Definition.setSchema(soap1); 
     return wsdl11Definition; 
    } 

    @Bean 
    public XsdSchema soap1() { 
     return new SimpleXsdSchema(new ClassPathResource("META-INF/schemas/hr.xsd")); 
    } 

} 

и Web Security в соответствии с http://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/ выглядит следующим образом

@EnableWebSecurity 
@Configuration 
public class CustomWebSecurityConfigurerAdapter extends 
    WebSecurityConfigurerAdapter { 
    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) { 
    auth 
     .inMemoryAuthentication() 
     .withUser("user1") 
      .password("password") 
      .roles("SOAP1") 
      .and() 
     .withUser("user2") 
      .password("password") 
      .roles("SOAP2"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeUrls() 
     .antMatchers("/soap/soap1").hasRole("SOAP1") 
     .antMatchers("/soap/soap2").hasRole("SOAP2") 
     .anyRequest().authenticated() 
     .and().httpBasic(); 
    } 
} 

После некоторых поисков, я обнаружил, что WSS4J обеспечивает UsernameToken аутентификация, но не может понять, как ее использовать. То, что я пытаюсь сделать, это следующее: https://sites.google.com/site/ddmwsst/ws-security-impl/ws-security-with-usernametoken , но без файлов XML с определениями бобов.

Что я планирую сделать:

  • Создать обратный вызов обработчика.
  • Создать Wss4jSecurityInterceptor, установив «setValidationActions» на «UsernameToken», «setValidationCallbackHandler» на мой обработчик обратного вызова, а затем добавить его перекрываяaddInterceptors на моем WebServiceConfig.

(я пытался что-то подобное, но я понял, что мой обратный вызов использует устаревший метод)

Проблема: Даже если она работает, она будет применяться ко всем моим «на веб-сервисы WebServiceConfig».

Update:

Реализация делает работу, но, как ожидается, оно применяется ко всем моим веб-служб. Как я могу добавить свой перехватчик только в 1 веб-службу?

После, код, который я добавил в WebServiceConfig

@Bean 
    public Wss4jSecurityInterceptor wss4jSecurityInterceptor() throws IOException, Exception{ 
     Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor(); 
     interceptor.setValidationActions("UsernameToken"); 
     interceptor.setValidationCallbackHandler(new Wss4jSecurityCallbackImpl()); 

    return interceptor; 
} 

@Override 
public void addInterceptors(List<EndpointInterceptor> interceptors) { 
    try { 
     interceptors.add(wss4jSecurityInterceptor()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

ответ

3

К сожалению, я совершенно забыл ответить на этот вопрос, но в случае, если это помогает кому-то:

Мы получили его работы по созданию нового SmartEndpointInterceptor, и применяя его только к нашей конечной точке:

public class CustomSmartEndpointInterceptor extends Wss4jSecurityInterceptor implements SmartEndpointInterceptor { 

    //CustomEndpoint is your @Endpoint class 
    @Override 
    public boolean shouldIntercept(MessageContext messageContext, Object endpoint) { 
     if (endpoint instanceof MethodEndpoint) { 
      MethodEndpoint methodEndpoint = (MethodEndpoint)endpoint; 
      return methodEndpoint.getMethod().getDeclaringClass() == CustomEndpoint.class; 
     } 
     return false; 
    } 
} 

вместо добавления WSS4J боб к WebServiceConfig, мы добавили наш SmartEndpointInterceptor:

@Configuration 
public class SoapWebServiceConfig extends WsConfigurationSupport { 

    //Wss4jSecurityCallbackImpl refers to an implementation of https://sites.google.com/site/ddmwsst/ws-security-impl/ws-security-with-usernametoken 
    @Bean 
    public CustomSmartEndpointInterceptor customSmartEndpointInterceptor() { 
     CustomSmartEndpointInterceptor customSmartEndpointInterceptor = new CustomSmartEndpointInterceptor(); 
     customSmartEndpointInterceptor.setValidationActions("UsernameToken"); 
     customSmartEndpointInterceptor.setValidationCallbackHandler(new Wss4jSecurityCallbackImpl(login, pwd)); 
     return customSmartEndpointInterceptor; 
    } 

    [...] 
} 

Надеется, что это достаточно ясно :)

+0

Я бег в том же номер. Я попытался сделать то, что вы упомянули выше, но метод shouldIntercept никогда не попадает. – lastmannorth

+0

Вы следовали этому https://spring.io/guides/gs/producing-web-service/#_configure_web_service_beans? Это конфигурация, с которой я работаю. У вас должен быть класс, расширяющий WsConfigurationSupport, и именно там вы должны добавить customSmartEndpointInterceptor Bean. –

+0

Немного поздно, но спасибо, что это сработало! – lastmannorth