20

PasswordTextWSSタイプを使用するWebサービスから情報を取得しようとしています。まず、soapUIを使用してテストし、データを正常に取得しました。次に、Javaに認証を実装し、SecurityHandlerを記述しました。

public final class SecurityHandler implements SOAPHandler<SOAPMessageContext> {

...

@Override
public boolean handleMessage(SOAPMessageContext messageContext) {
    boolean outInd = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    if (outInd) {
        try {
            WSSecUsernameToken builder = new WSSecUsernameToken();
            builder.setPasswordType(WSConstants.PASSWORD_TEXT);
            builder.setUserInfo(_username, _password);
            builder.addNonce();
            builder.addCreated();

            Document doc = messageContext.getMessage().getSOAPPart().getEnvelope().getOwnerDocument();
            WSSecHeader secHeader = new WSSecHeader();
            secHeader.insertSecurityHeader(doc);
            builder.build(doc, secHeader);
        } catch (Exception e) {
            LOGGER.error("Unable to handle SOAP message", e);
            return false;
        }
    }
    return true;
}

...
}

docオブジェクトをチェックしXMLUtils.PrettyDocumentToString(doc)て、soupUIによって送信されたXMLのように見えることを確認しました。すべての認証情報(ログイン、パスワード、ナンス、作成時刻)が設定されており、タグのmustUnderstand属性Securityがtrueでした。

それから私はエラーに直面しました:

javax.xml.ws.soap.SOAPFaultException:MustUnderstandヘッダー:[{ http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd }セキュリティ]は理解されていない

タグからmustUnderstand属性を削除するためのアドバイスを見つけましSecurityたが、役に立ちません。あなたはなにか考えはありますか?

PS

WebサービスエンドポイントはHTTPS上にあります。

WSDLのポリシー部分:

<wsp:Policy wsu:Id="BasicHttpBinding_RelateService_policy">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp:TransportBinding>
                <wsp:Policy>
                    <sp:TransportToken>
                        <wsp:Policy>
                            <sp:HttpsToken RequireClientCertificate="false"/>
                        </wsp:Policy>
                    </sp:TransportToken>
                    <sp:AlgorithmSuite>
                        <wsp:Policy>
                            <sp:Basic256/>
                        </wsp:Policy>
                    </sp:AlgorithmSuite>
                    <sp:Layout>
                        <wsp:Policy>
                            <sp:Lax/>
                        </wsp:Policy>
                    </sp:Layout>
                    <sp:IncludeTimestamp/>
                </wsp:Policy>
            </sp:TransportBinding>
            <sp:SignedSupportingTokens>
                <wsp:Policy>
                    <sp:UsernameToken
                            sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                        <wsp:Policy>
                            <sp:WssUsernameToken10/>
                        </wsp:Policy>
                    </sp:UsernameToken>
                </wsp:Policy>
            </sp:SignedSupportingTokens>
            <sp:Wss10>
                <wsp:Policy/>
            </sp:Wss10>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

soapUIリクエスト:

<soapenv:Envelope xmlns:ns="http://api.example.com/RelateService/1.0"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <wsse:Security soapenv:mustUnderstand="1"
                       xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-37"
                                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <wsse:Username>username</wsse:Username>
                <wsse:Password
                        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
                    password
                </wsse:Password>
                <wsse:Nonce
                        EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
                    li/0YK2wxrmrHL7Cg+etdQ==
                </wsse:Nonce>
                <wsu:Created>2012-02-21T08:59:10.262Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <ns:RetrieveCustomerByEmail>
            <ns:email>xxx@example.com</ns:email>
            <ns:firstName/>
            <ns:lastName/>
        </ns:RetrieveCustomerByEmail>
    </soapenv:Body>
</soapenv:Envelope>

私の要求:

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                       S:mustUnderstand="1">
            <wsse:UsernameToken wsu:Id="UsernameToken-1">
                <wsse:Username>username</wsse:Username>
                <wsse:Password
                        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
                    password
                </wsse:Password>
                <wsse:Nonce
                        EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
                    +jeleKO9zr0/wLjAIYcmSg==
                </wsse:Nonce>
                <wsu:Created>2012-02-21T09:42:03.760Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </S:Header>
    <S:Body>
        <ns5:RetrieveCustomerByEmail xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
                                     xmlns:ns2="http://schemas.datacontract.org/2004/07/XXX.Service"
                                     xmlns:ns3="http://schemas.datacontract.org/2004/07/XXX.Service.Relate.Contract"
                                     xmlns:ns4="http://schemas.datacontract.org/2004/07/XXX.Service.Dto"
                                     xmlns:ns5="http://api.example.com/RelateService/1.0"
                                     xmlns:ns6="http://schemas.microsoft.com/2003/10/Serialization/">
            <ns5:email>xxx@example.com</ns5:email>
            <ns5:firstName/>
            <ns5:lastName/>
        </ns5:RetrieveCustomerByEmail>
    </S:Body>
</S:Envelope>
4

4 に答える 4

24

サービスがヘッダーを処理しない場合、このエラーが発生する可能性があります。サービスは、ヘッダーを解決するgetHeaders()を使用してSOAPHandlerを実装する必要があります。上記の障害の場合、正しい実装は次のようになります。

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

サービスが実際に安全でないときにこれを取得することも可能ですが、クライアントはセキュリティ構成を使用しようとしています(おそらくXWSSセキュリティ構成を使用しています)これについては、ブラウザーから公開されたwsdlをチェックし、期待されるものが含まれていることを確認してくださいセキュリティポリシー(エンドポイントURLに?wsdlを追加)

于 2014-02-12T05:01:12.897 に答える
8

私は解決策を見つけました。次の依存関係が必要でした:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>2.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>2.2.3</version>
</dependency>

このトピックとcxfのいくつかの落とし穴に関する良い記事:http ://www.logicsector.com/java/how-to-create-a-wsdl-first-soap-client-in-java-with-cxf-and-maven //

于 2012-02-21T14:19:06.997 に答える
2

これが私のために働いたものです。基本的に、これは@Joseph Rajeev Mothaによって発音されたアイデアのアプリケーションです(他の場所で見つけましたが、ここ:https ://dwuysan.wordpress.com/2012/04/02/jax-ws-wsimport-and-the-error -mustunderstand-headers-not-understood /#comment-215)、しかし彼の答えは定型的なものを提供せず、それがなければ、答えはかなり神秘的です。

このシーケンスは、スタンドアロンの場合(Endpoint自分で公開する場合)に適用されることに注意してください。

ステップ1

SOAPHandlerヘッダーを「理解する」を作成します。

public class WSSESecurityUnderstandPretender implements SOAPHandler<SOAPMessageContext> {
    @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 Set<QName> headers = new HashSet<>();
        headers.add(securityHeader);

        // notify the runtime that this is handled
        return headers;
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        // we must return true, or else the runtime will return
        // wrong wrapper element name (like makeTransfer instead of
        // makeTransferResponse)
        return true;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        // we must return true, or else the runtime will return
        // wrong wrapper element name (like makeTransfer instead of
        // makeTransferResponse)
        return true;
    }

    @Override
    public void close(MessageContext context) {
    }
}

ステップ2

ファイルを作成し、handler-chain.xmlクラスパスに配置します。

<?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>com.mypackage.WSSESecurityUnderstandPretender</javaee:handler-class>
    </javaee:handler>
  </javaee:handler-chain>
</javaee:handler-chains>

ステップ3

@WebServiceハンドラーチェーンファイルへの参照を使用して、実装クラス(で注釈が付けられたクラス)に注釈を付けます。

@HandlerChain(file = "handler-chain.xml")

ステップ4

エンドポイントを公開します。

Endpoint endpoint = Endpoint.publish(url, impl);

重要な注意事項

handleMessage()handleFault()ハンドラーによって定義された場合は、を返す必要がありますtrue。そうしないと、別のラッパー要素名が使用されるため、「予期しないラッパー要素」などの奇妙なエラーが発生します。

于 2018-09-28T18:13:36.910 に答える
-2

Java 11を使用するプロジェクトでこの問題が発生した場合は、ApacheCXF3.3.xリリースを使用してみてください。Apache CXF FAQ
から以下の回答:

CXFはJDK​​/Java 9+(10、11)で実行できますか?
はい。CXFは、次の3.3.xリリースでJava9-11をサポートします。

于 2020-06-17T10:37:11.580 に答える