2016-12-07 15 views
0

Со вчерашнего дня я пытаюсь интегрировать безопасность в мое мыло для веб-сервисов (с apache cxf) через ws-security. Для этого у меня есть следующая конфигурация: --my endppoint и его конфигурация перехватчики:Исключение запроса на проверку подлинности с помощью ws-security

@Configuration 
@ImportResource({"classpath:META-INF/cxf/cxf.xml"}) 
@ComponentScan(basePackages ={"com.nhit.dev"}) 
public class MyConfig extends SpringBootServletInitializer{ 



@Bean 
public IServicesWeb momoService() { 
    return new MomoServices(); 
} 

@Bean(name = Bus.DEFAULT_BUS_ID) 
public SpringBus springBus() { 
    return new SpringBus(); 
} 


@Bean 
public ServletRegistrationBean cxfServlet() { 
    ServletRegistrationBean servlet = new ServletRegistrationBean(new CXFServlet(), "/services/*"); 
    servlet.setLoadOnStartup(1); 
    return servlet; 
} 

@Bean 
public Endpoint endpoint() { 

EndpointImpl endpoint = new EndpointImpl(springBus(), momoService()); 
endpoint.publish("/momo"); 
Map<String, Object> inProps = new HashMap<String, Object>(); 
inProps.put("action", "UsernameToken"); 
inProps.put("passwordType", "PasswordText"); 
inProps.put("passwordCallbackClass", "com.nhit.dev.mobilepayment.web.WsPwdCallBack"); 
endpoint.getInInterceptors().add(new WSS4JInInterceptor(inProps)); 

     Map<String, Object> outProps = new HashMap<String, Object>(); 
    outProps.put("action", "UsernameToken"); 
    outProps.put("user", "abc"); 
    outProps.put("passwordType", "PasswordText"); 
    outProps.put("passwordCallbackClass", "com.nhit.dev.mobilepayment.web.WsPwdCallBack"); 
    endpoint.getOutInterceptors().add(new WSS4JOutInterceptor(outProps)); 
    return endpoint; 
} 

}

--my обработчик класса PasswordCallBack:

public class WsPwdCallBack implements CallbackHandler{ 

protected final Log logger = LogFactory.getLog(getClass()); 

private Map<String, String> passwords = new HashMap<String, String>(); 

public WsPwdCallBack() { 
    passwords.put("abc", "abc"); 
    passwords.put("xyz", "xyz"); 
} 

public void handle(Callback[] callbacks) throws IOException, 
     UnsupportedCallbackException { 
    for (int i = 0; i < callbacks.length; i++) { 
     WSPasswordCallback pc = (WSPasswordCallback) callbacks[i]; 

     String pass = passwords.get(pc.getIdentifier()); 
     if (pass != null) { 
      pc.setPassword(pass); 
      return; 
     } 
    } 
} 

}

- - наконец-то мой запрос на мыло от soapUI:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.web.mobilepayment.dev.nhit.com/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
 
    <soapenv:Header> 
 
    <wsse:Security 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" soapenv:mustUnderstand="1"> 
 
     <wsse:UsernameToken wsu:Id="UsernameToken-87b7b0c5-31fe-4a01-b333-f9ca564ded57"> 
 
      <wsse:Username>xyz</wsse:Username> 
 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">TlPGdyb/NOoeA2KMO0n6DbmA0AA=</wsse:Password> 
 
      <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">FCG+tTtuZXguO8nUQUQeIQ==</wsse:Nonce> 
 
      <wsu:Created>2016-12-08T12:12:00.Z</wsu:Created> 
 
     </wsse:UsernameToken> 
 
     </wsse:Security> 
 
    </soapenv:Header> 
 
    <soapenv:Body> 
 
     <web:creerDevise> 
 
     <!--Optional:--> 
 
     <libelle>Livre</libelle> 
 
     </web:creerDevise> 
 
    </soapenv:Body> 
 
</soapenv:Envelope>

От SoapUI, когда я выполняю этот запрос, я получаю следующее сообщение об ошибке:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
 
    <soap:Body> 
 
     <soap:Fault> 
 
     <faultcode xmlns:ns1="http://ws.apache.org/wss4j">ns1:SecurityError</faultcode> 
 
     <faultstring>A security error was encountered when verifying the message</faultstring> 
 
     </soap:Fault> 
 
    </soap:Body> 
 
</soap:Envelope>

Итак, я буду смотреть на wildfly журналов, где я развернули архив .ear моего приложения; И там я увидел это исключение:

Caused by: org.apache.wss4j.common.ext.WSSecurityException: The message has expired

Пожалуйста, помогите мне исправить это, я очень нового в WS-Security. Я не знаю, как я могу устранить это исключение.

+0

Являются ли сервер и клиент одной машиной? Синхронизированы ли часы? – pedrofb

+0

@pedrofb, да, сервер и клиент - это одна и та же машина. сервер Wildfly, он установлен на localhost, а клиент SoapUI установлен на том же компьютере – FiokoSoft

ответ

1

WSS4J устанавливает ограничение по времени на 5 минут по умолчанию на отметке времени создания слова UsernameToken. Поэтому в интерфейсе SOAP вам нужно будет восстановить фрагмент UsernameToken, если прошло более 5 минут с момента его создания. В качестве альтернативы вы можете настроить WSS4J на более длительный срок для истечения срока действия.

+0

Спасибо @Colm, как я могу настроить wss4j вот так? – FiokoSoft

+0

Спасибо @Colm, как я могу настроить wss4j вот так? И временной интервал в 5 минут соответствует тому временному интервалу? Потому что я пишу дату и время создания (элемент ) вручную. Я очень новичок в этой технологии, пожалуйста, вы можете объяснить мне более глубоко, если это возможно с примером ... – FiokoSoft

+1

Почему вы хотите отключить ограничение срока действия? Если вам действительно нужно, вы можете установить свойство «utTimeToLive» на некоторое большое значение (по умолчанию «300» - это время в секундах). 5 минут - это время после Созданного времени в UsernameToken, где получатель считает, что сообщение истекло. –