2012-04-27 3 views
0

opentravel.org OTA XML 요청을 받아들이고 적절히 응답하는 tomcat 웹 서비스가 있습니다. JibX OTA 클래스를 사용합니다.JibX WS에서 SOAP 헤더에 액세스

지금까지 서비스 사용자는 POX를 사용해 왔지만 실제로는 잘 작동하지만 새로운 사용자는 SOAP 헤더를 사용하여 SOAP 헤더에 보안 자격 증명을 추가하려고합니다. 대신 POS xml 조각을 사용합니다. ..

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Header> 
    <wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org  /wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <wsse:UsernameToken> 
     <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">SECRET</wsse:Password> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    </soap:Header> 
그래서 나는 서비스 구현 클래스 내에서 헤더에 액세스 할 필요가 있다고 생각 요청을 인증합니다.

SOAP 헤더 예제를 살펴본 결과, inContext를 포함하여 헤더에 액세스 할 수 있다고 나와 있습니다.

public RoomListRS list(RoomListRQ roomListRQ, InContext inCtx){ 
.... 
} 

그래서이 방법에서 나는이 작업을 수행 할 수 있습니다

...
Security security = (Security) inCtx.getAttribute("security"); 

그래서 난 토큰 내에서 사용자 이름을 액세스 할 수

는 ... 서비스에서이 지정하는 데 ...

<service name="OTAService"> 
    <service-class>com.xx.webservice.ota.HotelServiceImpl</service-class> 
    <operation method="list"/> 
    <handler-class class="org.jibx.ws.io.handler.ContextAttributeUnmarshallingInHandler"> 
    <constructor-arg value="com.xx.shared.soap.security.Security"/> 
    <constructor-arg value="security"/> 
    </handler-class> 
</service> 

내가 맞습니까?

그래서 Security 클래스를 만들었지 만 모든 네임 스페이스 항목을 빠져 나가기 만하면 헤더에있는 항목에 액세스 할 수 있음을 알 수 있습니다. ... 이런 조각을 가지고 바탕으로

<Security> 
     <UsernameToken> 
     <Username>USERNAME</Username> 
     <Password>SECRET</Password> 
     </UsernameToken> 
    </Security> 

그래서 나는 bindgen 바인딩 생성 한 후 컴파일, 다음 soapUI

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.opentravel.org/OTA/2003/05"> 
    <soapenv:Header> 
    <Security> 
     <UsernameToken> 
     <Username>USERNAME</Username> 
     <Password>SECRET</Password> 
     </UsernameToken> 
    </Security> 
    </soapenv:Header> 
    <soapenv:Body> 
<OTA_HotelRoomListRQ xmlns="http://www.opentravel.org/OTA/2003/05" Version="2.0"> 
.... 
</OTA_HotelRoomListRQ> 
</soapenv:Body> 
</soapenv:Envelope> 

로라고하지만 난에서 보안 개체를 가져하려고 할 때 문맥은 null

막대의 끝이 잘못 되었습니까?

SOAPY를 사용하여 다른 끝점을 가진 다른 서비스를 만들어야합니까?

JibX WS와 inHandler를 사용하여 수행 할 수없는 작업이 무엇입니까?

모든 의견을 환영합니다.


제 질문에 답변 해 주셔서 대단히 감사드립니다.

내가 추가 한 내용을 검토하려고합니다. 커스텀 화와 xsd를 사용하여 java 소스와 binding.xml을 생성했습니다. ,

C:\Java\wsse>java org.jibx.binding.generator.BindGen org.oasisopen.docs.wss.oasis200401wsswssecuritysecext1.SecurityHeaderType 
Exception in thread "main" java.lang.IllegalStateException: No way to handle type java.lang.Object, referenced from org.oasisopen.docs.wss.oasis200401wsswssecuritysecext1.SecurityHeaderType 
    at org.jibx.binding.generator.BindGen.expandReferences(BindGen.java:227) 
    at org.jibx.binding.generator.BindGen.findReferences(BindGen.java:1010) 
    at org.jibx.binding.generator.BindGen.generate(BindGen.java:1124) 
    at org.jibx.binding.generator.BindGen.main(BindGen.java:1302) 

나는 그 어떤 실마리 있는지 bindgen의 사용자 정의한 내용을 살펴 하겠어 :

나는 클래스를 컴파일하고 난 지금을 결합하려고하지만이 오류를 얻고있다 이것이이 문제에 대한 유일한 단서이기 때문입니다.이걸 어떻게 잡았는지 말해 줄 수 있니?

다시 한번 감사드립니다.

+0

누구도이 작업을 수행해야합니까? 제가 유일한가요? – iainmac999

답변

0

WS-Security 사용자 이름/암호 헤더에 대해 가지고있는 프로덕션 코드를 공유 할 수 있습니다. 왜 코드가 작동하지 않는지 알 수 없지만 아마도 도움이 될 것입니다.

<!-- Contains customization elements for code generation from WS Security schema --> 
<schema-set show-schema="false" generate-all="false" xmlns:xs="http://www.w3.org/2001/XMLSchema" line-width="120"> 
    <schema name="oasis-200401-wss-wssecurity-secext-1.0.xsd" generate-all="true" prefer-inline="true" any-handling="mapped"> 
    <class-decorator class="org.jibx.schema.codegen.extend.CollectionMethodsDecorator" /> 
    </schema> 
</schema-set> 

다음으로 내장되어 있습니다 :

우리는 다음과 같은 사용자 정의로, 오아시스 - 200401 - WSS-wssecurity-secext-1.0.xsd 스키마에서 WS-보안 코드와 바인딩을 생성

<target name="codegen-wss" description="Regenerate JiBX bindings and generated code for WS-Security schema"> 
    <echo message="Running code generation from schema" /> 
    <mkdir dir="${gen.src.dir}" /> 
    <java classname="org.jibx.schema.codegen.CodeGen" fork="yes" classpathref="build.classpath" failonerror="true"> 
    <arg value="-c" /> 
    <arg value="custom_jibx_gen_wssec.xml" /> 
    <arg value="-t" /> 
    <arg value="${gen.src.dir}" /> 
    <arg value="wsdl/wssec/oasis-200401-wss-wssecurity-secext-1.0.xsd" /> 
    </java> 
    <move file="${gen.src.dir}/binding.xml" tofile="${wssec.binding.file}" failonerror="true" /> 
</target> 

과 함께 바인딩 :

<target name="compile" depends="init" description="Compile the source code and run JiBX binding compiler"> 
    <mkdir dir="${dest.dir}" /> 
    <javac srcdir="${src.dir}:${gen.src.dir}" destdir="${dest.dir}" deprecation="on"> 
    <classpath refid="build.classpath" /> 
    </javac> 
    <bind binding="${gen.src.dir}/xxx-binding.xml"> 
    <classpath path="${dest.dir}" /> 
    </bind> 
    <bind binding="${wssec.binding.file}"> 
    <classpath path="${dest.dir}" /> 
    </bind> 
</target> 

서블릿의 봄 설정은 t을 정의

<property name="handlerDefinitions"> 
    <list> 
    <bean class="org.jibx.ws.server.HandlerDefinition" > 
     <description>Handler for inbound WS/Security header</description> 
     <property name="className" value="org.jibx.ws.io.handler.ContextAttributeUnmarshallingInHandler" /> 
     <property name="args"> 
     <list> 
      <value>org.oasisopen.docs.wss.oasis200401wsswssecuritysecext1.SecurityHeaderType</value> 
      <value>wssecurity.header</value> 
     </list> 
     </property> 
    </bean> 

및 엔드 포인트를 사용하여 헤더를 검색 : 그는 InHandler

public ServiceRequestReceipt processRequest(ServiceRequest request, InContext inCtx, OutContext outCtx) 
    throws WsException { 
    SecurityHeaderType securityHeader = (SecurityHeaderType) inCtx.getAttribute("wssecurity.header"); 

우리의 코드를 같이 securityHeader 보이는 사용 : 나는 희망이 도움이

 if (securityHeader == null) { 
      throw new AuthenticationException("No WS-Security header found"); 
     } 

     List<Object> securityHeaderTypes = securityHeader.getSecurityHeaderTypes(); 
     if (securityHeaderTypes == null || securityHeaderTypes.size() == 0) { 
      throw new AuthenticationException("WS-Security header appears to be empty"); 
     } 

     UsernameTokenType usernameToken = null; 
     try { 
      usernameToken = (UsernameTokenType) securityHeaderTypes.get(0); 
     } catch (ClassCastException e) { 
      throw new AuthenticationException("Expected UsernameToken in WS-Security header"); 
     } 

     AttributedString usernameAttStr = usernameToken.getUsername(); 
     if (usernameAttStr == null) { 
      throw new AuthenticationException("Expected Username in WS-Security header"); 
     } 

     String username = usernameAttStr.getString(); 
     if (!username.equals(retailer.getRetailerUsername())) { 
      throw new AuthenticationException("Invalid username in WS-SecurityHeader"); 
     } 
     List<Object> any = usernameToken.getAny(); 
     if (any == null) { 
      throw new AuthenticationException("Expected Password element in WS-Security header"); 
     } 
     PasswordString passwordString = null; 
     for (Iterator iterator = any.iterator(); iterator.hasNext();) { 
      try { 
       passwordString = (PasswordString) iterator.next(); 
      } catch (ClassCastException ignore) { 
       logger.debug("Found non password string object"); 
      } 
     } 
     if (passwordString == null) { 
      throw new AuthenticationException("Expected Password in WS-Security header"); 
     } 
     if (passwordString.getAttributedString() == null) { 
      throw new AuthenticationException("Expected Password AttributedString in WS-Security header"); 
     } 

     String password = passwordString.getAttributedString().getString(); 
     if (!password.equals(retailer.getRetailerPassword())) { 
      throw new AuthenticationException("Invalid password in WS-SecurityHeader"); 
     } 

!