当前位置: 首页 > 面试题库 >

在JAXWS服务器端检索Soap Header

钱黎明
2023-03-14
问题内容

我们正在尝试在我们的JAX Web服务中执行安全性实施,并在标头中传递用户名和密码,如下所示。

<soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="0" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:UsernameToken wsu:Id="Id-8zvykuwmK8yg6dxn3632nQJB" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>gears_user</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">##########</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>

在Java中,我们正在尝试检索用户名和密码,但是我们不确定该怎么做,因为它是Soap Header的一部分,并且我们之前没有检索过Header信息。

    .....
     @Resource
WebServiceContext wsctx;


public ServiceAvailabilityResponseType inquireGeographicEligibility(ServiceAvailabilityRequestType inquireGeographicEligibilityRequest)
    throws WSException
{

     HeaderList hl=(HeaderList)wsctx.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
     QName security = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", 
            "Security");    
     Header hd = hl.get(security, false);


     QName userName = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", 
        "Username");
     try
     {
         System.out.println(hd.readHeader());    
         System.out.println(hd.getAttribute(userName));
     }catch (Exception e) {
        System.out.println(e.getMessage());
    }

   }

我们正在尝试做上述操作并获取header元素,但它没有返回值。任何有关检索用户名和密码的帮助将不胜感激。


问题答案:

你可以阅读从SOAP头SOAPMessageContextSOAPHandler类,则值传递给你@WebService通过在属性的实现MessageContext

尽管该HeaderListAPI是特定于JAX-WS参考实现的,但以下示例应可在任何JAX-WS运行时中移植。

例:

Web服务暗示:

package org.example.sampleservice;

import javax.annotation.Resource;
import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;

@WebService(endpointInterface = "org.example.sampleservice.SampleService")
@HandlerChain(file="handlers.xml")
public class SampleServiceImpl implements SampleService {

    @Resource
    private WebServiceContext ctx;

    @Override
    public String sayHello(String name) {
        String usernameFromHeader = (String) ctx.getMessageContext().get("USERNAME");
        return "Hello, "
                + name
                + " (invoked by "
                + (usernameFromHeader == null ? "[err or no 'Security' header found]"
                        : usernameFromHeader) + ")";
    }

}

处理 程序 链XML( handlers.xml ,与相同的软件包中的文件SampleServiceImpl.java):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains 
     xmlns:javaee="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <javaee:handler-chain>
    <javaee:handler>
      <javaee:handler-class>org.example.sampleservice.UsernameTokenHandler</javaee:handler-class>
    </javaee:handler>
  </javaee:handler-chain>
</javaee:handler-chains>

JAX-WS处理程序类:

package org.example.sampleservice;

import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.MessageContext.Scope;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class UsernameTokenHandler implements SOAPHandler<SOAPMessageContext> {

    private static final String WSSE_NS_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
    private static final QName QNAME_WSSE_USERNAMETOKEN = new QName(WSSE_NS_URI, "UsernameToken");
    private static final QName QNAME_WSSE_USERNAME = new QName(WSSE_NS_URI, "Username");
    private static final QName QNAME_WSSE_PASSWORD = new QName(WSSE_NS_URI, "Password");

    @Override
    public boolean handleMessage(SOAPMessageContext context) {

        Boolean outbound = (Boolean) context
                .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if ((outbound != null) && (!outbound.booleanValue())) {
            handleInboundMessage(context);
        }
        return true;
    }

    private void handleInboundMessage(SOAPMessageContext context) {
        String wsseUsername = null;
        String wssePassword = null;
        try {
            SOAPHeader header = context.getMessage().getSOAPHeader();
            Iterator<?> headerElements = header.examineAllHeaderElements();
            while (headerElements.hasNext()) {
                SOAPHeaderElement headerElement = (SOAPHeaderElement) headerElements
                        .next();
                if (headerElement.getElementName().getLocalName()
                        .equals("Security")) {
                    SOAPHeaderElement securityElement = headerElement;
                    Iterator<?> it2 = securityElement.getChildElements();
                    while (it2.hasNext()) {
                        Node soapNode = (Node) it2.next();
                        if (soapNode instanceof SOAPElement) {
                            SOAPElement element = (SOAPElement) soapNode;
                            QName elementQname = element.getElementQName();
                            if (QNAME_WSSE_USERNAMETOKEN.equals(elementQname)) {
                                SOAPElement usernameTokenElement = element;
                                wsseUsername = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_USERNAME);
                                wssePassword = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_PASSWORD);
                                break;
                            }
                        }

                        if (wsseUsername != null) {
                            break;
                        }
                    }
                }
                context.put("USERNAME", wsseUsername);
                context.setScope("USERNAME", Scope.APPLICATION);

                context.put("PASSWORD", wssePassword);
                context.setScope("PASSWORD", Scope.APPLICATION);
            }
        } catch (Exception e) {
            System.out.println("Error reading SOAP message context: " + e);
            e.printStackTrace();
        }

    }

    private String getFirstChildElementValue(SOAPElement soapElement, QName qNameToFind) {
        String value = null;
        Iterator<?> it = soapElement.getChildElements(qNameToFind);
        while (it.hasNext()) {
            SOAPElement element = (SOAPElement) it.next(); //use first
            value = element.getValue();
        }
        return value;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return false;
    }

    @Override
    public void close(MessageContext context) {
    }


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

}


 类似资料:
  • 我正试图从ftp服务器检索一个文件,但我得到如下错误。请你帮帮我好吗 导入java.io.BufferedOutputStream; 导入java.io.file; 导入java.io.FileOutputStream; 导入java.io.IOException; 导入java.io.InputStream; 导入java.io.OutputStream; 导入java.text.DateFor

  • 其中map包含值。 在服务器端,我无法检索此映射。我尝试了@RequestParam Object obj,但没有成功。我不知道怎么才能把这些值拿到那里? 我需要将它转换成POST吗?

  • 问题内容: 我见过的大多数实现都是在客户端进行浏览器检测。我只是想知道是否有可能在将任何资源发送到客户端之前进行浏览器检测。 谢谢。 问题答案: 那应该为您工作。只需将其放在响应处理程序中即可。

  • 我试图通过json从在线数据库(MySql)获取数据,并希望将其显示为ListView。到目前为止我所做的: Downloader.java } 美娜ctivity.java 当我运行应用程序时,应用程序。。在Downloader.java类的第35行,我收到一条toast消息,上面写着“无法下载数据”。所以我猜我从数据库中得到的数据是空的…但为什么是空的。。。。 $con=mysqli_conn

  • 在以下片段中,是blob键吗?

  • 网防G01提供网页木马、二进制后门、弱口令扫描、漏洞扫描等服务器安全巡检功能,可以批量、快速、定时化的帮助用户排查服务器中存在的安全薄弱点。 网页木马 二进制后门 弱口令扫描 漏洞扫描 网页木马 网页木马扫描,用于检查服务器中感染网页木马的状况,可以指定需要检查的文件目录,需要检查的文件类型,配置定时巡检的策略,并生成报告提供给用户。 二进制后门 二进制后门检查,检查所选服务器是否存在的后门、可疑