使用ws-security的身份验证soap请求的例外情况

时间:2016-12-07 17:08:41

标签: timestamp cxf soapui ws-security usernametoken

从昨天开始,我尝试通过ws-security将安全性集成到我的Web服务soap(使用apache cxf)中。为此,我有以下配置:  --my endppoint及其拦截器配置:

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

}

- 我的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的肥皂请求:

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

当我执行此请求时,从SOAPUI,我收到以下错误:

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

所以,我要查看我已经部署了应用程序的.ear存档的wildfly日志;在那里我看到了这个例外:

  

引起:org.apache.wss4j.common.ext.WSSecurityException:邮件已过期

请帮我解决,我是ws-security的新手。我不知道如何解决此异常。

1 个答案:

答案 0 :(得分:1)

WSS4J默认在UsernameToken的创建时间戳上强制执行5分钟的时间限制。因此,在SOAP UI中,如果自上次创建后超过5分钟,则需要重新创建UsernameToken片段。或者,您可以配置WSS4J以允许更长的到期时间限制。