2016-12-07 4 views
0

어제부터 ws-security를 ​​통해 웹 서비스 비누 (apache cxf 포함)에 보안을 통합하려고합니다. 이를 위해 나는 다음과 같은 구성이 있습니다 아니야 자,가요 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; 
} 

}

아니야 자,가요 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; 
     } 
    } 
} 

}

- -finally soapUI의 비누 요청 :

나는이 요청을 실행 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>

, 나는 다음과 같은 오류가 나타납니다 나는 제이보스 로그를 볼거야, 그래서

<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>

을 어디 내 응용 프로그램의 .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는 UsernameToken의 생성 타임 스탬프에 기본적으로 5 분의 시간 제한을 적용합니다. 따라서 SOAP UI에서 마지막으로 생성 한 이후 5 분 이상 경과 한 경우 UsernameToken 스 니펫을 다시 만들어야합니다. 또는 만료 시간을 길게 허용하도록 WSS4J를 구성 할 수도 있습니다.

+0

감사합니다 @Colm, 어떻게 wss4j를 구성 할 수 있습니까? – FiokoSoft

+0

@Colm, 고맙습니다. 어떻게 wss4j를 구성 할 수 있습니까? 그리고 5 분의 시간 제한은 어느 시간 간격에 해당합니까? 왜냐하면, 저는 창조의 날짜 시간 (요소 : )을 손으로 씁니다. 나는이 기술에 대해 아주 새로운 것입니다. 가능한 한 예를 들어 설명해 주시겠습니까? – FiokoSoft

+1

만료 기한을 비활성화 하시겠습니까? 정말로 필요한 경우, "utTimeToLive"속성을 몇 가지 큰 값 (기본값은 초 단위의 "300")으로 설정할 수 있습니다. 수신자가 메시지가 만료 된 것으로 간주하는 UsernameToken의 Created 시간 이후 5 분이 소요됩니다. –