Que estamos tratando de hacer una aplicación de la seguridad en nuestros servicios web JAX y se pasa el nombre de Usuario y Contraseña en el encabezado como el siguiente.

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

En Java que estamos tratando de recuperar el nombre de Usuario y la contraseña pero no estamos seguros de como hacerlo ya que, su parte de Encabezado Soap y no hemos obtenido información de encabezado de antes.

    .....
     @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());
    }

   }

Que estamos tratando de hacer como en el anterior y obtener los elementos de encabezado, pero no devolvernos el valor. Cualquier ayuda en el camino para recuperar el nombre de Usuario y Contraseña que será apreciado.

OriginalEl autor Suraj | 2015-02-12

2 Comentarios

  1. 24

    Usted puede leer el encabezado soap de la SOAPMessageContext en un SOAPHandler de la clase, a continuación, pasar los valores a su @WebService la aplicación a través de los atributos en el MessageContext.

    Mientras que el HeaderList API es específico para el JAX-WS implementación de referencia, en el siguiente ejemplo debe ser portable a través de cualquier JAX-WS en tiempo de ejecución.

    Ejemplo:

    Servicio Web impl:

    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) + ")";
        }
    
    }

    Controlador de la cadena XML (handlers.xml, un archivo en el mismo paquete 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>

    El JAX-WS clase de controlador:

    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;
    }
    }
    Yo upvoted esta respuesta, pero luego me di cuenta de que no funciona en todos los casos. Ahora tengo un validador que implementa PasswordValidationCallback.PasswordValidator, y en este caso header.examineAllHeaderElements() devuelve un vacío interator, como si no fuese por todos los nodos en el encabezado, getChildElements() hace lo mismo. ¿Por qué es eso? El validador de alguna manera, se elimina el encabezado de la solicitud?

    OriginalEl autor Scott Heaberlin

  2. 0

    Reemplazar el getHeaders() método si usted está recibiendo el mensaje de error “MustUnderstand encabezados”.

    @Override
    public Set<QName> getHeaders() {
    final QName securityHeader = new QName(
    "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
    "Security",
    "wsse");
    final HashSet headers = new HashSet();
    headers.add(securityHeader);
    //notify the runtime that this is handled
    return headers;
    }

    OriginalEl autor Chami

Dejar respuesta

Please enter your comment!
Please enter your name here