5

我需要在我的新 Web 服务中加入一个身份验证标头(即作为 SOAP 标头请求的一部分)。该身份验证标头将验证用户 ID 和密码详细信息。我必须在我的 Web 服务中验证请求标头详细信息的内容以进行身份​​验证。如果经过身份验证,则将处理请求的 SOAP 正文,否则 Web 服务将向调用该服务的客户端应用程序发回无效身份验证消息。

我无法理解如何创建一个 Web 服务,其中 SOAP 标头将包含一些元素(在我的例子中,身份验证元素,如 userId 和密码)。

通常,服务中公开的任何方法都将作为 SOAP 主体的一部分。因此混淆了如何继续在 SOAP 标头中添加身份验证元素。

请帮忙

问候,

4

2 回答 2

5

最近我写了一个将用户凭据添加到SOAP标题的类。为此,您需要创建一个实现SOAPHandler<SOAPMessageContext>接口的类。例如:

public class MyHandler implements SOAPHandler<SOAPMessageContext> {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class);

    private String username;

    private String password;

    /**
     * Handles SOAP message. If SOAP header does not already exist, then method will created new SOAP header. The
     * username and password is added to the header as the credentials to authenticate user. If no user credentials is
     * specified every call to web service will fail.
     *
     * @param context SOAP message context to get SOAP message from
     * @return true
     */
    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        try {
            SOAPMessage message = context.getMessage();
            SOAPHeader header = message.getSOAPHeader();
            SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
            if (header == null) {
                header = envelope.addHeader();
            }
            QName qNameUserCredentials = new QName("https://your.target.namespace/", "UserCredentials");
            SOAPHeaderElement userCredentials = header.addHeaderElement(qNameUserCredentials);

            QName qNameUsername = new QName("https://your.target.namespace/", "Username");
            SOAPHeaderElement username = header.addHeaderElement(qNameUsername );
            username.addTextNode(this.username);
            QName qNamePassword = new QName("https://your.target.namespace/", "Password");
            SOAPHeaderElement password = header.addHeaderElement(qNamePassword);
            password.addTextNode(this.password);

            userCredentials.addChildElement(username);
            userCredentials.addChildElement(password);

            message.saveChanges();
            //TODO: remove this writer when the testing is finished
            StringWriter writer = new StringWriter();
            message.writeTo(new StringOutputStream(writer));
            LOGGER.debug("SOAP message: \n" + writer.toString());
        } catch (SOAPException e) {
            LOGGER.error("Error occurred while adding credentials to SOAP header.", e);
        } catch (IOException e) {
            LOGGER.error("Error occurred while writing message to output stream.", e);
        }
        return true;
    }

    //TODO: remove this class after testing is finished
    private static class StringOutputStream extends OutputStream {

        private StringWriter writer;

        public StringOutputStream(StringWriter writer) {
            this.writer = writer;
        }

        @Override
        public void write(int b) throws IOException {
            writer.write(b);
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        LOGGER.debug("handleFault has been invoked.");
        return true;
    }

    @Override
    public void close(MessageContext context) {
        LOGGER.debug("close has been invoked.");
    }

    @Override
    public Set<QName> getHeaders() {
        LOGGER.debug("getHeaders has been invoked.");
        return null;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

请注意,我只是将凭据添加到标头并返回true. 你对整个消息做任何你想做的false事情,如果预期的事情失败,你就会返回。

我已经在客户端实现了这个:

<bean id="soapHandler" class="your.package.MyHandler">
    <property name="username" value="testUser"/>
    <property name="password" value="testPassword"/>
</bean>

<jaxws:client "...">
    <jaxws:handlers>
        <ref bean="soapHandler"/>
    </jaxws:handlers>
</jaxws:client>

但它也可以在endpoint.

于 2012-09-06T11:11:46.903 回答
0

我们只能从信封中获取标题,而不能从肥皂消息中获取。

于 2015-10-06T12:10:13.153 回答