简体   繁体   中英

Axis2 Adb Client Basic Auth over https secure url

I have serached this question on Stackoverflow and found some similar questions but none of them solved my issue. I have compiled all the "proposed" solution but NOTHING works :-( I have a wsdl and I generated the client code using adb client(Axis 2). The wsdl says that this request will be sent over Https url. I able to successfully create a stub using wsdl to java. However I am not sure how to Basic authentication. The documentation which tells me the details also says that I user name and pwd should be encoded using Base64.

The authentication method used is HTTP Basic . The user name and password will need to be encoded in a base64 format – UTF8 character set.

Example: Username:Password = “VXNlcm5hbWU6UGFzc3dvcmQ=”

BTW I have tried this wsdl in SOAP UI and and I am getting correct response but some how my java code won't work

Now Here is the wsdl

<?xml version="1.0" encoding="UTF-8"?>
<definitions targetNamespace="urn:OTSB2B" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:OTSB2B" xmlns:intf="urn:OTSB2B" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
        <schema targetNamespace="urn:OTSB2B" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:urn="urn:OTSB2B">
            <simpleType name="tn">
                <restriction base="string">
                    <length value="10"/>
                </restriction>
            </simpleType>
            <simpleType name="prov">
                <restriction base="string">
                    <length value="2"/>
                    <enumeration value="on"/>
                    <enumeration value="qc"/>
                </restriction>
            </simpleType>
            <element name="getPresaleByTN">
                <complexType>
                    <sequence>
                        <element name="tn" type="urn:tn"/>
                        <element name="prov" type="urn:prov"/>
                    </sequence>
                </complexType>
            </element>
            <element name="getPresaleByTNReturn" type="xsd:string"/>
            <element name="isAlive"/>
            <element name="isAliveReturn" type="xsd:boolean"/>
        </schema>
    </wsdl:types>
    <message name="isAliveRequest">
        <part element="impl:isAlive" name="isAlive"/>
    </message>
    <message name="getPresaleByTNRequest">
        <part element="impl:getPresaleByTN" name="getPresaleByTN"/>
    </message>
    <message name="isAliveResponse">
        <part element="impl:isAliveReturn" name="isAliveReturn"/>
    </message>
    <message name="getPresaleByTNResponse">
        <part element="impl:getPresaleByTNReturn" name="getPresaleByTNReturn"/>
    </message>
    <portType name="GetPresaleByTN">
        <operation name="getPresaleByTN">
            <input message="impl:getPresaleByTNRequest" name="getPresaleByTNRequest"/>
            <output message="impl:getPresaleByTNResponse" name="getPresaleByTNResponse"/>
        </operation>
        <operation name="isAlive">
            <input message="impl:isAliveRequest" name="isAliveRequest"/>
            <output message="impl:isAliveResponse" name="isAliveResponse"/>
        </operation>
    </portType>
    <binding name="DominoSoapBinding" type="impl:GetPresaleByTN">
        <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="getPresaleByTN">
            <wsdlsoap:operation soapAction=""/>
            <input name="getPresaleByTNRequest">
                <wsdlsoap:body use="literal"/>
            </input>
            <output name="getPresaleByTNResponse">
                <wsdlsoap:body use="literal"/>
            </output>
        </operation>
        <operation name="isAlive">
            <wsdlsoap:operation soapAction=""/>
            <input name="isAliveRequest">
                <wsdlsoap:body use="literal"/>
            </input>
            <output name="isAliveResponse">
                <wsdlsoap:body use="literal"/>
            </output>
        </operation>
    </binding>
    <service name="GetPresaleByTNService">
        <port binding="impl:DominoSoapBinding" name="Domino">
            <wsdlsoap:address location="https://b2b.ivv.bell.ca/ots-qualification-service-tn"/>
        </port>
    </service>
</definitions>

I have tried this:

GetPresaleByTNServiceStub stub = new GetPresaleByTNServiceStub();
            ServiceClient client = stub._getServiceClient();
            client.addStringHeader(new QName("userName"), "XXX");
            client.addStringHeader(new QName("password"), "YYYYYYYY");

            GetPresaleByTNServiceStub.GetPresaleByTN request = new GetPresaleByTN();
            Tn tn = new Tn();
            tn.setTn("4164390001");
            request.setTn(tn);
            request.setProv(Prov.on);

            GetPresaleByTNReturn response = stub.getPresaleByTN(request);
            System.out.println(response.getGetPresaleByTNReturn());

This gives me following error:

org.apache.axis2.AxisFault: Failed to add string header, you have to have namespaceURI for the QName at org.apache.axis2.client.ServiceClient.addStringHeader(ServiceClient.java:434) at com.dinesh.bellAxis.App.main(App.java:30)

Then I tried this

GetPresaleByTNServiceStub stub = new GetPresaleByTNServiceStub();
            ServiceClient client = stub._getServiceClient();

            HttpTransportProperties.Authenticator basicAuth = new HttpTransportProperties.Authenticator();
            basicAuth.setUsername("XXX");
            basicAuth.setPassword("CCCCC");
            basicAuth.setPreemptiveAuthentication(true);

            stub._getServiceClient().getOptions().setProperty(HTTPConstants.AUTHENTICATE, basicAuth);

            GetPresaleByTNServiceStub.GetPresaleByTN request = new GetPresaleByTN();
            Tn tn = new Tn();
            tn.setTn("4164390001");
            request.setTn(tn);
            request.setProv(Prov.on);

            GetPresaleByTNReturn response = stub.getPresaleByTN(request);
            System.out.println(response.getGetPresaleByTNReturn());

This gives me the following error:

org.apache.axis2.AxisFault: Transport level information does not match with SOAP Message namespace URI at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:90) at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:353) at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:416) at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228) at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163) at com.acn.client.GetPresaleByTNServiceStub.getPresaleByTN(GetPresaleByTNServiceStub.java:460)

Next I tried this: which I think is incorrect as it WS Security and not basic auth but what the heck I exhausted all my options

GetPresaleByTNServiceStub stub = new GetPresaleByTNServiceStub();
            ServiceClient client = stub._getServiceClient();

            OMFactory omFactory = OMAbstractFactory.getOMFactory();
            OMElement omSecurityElement = omFactory.createOMElement(new QName( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse"), null);


            OMElement omusertoken = omFactory.createOMElement(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "UsernameToken", "wsu"), null);

            OMElement omuserName = omFactory.createOMElement(new QName("", "Username", "wsse"), null);
            omuserName.setText("XXXX");

            OMElement omPassword = omFactory.createOMElement(new QName("", "Password", "wsse"), null);
            omPassword.addAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText",null );
            omPassword.setText("YYYYYYY");

            omusertoken.addChild(omuserName);
            omusertoken.addChild(omPassword);
            omSecurityElement.addChild(omusertoken);
            stub._getServiceClient().addHeader(omSecurityElement);

            GetPresaleByTNServiceStub.GetPresaleByTN request = new GetPresaleByTN();
            Tn tn = new Tn();
            tn.setTn("4164390001");
            request.setTn(tn);
            request.setProv(Prov.on);

            GetPresaleByTNReturn response = stub.getPresaleByTN(request);
            System.out.println(response.getGetPresaleByTNReturn());

This gives the following error:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot create a prefixed element with an empty namespace name at org.apache.axiom.om.impl.llom.OMElementImpl.handleNamespace(OMElementImpl.java:186) at org.apache.axiom.om.impl.llom.OMElementImpl.(OMElementImpl.java:161) at org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory.createOMElement(OMLinkedListImplFactory.java:126) at com.dinesh.bellAxis.App2.main(App2.java:37)

I am not sure what to do next and have checked all the documentation on Apache Axis2 and googled all over the place but could get the code to work.

Any suggestions

Code fragments 1 and 3 don't work because they attempt to create a message that is invalid with respect to SOAP (fragment 1) or XML (fragment 3). Anyway, they attempt to add SOAP headers to the message, which is not what basic auth is about.

Code fragment 2 looks correct. From the stack trace of the exception (more precisely the presence of the handleResponse method) you can see that there is an issue with the response. The error message likely indicates that the content type of the response doesn't match the SOAP version actually used in the response. This means that there is a problem with the service, not with the client.

I found the answer after a lot of trial and error and going over SAAj tutorial on Oracle website.

I able to do Basic authentication using this String authorization = new sun.misc.BASE64Encoder().encode((“myUserName”+”:”+”myPassword”).getBytes()); headers.addHeader(“Authorization”, “Basic ” + authorization);

Here's the complete tutorial - http://www.javahabit.com/2014/10/17/quick-tutorial-saaj-api/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM