axis2 + rampart  调用基于ws-trust的.net webservice 碰到的问题总结

1. 首先请求是https或者需要证书签名的,需要把证书和private key导入java 的keystore。不过一般.net服务端给的证书是.pfx格式的,我也没找到太好的办法导入,于是就把证书转换成jks的,然后重命名为cacerts,此时你需要把keystore的密码改为"changeit"。

2.  我用的是axis2 1.5.1 和 rampart 1.4 , 如果wsdl如果存在多个endpoint的时候,用wsdl2java工具生成客户端是会抛错: "can not determine the MEP ".

3.  配置sts-config.xml
<wsp:Policy wsu:Id="STS"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<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:EndorsingSupportingTokens>
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
</wsp:Policy>
</sp:X509Token>
<sp:SignedParts
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
</wsp:Policy>
</sp:EndorsingSupportingTokens>
<sp:Wss11>
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier />
<sp:MustSupportRefIssuerSerial />
<sp:MustSupportRefThumbprint />
<sp:MustSupportRefEncryptedKey />
</wsp:Policy>
</sp:Wss11>
<sp:Trust10>
<wsp:Policy>
<sp:MustSupportIssuedTokens />
<sp:RequireClientEntropy />
<sp:RequireServerEntropy />
</wsp:Policy>
</sp:Trust10>

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user> le-8066a9f7-c96a-4c3c-85a8-47121aed3a19
</ramp:user>
<ramp:passwordCallbackClass>com.mimeo.sandbox.client.sts.PWCBHandler
</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property
name="org.apache.ws.security.crypto.merlin.keystore.type">PKCS12</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file">
./reposity/keys/XXX.pfx</ramp:property>
<ramp:property
name="org.apache.ws.security.crypto.merlin.keystore.alias"> le-8066a9f7-c96a-4c3c-85a8-47121aed3a19
</ramp:property>
<ramp:property
name="org.apache.ws.security.crypto.merlin.keystore.password">xxxxxxx</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

红色部分为证书的别名。

4.  .net 支持的saml token 是1.0版本的,rampart 请求sts 服务后解析返回xml时是取不到token id 的,需要修改STSClient.java的源代码,需要从"AssertionID"这个属性中取得token id。
private String findIdentifier(OMElement reqAttRef,
                                  OMElement reqUnattRef,
                                  OMElement token) {
        String id;
        if (reqAttRef != null) {
            //First try the attached ref
            id = this.getIdFromSTR(reqAttRef);
        } else if (reqUnattRef != null) {
            //then try the unattached ref
            id = this.getIdFromSTR(reqUnattRef);
        } else {
            //Return wsu:Id of the token element
            id = token.getAttributeValue(new QName(WSConstants.WSU_NS, "Id"));
        }
        if (id == null){
        id = "#" + token.getAttributeValue(new QName("AssertionID"));
        }

        return id;
    }

5.  配置policy.xml (调用服务时的ws policy)
<wsp:Policy
wsu:Id="Scenario_5_IssuedTokenForCertificate_MutualCertificate11_policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding
                    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <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:EndorsingSupportingTokens
                    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:IssuedToken
                            sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                            <Issuer
                                xmlns="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                                <Address
                                    xmlns="http://www.w3.org/2005/08/addressing">http://xxxxx/AuthenticationService.svc</Address>
                            </Issuer>
                            <sp:RequestSecurityTokenTemplate>
                                <t:TokenType
                                    xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
                                <t:KeyType
                                    xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey</t:KeyType>
                                <t:KeySize
                                    xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">256</t:KeySize>
                            </sp:RequestSecurityTokenTemplate>
                            <wsp:Policy>
                                <sp:RequireInternalReference/>
                            </wsp:Policy>
                        </sp:IssuedToken>
                        <!--<sp:SignedParts>
                            <sp:Header
                                Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
                        </sp:SignedParts>-->
                      </wsp:Policy>
                </sp:EndorsingSupportingTokens>
                <sp:Wss11
                    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:MustSupportRefKeyIdentifier/>
                        <sp:MustSupportRefIssuerSerial/>
                        <sp:MustSupportRefThumbprint />
<sp:MustSupportRefEncryptedKey />
                    </wsp:Policy>
                </sp:Wss11>
                <sp:Trust10
                    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:MustSupportIssuedTokens/>
                        <sp:RequireClientEntropy/>
                        <sp:RequireServerEntropy/>
                    </wsp:Policy>
                </sp:Trust10>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

6.  此时调用.net的webservice还是不成功,在对比了.net客户端发出的消息后发现
<KeyInfo>
       <o:SecurityTokenReference>
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-  1.1#ThumbprintSHA1">XqQ6CjOEBvBddZtWdSue8LOyUxE=</o:KeyIdentifier>
       </o:SecurityTokenReference>
</KeyInfo>
用的是<o:KeyIdentifier>标签,而axis2发出的用的是<wsse:Reference>标签,在ws-trust文档里说明这两种标签都是可以的,不知道为什么调用.net时用<Reference>就不行。如果要使用<keyidentifier>就需要修改WSS4J包中WSSecSignature.java的源代码:

case WSConstants.CUSTOM_SYMM_SIGNING:
//            Reference refCust = new Reference(document);
//            refCust.setValueType(this.customTokenValueType);
//            refCust.setURI("#" + this.customTokenId);
//            secRef.setReference(refCust);

            Document doc1 = secRef.getElement().getOwnerDocument();
            Element keyId = doc1.createElementNS(WSConstants.WSSE_NS,"wsse:KeyIdentifier");
            keyId.setAttributeNS(null, "ValueType", this.customTokenValueType);
            keyId.setAttributeNS(null, "EncodingType",BinarySecurity.BASE64_ENCODING);
            keyId.appendChild(doc1.createTextNode(this.customTokenId));
            Element elem = secRef.getFirstElement();
            if (elem != null) {
                secRef.getElement().replaceChild(keyId, elem);
            } else {
                secRef.getElement().appendChild(keyId);
            }

            break;

再调用.net的服务,此时就成功了。其中碰到的其他小问题还是挺多的,总之要看axis2 + rampart 的源代码, 加上不断的断点调试。

你可能感兴趣的:(xml,.net,webservice)