2012-01-12 40 views
5

Tôi đang cố truy cập dịch vụ web của bên thứ ba yêu cầu tôi để tạo tiêu đề bảo mật truyền thông tin thời gian, tên người dùng và mật khẩu. Tôi đã lướt web để làm ví dụ và đã thử nhiều cách. Tôi đang cố gắng để làm điều này chỉ với những gì được xây dựng vào Java 6. Tôi không chắc chắn những gì tôi đang làm sai. Sau khi tạo các lớp máy khách dịch vụ web của tôi từ WSDL, tôi đã tạo Trình xử lý bên dưới.com.sun.xml.ws.message.saaj.SAAJHeader không thể truyền sang com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader

import java.util.Set; 
import java.util.TimeZone; 
import javax.xml.namespace.QName; 
import javax.xml.soap.Node; 
import javax.xml.soap.SOAPElement; 
import javax.xml.soap.SOAPEnvelope; 
import javax.xml.soap.SOAPFactory; 
import javax.xml.soap.SOAPHeader; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.soap.Text; 
import javax.xml.ws.handler.MessageContext; 
import javax.xml.ws.handler.soap.SOAPHandler; 
import javax.xml.ws.handler.soap.SOAPMessageContext; 

public class MyHeaderHandler implements SOAPHandler<SOAPMessageContext> 
{ 
    public boolean handleMessage(SOAPMessageContext context) 
    { 
    String prefixUri = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-"; 
    String uri = prefixUri + "wssecurity-secext-1.0.xsd"; 
    String uta = prefixUri + "wssecurity-utility-1.0.xsd"; 
    String ta = prefixUri + "username-token-profile-1.0#PasswordText"; 
    Boolean isRequest = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 
    if(isRequest) 
    { 
     try 
     { 
     SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:dd.SSS'Z'"); 
     formatter.setTimeZone(TimeZone.getTimeZone("GMT")); 
     java.util.Date created = new java.util.Date(); 
     java.util.Date expires = new java.util.Date(created.getTime() + (5l * 60l * 1000l)); 
     SOAPMessage soapMsg = context.getMessage(); 
     SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope(); 
     SOAPHeader soapHeader = soapEnv.getHeader(); 
     if (soapHeader == null) 
      soapHeader = soapEnv.addHeader(); 
     SOAPFactory factory = SOAPFactory.newInstance(); 
     SOAPElement securityElem = factory.createElement("Security", "o", uri); 
     securityElem.addAttribute(QName.valueOf("s:mustUnderstand"), "0"); 
     SOAPElement timestampElem = factory.createElement("Timestamp", "u", uta); 
     timestampElem.addAttribute(QName.valueOf("xmlns:u"), uta); 
     timestampElem.addAttribute(QName.valueOf("Id"), "_0"); 
     SOAPElement elem = factory.createElement("Created", "u", uta); 
     elem.addTextNode(formatter.format(created)); 
     timestampElem.addChildElement(elem); 
     elem = factory.createElement("Expires", "u", uta); 
     elem.addTextNode(formatter.format(expires)); 
     timestampElem.addChildElement(elem); 
     securityElem.addChildElement(timestampElem); 
     SOAPElement usernameElem = factory.createElement("UsernameToken", "o", uri); 
     elem = factory.createElement("Username", "o", uri); 
     elem.addTextNode("xxxxx"); 
     usernameElem.addChildElement(elem); 
     elem = factory.createElement("Password", "o", uri); 
     elem.addTextNode("xxxxx"); 
     elem.addAttribute(QName.valueOf("Type"), ta); 
     usernameElem.addChildElement(elem); 
     securityElem.addChildElement(usernameElem); 
     soapHeader.addChildElement(securityElem); 
     } 
     catch(Exception e) 
     { 
     System.out.println("Handler error!!!! - " + e); 
     } 
    } 
    return true; 
    } 

public boolean handleFault(SOAPMessageContext context) 
    { 
    return true; 
    } 

public void close(MessageContext context) 
    { 
    } 

public Set<QName> getHeaders() 
    { 
    return null; 
    } 
} 

Tiếp theo, tôi đã mã hóa chương trình thử nghiệm của mình để đính kèm trình xử lý và thử gọi dịch vụ web.

import java.util.ArrayList; 
import java.util.List; 
import javax.xml.namespace.QName; 
import javax.xml.ws.handler.Handler; 
import javax.xml.ws.handler.HandlerResolver; 
import javax.xml.ws.handler.PortInfo; 
import org.tempuri.ServiceName; 
import org.tempuri.IServiceName; 


public class test 
{ 
public static void main(String[] args) 
throws Exception 
{ 
    ServiceName service = new ServiceName(new URL("https://url.to.service/services/ServiceName.svc?wsdl"), new QName("http://org.tempuri/", "ServiceName")); 
    service.setHandlerResolver(new HandlerResolver() 
    { 
    public List<Handler> getHandlerChain(PortInfo portInfo) 
    { 
     List<Handler> handlerList = new ArrayList<Handler>(); 
     handlerList.add(new MyHeaderHandler()); 
     return handlerList; 
    } 
    }); 
    IServiceName binding = service.getBasicHttpBindingIServiceName(); 
    ArrayLiist results = binding.getMyData("my parm"); 
    System.out.println("Size: " + results.size()); 
} 
} 

Khi tôi chạy này, tôi nhận được lỗi sau tại dòng nơi tôi làm binding.getMyData():

Exception in thread "main" java.lang.ClassCastException: com.sun.xml.ws.message.saaj.SAAJHeader cannot be cast to com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader 
at com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext.setJAXWSMessage(JAXBFilterProcessingContext.java:140) 
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.secureOutboundMessage(SecurityPipeBase.java:389) 
at com.sun.xml.wss.jaxws.impl.SecurityClientPipe.process(SecurityClientPipe.java:196) 
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:115) 
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595) 
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554) 
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539) 
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436) 
at com.sun.xml.ws.client.Stub.process(Stub.java:248) 
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135) 
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109) 
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89) 
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118) 
at $Proxy40.getM(Unknown Source) 
at test.main(test.java:30) 

Mỗi cách tiếp cận tôi cố gắng kết thúc tại cùng một điểm. Làm thế nào để tôi có được điều này? Tôi không thể tìm ra cách tạo SecurityHeader để đặt vào tiêu đề. Mọi sự trợ giúp sẽ rất được trân trọng. Một ví dụ làm việc sẽ là tuyệt vời.

Cảm ơn!

Trả lời

1

Khi tôi đang giải quyết vấn đề tương tự, this thread really đã giúp tôi.

Vấn đề là khi bạn có thư viện Metro (thư viện WS của Oracle) trên classpath, chúng được tự động phát hiện và bao gồm trong quá trình xử lý WS. Một chức năng là xác thực trong suốt/xử lý bảo mật, khi chính sách điểm cuối có mặt trong WSDL. Unfortunatelly xử lý bảo mật này không phải là

Tôi không thể thay đổi WSDL. Giải pháp cho tôi là loại bỏ JAR không mong muốn (wsit-rt) khỏi đường dẫn lớp.

0

Câu hỏi cũ, nhưng hiện tại tôi đã gặp vấn đề tương tự. Giải pháp là xóa các tiêu đề bảo mật bổ sung mà tôi đã đưa vào theo cách thủ công. Vì vậy, nếu bạn gặp phải sự cố này, hãy kiểm tra xem bạn có bất kỳ trình xử lý nào (SOAPHandler) viết bất kỳ tiêu đề nào vào phần tiêu đề thư của bạn <Security> phần đầu trang hay không.

Các vấn đề liên quan