【问题标题】:How to create a soap service which requires username/password in soap Header如何在soap Header中创建需要用户名/密码的soap服务
【发布时间】:2015-09-19 16:58:18
【问题描述】:

请让我澄清我的要求。以下是我知道/学到的相关要求。

  1. 添加 ws-security 标头。 (我使用 apache 壁垒做到了。使用 UsernameToken 进行身份验证) http://www.ibm.com/developerworks/library/j-jws4/
  2. 访问 web 服务的容器级安全约束(我确实使用了 web.xml 中所需的配置) http://www.mkyong.com/webservices/jax-ws/container-authentication-with-jax-ws-tomcat/
  3. 用户名/密码绑定为 Http 请求标头的应用程序级别。 http://www.mkyong.com/webservices/jax-ws/application-authentication-with-jax-ws/

以上三种我不想要的方式。我的要求是添加采用 username/password 的自定义标头元素。对于我们的一位客户,我遇到了这个要求。他们的wsdl部分如下

<s:element name="AuthenticationHeader" type="tns:AuthenticationHeader" />
      <s:complexType name="AuthenticationHeader">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="UserName" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string" />
        </s:sequence>
        <s:anyAttribute />
      </s:complexType>

xmlns 前缀 s=http://www.w3.org/2001/XMLSchema

在客户端,我通过在soap标头中提供上述复杂类型元素来使用服务

现在我想知道如何创建一个可以接受上述soap-header的soap服务。

提前致谢

【问题讨论】:

    标签: java web-services soap wsdl


    【解决方案1】:

    我还看到了一些在提供的 XSD 中可能会更好的东西。复杂类型可以为全局元素指定不同的名称。

    <s:element name="AuthenticationHeader" type="tns:AuthenticationHeaderType" />
          <s:complexType name="AuthenticationHeaderType">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="UserName" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string" />
            </s:sequence>
            <s:anyAttribute />
          </s:complexType>
    

    如果xsd如上所述,实现如下

      AuthenticationHeader authenticationHeader = new AuthenticationHeader();
     AuthenticationHeaderType authenticationHeaderType = new AuthenticationHeaderType();
        authenticationHeaderType.setUsername("MyUsername");
        authenticationHeaderType.setPassword("MyPassword");
    
    authenticationHeader.setAuthenticationHeader(authenticationHeaderType ); 
    

    将上述 authenticationHeader 对象与 webservice 请求对象一起附加。


    您的示例将根据我从您提供的块中准备的 xsd 创建以下类

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        attributeFormDefault="unqualified" elementFormDefault="unqualified">
    <xs:element name="AuthenticationHeader" type="AuthenticationHeader" />
          <xs:complexType name="AuthenticationHeader">
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="1" name="UserName" type="xs:string" />
              <xs:element minOccurs="0" maxOccurs="1" name="Password" type="xs:string" />
            </xs:sequence>
            <xs:anyAttribute />
          </xs:complexType>
          </xs:schema>
    

    生成的类如下

    ObjectFactory.java

    import javax.xml.bind.JAXBElement;
    import javax.xml.bind.annotation.XmlElementDecl;
    import javax.xml.bind.annotation.XmlRegistry;
    import javax.xml.namespace.QName;
    
    
    /**
     * This object contains factory methods for each 
     * Java content interface and Java element interface 
     * generated in the com.auth package. 
     * <p>An ObjectFactory allows you to programatically 
     * construct new instances of the Java representation 
     * for XML content. The Java representation of XML 
     * content can consist of schema derived interfaces 
     * and classes representing the binding of schema 
     * type definitions, element declarations and model 
     * groups.  Factory methods for each of these are 
     * provided in this class.
     * 
     */
    @XmlRegistry
    public class ObjectFactory {
    
        private final static QName _AuthenticationHeader_QNAME = new QName("", "AuthenticationHeader");
    
        /**
         * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.auth
         * 
         */
        public ObjectFactory() {
        }
    
        /**
         * Create an instance of {@link AuthenticationHeader }
         * 
         */
        public AuthenticationHeader createAuthenticationHeader() {
            return new AuthenticationHeader();
        }
    
        /**
         * Create an instance of {@link JAXBElement }{@code <}{@link AuthenticationHeader }{@code >}}
         * 
         */
        @XmlElementDecl(namespace = "", name = "AuthenticationHeader")
        public JAXBElement<AuthenticationHeader> createAuthenticationHeader(AuthenticationHeader value) {
            return new JAXBElement<AuthenticationHeader>(_AuthenticationHeader_QNAME, AuthenticationHeader.class, null, value);
        }
    
    }
    

    AuthenticationHeader.java

    import java.util.HashMap;
    import java.util.Map;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlAnyAttribute;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlType;
    import javax.xml.namespace.QName;
    
    
    /**
     * <p>Java class for AuthenticationHeader complex type.
     * 
     * <p>The following schema fragment specifies the expected content contained within this class.
     * 
     * <pre>
     * &lt;complexType name="AuthenticationHeader">
     *   &lt;complexContent>
     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
     *       &lt;sequence>
     *         &lt;element name="UserName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
     *         &lt;element name="Password" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
     *       &lt;/sequence>
     *       &lt;anyAttribute/>
     *     &lt;/restriction>
     *   &lt;/complexContent>
     * &lt;/complexType>
     * </pre>
     * 
     * 
     */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "AuthenticationHeader", propOrder = {
        "userName",
        "password"
    })
    public class AuthenticationHeader {
    
        @XmlElement(name = "UserName")
        protected String userName;
        @XmlElement(name = "Password")
        protected String password;
        @XmlAnyAttribute
        private Map<QName, String> otherAttributes = new HashMap<QName, String>();
    
        /**
         * Gets the value of the userName property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getUserName() {
            return userName;
        }
    
        /**
         * Sets the value of the userName property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setUserName(String value) {
            this.userName = value;
        }
    
        /**
         * Gets the value of the password property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getPassword() {
            return password;
        }
    
        /**
         * Sets the value of the password property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setPassword(String value) {
            this.password = value;
        }
    
        /**
         * Gets a map that contains attributes that aren't bound to any typed property on this class.
         * 
         * <p>
         * the map is keyed by the name of the attribute and 
         * the value is the string value of the attribute.
         * 
         * the map returned by this method is live, and you can add new attribute
         * by updating the map directly. Because of this design, there's no setter.
         * 
         * 
         * @return
         *     always non-null
         */
        public Map<QName, String> getOtherAttributes() {
            return otherAttributes;
        }
    
    }
    

    您可以通过以下方式实现您的代码

    public class ImplementAuthentication {
    
        void authentication() {
    
            AuthenticationHeader authenticationHeader = new AuthenticationHeader();
    
            authenticationHeader.setPassword("MyPassword");
            authenticationHeader.setUserName("MyUsername");
    
            ObjectFactory obj = new ObjectFactory();
    
            obj.createAuthenticationHeader(authenticationHeader);
        }
    }
    

    【讨论】:

    • 这个类 AuthenticationHeaderType 是什么,它是 ws 库的一部分吗?
    • 嗨,我看到您对复杂类型和全局元素使用相同的名称。请尝试生成上述xsd的代码并尝试设置对象。
    • 请检查实施。我希望你的样本现在清楚了吗?
    • 还有一件事。如何将此附加到肥皂服务标头。我在我的 impl 类中遵循以下方法来覆盖方法 public String getHelloWorldAsObject(@WebParam (name="HelloObject") String name) { return "Name Passed : "+new HelloMessage(name).getName(); }
    • 知道了,你已经添加了。只是检查。我会尝试,但我认为这会有所帮助,我可以继续
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    相关资源
    最近更新 更多