Send username/password to SOAP Service - apigee

I created a WDSL API-Proxy, everything works find but as expected i'm receiving an Authentication error because i'm not sending the correct user and password to the SOAP server, where do i set that?

Maybe you need pass username and password in header request.

Typical you will include an Authorization header for a SOAP call. I typically do these in an assign message policy like the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<AssignMessage name="buildSoapMessage">
<DisplayName>buildSoapMessage</DisplayName>
<AssignTo createNew="true" type="request">request</AssignTo>
<Set>
<Headers>
<Header name="Authorization">{request.header.Authorization}</Header>
</Headers>
<Verb>POST</Verb>
<Payload contentType="text/xml">
<Request xmlns="urn:foo:bar:1.0">

Related

How to force soap header authentication for my scenario?

The problem is: I need to connect to a soap web service; generated by java code; using ASP.Net client via C# through MS Visual Studio 2013.
Try 1, The usual way:
I have added a web service reference using the wsdl and by assigning the credentials like:
Credentials.Username.Username = "test";
Credentials.Password.Password = "test";
When executing, the following exception is being encountered:
The login information is missing!
Try 2:
I have searched for similar problems like:
how-to-go-from-wsdl-soap-request-envelope-in-c-sharp
Dynamic-Proxy-Creation-Using-C-Emit
c# - Client to send SOAP request and received response
I had chosen to generate a proxy class using the wsdl tool, then added the
header attribute, but I have found the following note from Microsoft:
Note: If the Web service defines the member variables representing the SOAP headers of type SoapHeader or SoapUnknownHeader instead of a class deriving from SoapHeader, a proxy class will not have any information about that SOAP header.
Try 3:
I have tried to change the service model in the client web.config:
<bindings>
<basicHttpBinding>
<binding name="CallingCardServicePortBinding">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
Then added the credentials like the first try, but the following error appears:
MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood
So, now I don't know what to do !
I have no control over the web service and I need to build a client that understands it.
Help Please!
The Soap Request template is the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="...">
<soapenv:Header>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</soapenv:Header>
<soapenv:Body>
<ser:someRequest>
.......
.......
.......
</ser:someRequest>
If the destination web service uses authentication, then just ASMX won't do, since it is not aware of authentication, encryption etc. You have 2 options:
Use Microsoft WSE: http://www.microsoft.com/en-us/download/details.aspx?id=14089
this is nothing but an extension of ASMX which makes it Security/Encryption aware. (and some other features) technically, you'll be adding a reference to the WSE DLL and your Soap Proxy will extend from the WSE SOAP Client instead of the System one.
once you do that, the proxy class will have additional username/password properties that you can use to authenticate properly.
set the properties and see the outgoing request using fiddler. if the header is not what you want (because of namespaces etc.), then you can write a custom outgoing message inspector and modify the soap request nicely.
The other option (preferred) is to use WCF.
ASMX and WSE are older than WCF. WCF tries to bring all the web service nuances under one roof. if you get a WCF service reference, it (svcutil.exe) will automatically create the proxy class and the right bindings for you. (mostly custom)
once you do that, try setting the user name and password.
if that doesn't work, (i have frequently struggled to generate the right soap header for remote java based services that require username/password authentication), you can define a static header chunk in the web.config/app.config, that'll be sent as part of every request.
e.g.
<client>
<endpoint>
<headers>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</headers>
</endpoint>
</client>

Apigee: Using environment name to extract variable

I have set up a custom variable in my developer app called sandbox.app_id so I can have different ids for different applications.
I am using the verify api key policy and this populate the verifyapikey.* variables.
I want an ExtractVariable policy similar to below:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-TLRG-App-ID">
<DisplayName>Extract TLRG App ID</DisplayName>
<FaultRules/>
<Properties/>
<Variable name="app_id">verifyapikey.verify-api-key.{environment.name}.app_id</Variable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>
Is this possible, or will I have to resort to javascript?
Basically you are trying to access custom application attributes from your extract variable policy. So you need to place this extract variable policy after your verify api key policy. A verify api key policy would load all the application attributes as flow variables for a valid key. You may not see the custom attributes as variables in the debug view. However correct way to access the variables is to use this naming format below:
verifyapikey.{your_policy_name}.app.{custom_attribute_name}
Note that the verify api key policy is mandatory, otherwise the application associated with the API call can not be identified.

Apigee RouteRule evaluates correctly but then returns a 503

I have two Resources set up for my API proxy and have a route rule named talkback that should take POST requests to my /matches API resource and route them to my talkback subdomain rather than www.
I have this working correctly for GET requests that redirect to my open subdomain. However the talkback rule correctly evaluates but then returns a 503 without reaching my target endpoint:
error The Service is temporarily unavailable
error.cause Connection refused
error.class com.apigee.messaging.adaptors.http.HttpAdaptorException
state TARGET_REQ_FLOW
type ErrorPoint
Are you able to advise on what may be the issue?
This is the route rule I'm using:
<RouteRule name="talkback">
<Condition>(proxy.pathsuffix MatchesPath "/matches/**") and (request.verb equals "POST")</Condition>
<TargetEndpoint>talkback</TargetEndpoint>
</RouteRule>
This is the talkback target endpoint:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="talkback">
<Description/>
<FaultRules/>
<Flows/>
<HTTPTargetConnection>
<Properties/>
<URL>http://talkback.test.xxxx.co.uk/gapi</URL>
</HTTPTargetConnection>
<PreFlow name="PreFlow">
<Request/>
<Response/>
</PreFlow>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</TargetEndpoint>
This pretty much looks like an issue where Apigee is not able to connect to your target backend - http://talkback.test.xxxx.co.uk. Apigee throws a 503 back to the client when its unable to connect to the backend. Is the backend publicly accessible?

Calling a GET on the Apigee HTTPTargetConnection when the request was POST

I need to call a legacy API which uses GET.
My API proxy uses POST.
I tried using in AssignMessage:
<AssignTo type="request" createNew="false"/>
and
<Set> ... <Verb>GET</Verb>
But it still does a POST on the target API.
What is the proper way of converting?
Will the gateway automatically convert the POST form parameters into GET query parameters?
Is message.queryparam the same for both GET and POST?
When converting the Verb from POST to GET, the policy will NOT automatically convert the form parameters to query parameters. You will need to use the <Add> and/or <Remove> functionality of the AssignMessage policy to manipulate the message further. Example use in the AssignMessage policy to add the queryparams, referencing the formparams:
<Add>
<QueryParams>
<QueryParam name="q1">{request.formparam.q1}</QueryParam>
</QueryParams>
</Add>
Also, in your question you mentioned that the API Proxy accepts the request using method as POST. Then, you have a policy to set GET:
<Set> ... <Verb>GET</Verb>
But it still does a GET on the target API.
What's the problem? Isn't that what you are expecting? The request goes into the Apigee API Proxy as POST, the proxy converts the method (verb) to GET, and sends the request to the backend legacy API using GET.
Note: <AssignTo> is optional in the AssignMessage. Try leaving this out if the method is not being set properly. In its absence, the message at the current point in the flow will be modified.
Change this predefined variable to post
request.verb = "GET"
Note: If you do this and you have a flow condition based on request.verb="POST" that will not work well in the response. So you need to use another variable to use in the flow condition.
Here is the policy code that worked for me.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="changeverbassignmessage">
<DisplayName>ChangeVerbAssignMessage</DisplayName>
<FaultRules/>
<Properties/>
<AssignVariable>
<Name>request.verb</Name>
<Value>GET</Value>
<Ref/>
</AssignVariable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Webservice with security headers

I'm trying to consume a third party webservice (from the Component Interface in Peoplesoft), but in order to authenticate I have to have a header that looks like this:
<soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>X</wsse:Username>
<wsse:Password>X</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
I added a block to the web.config file in my app that's trying to use the webservice as follows:
<system.serviceModel>
<client>
<header>
<endpoint>
<wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>X</wsse:Username>
<wsse:Password>X</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</endpoint>
</header>
</client>
</system.serviceModel>
But the header still doesn't appear in the XML request to the webservice.
Am I even on the right track?
If you're using .NET 2.0 to connect to the service, your best bet is to download WSE 3.0 (WSE 2.0 if you're using .NET 1.1).
If you're using WCF to connect to the service, here's a link that should help you along your way. It's about the proper way to implement the WS-Security standard in WCF:
Enterprise .NET Community: Security your WCF Services
Look at this link : http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/03db0772-b319-468c-9298-0ec301dacf34
I never though WCF will not allow a simple username token on http

Resources