I am trying to connet my C# console application with a thridparty SOAP WSDL API however I cannot get it working.
I connect to the service with the WSDL string as a Service recourse in Visual studio: https://domain.tld/SimpleAPI/SimpleAPIService.svc?singleWsdl
The documentation says:
Authentication is sessions based. The requester must provide a valid session token in the Authenticate field of each request. A session has access to the same resources and capabilities as the given user. To get a session token, use the GetSessionToken method. To validate a session, use the PingPong method.
The documentation focuses on the REST API, which is not an option for me. The two methods for connecting is as follows:
curl \ -H "Content-Type: application/json" \ -X POST -d '{ "username": "admin#domain.com", "password": "VerySecure123" }' \ https://domain.tld/SimpleAPI/SimpleAPIService.svc/rest/GetSessionToken
This should return something like this: C9C5MlqrpMwG/6bQ3mAVlm0Z6hi/eh1vsQs4i1I/g==
This part is okay, I get a token back. However when I try the PingPong method, I get an error saying that it is a wrong token or the session has expired.
curl \ -H "Content-Type: application/json" \ -H "Authenticate:CCPSessionId C9C5MlqrpMwG/6bQ3mAVlm0Z6hi/eh1vsQs4i1I/g==" \ -X POST -d '{}' \ https://domain.tld/SimpleAPI/SimpleAPIService.svc/rest/PingPong
My code is as follows:
static void Main(string[] args)
{
string apiUsername = "user";
string apiPassword = "pass";
using (var client = new acmp.SimpleAPIServiceClient())
{
client.ClientCredentials.UserName.UserName = apiUsername;
client.ClientCredentials.UserName.Password = apiPassword;
string token = client.GetSessionToken(apiUsername, apiPassword);
string tokenText = string.Format("CCPSessionId {0}", token);
using (OperationContextScope contextScope = new OperationContextScope(client.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = token; //tokenText
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
client.PingPong();
}
}
Console.WriteLine("End...");
Console.ReadLine();
}
The theory right now is that my script is not passing the correct header.
Please help, we have spend so much time debugging.
Did a little reading up, and I can't find a token text of "CCPSessionsid " anywhere.
I see "bearer", token.AccessToken
Along the lines of:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token.AccessToken);
I also came across this issue while working with the same API. Cutting the quotation marks off the string solved this for me.
request.Headers.TryAddWithoutValidation("Authenticate", token.Trim(new Char[] {'"'}));
Related
We are trying to call the Google.Cloud.AIPlatform.V1 predict API using the .Net client and keep getting the following error: Received http2 header with status: 404
We setup credentials using the API key and environment variable: GOOGLE_APPLICATION_CREDENTIALS
Here is the code to call the vertex AI predict API:
const string projectId = "xxxxxx";
const string location = "us-central1";
const string endpointId = "xxxxxx";
PredictionServiceClient client = PredictionServiceClient.Create();
var structVal = Google.Protobuf.WellKnownTypes.Value.ForStruct(new Struct
{
Fields =
{
["mimeType"] = Google.Protobuf.WellKnownTypes.Value.ForString("text/plain"),
// Sample contents is a string constant defined in a separate file
["content"] = Google.Protobuf.WellKnownTypes.Value.ForString(Consts.SampleContents)
}
});
PredictRequest req = new PredictRequest()
{
EndpointAsEndpointName = EndpointName.FromProjectLocationEndpoint(projectId, location, endpointId),
Instances = { structVal }
};
PredictResponse response = client.Predict(req);
The full error returned:
Status(StatusCode="Unimplemented", Detail="Received http2 header with status: 404", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"#1644947338.412000000","description":"Received http2 :status header with non-200 OK status","file":"......\src\core\ext\filters\http\client\http_client_filter.cc","file_line":134,"grpc_message":"Received http2 header with status: 404","grpc_status":12,"value":"404"}")
I validate the same call using CURL and was able to successfully make the call.
curl -X POST -H "Authorization: Bearer XXXXX" -H "Content-Type: application/json" https://us-central1-aiplatform.googleapis.com/ui/projects/XXXXXX/locations/us-central1/endpoints/XXXXXX:predict -d #payload.json
Any help would be greatly appreciated.
I think, we had same problem
and I was resolve that
PredictionServiceClient -> Need EndPoint of PredictionServiceClient Set,
PredictionServiceClient client = PredictionServiceClient.Create();
change please
PredictionServiceClientBuilder ClientBuilder = new PredictionServiceClientBuilder();
ClientBuilder .Endpoint = "us-central1-aiplatform.googleapis.com";
PredictionServiceClient client = ClientBuilder.Build();
thanks
Im trying to do this curl request (from API documentation) in HttpClient:
Please not that the code below is just copied from their documentation and does not contain any of my information.
POST /oauth/token (get access token)
$ curl -v -X POST https://api.tink.com/api/v1/oauth/token \
-d 'code=1a513b99126ade1e7718135019fd119a' \
-d 'client_id=YOUR_CLIENT_ID' \
-d 'client_secret=YOUR_CLIENT_SECRET' \
-d 'grant_type=authorization_code'
{
"access_token": "78b0525677c7414e8b202c48be57f3da",
"token_type": "bearer",
"expires_in": 7200,
"refresh_token": "33f10ce3cb1941b8a274af53da03f361",
"scope": "accounts:read,statistics:read,transactions:read,user:read"
}
I've tried to make a post request to the oauth/token endpoint both with all the information requested as header (with an empty body) and as a json document (with and without the headers).
When I only have the information in the headers I get a 401 back, but I've verified that all the data is correct. All other ways that I've tried has generated a 400.
As far as I can understand the json below the curl is the response, but Im not accustomed at all to curl.
There's a handy site here: https://curl.olsh.me/
I wouldn't recommend sending secrets over the web, so be sure to anonymise the values first and translate them back after.
So for the command you've pasted you'd get:
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.tink.com/api/v1/oauth/token"))
{
var contentList = new List<string>();
contentList.Add("code=1a513b99126ade1e7718135019fd119a");
contentList.Add("client_id=YOUR_CLIENT_ID");
contentList.Add("client_secret=YOUR_CLIENT_SECRET");
contentList.Add("grant_type=authorization_code");
request.Content = new StringContent(string.Join("&", contentList));
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var response = await httpClient.SendAsync(request);
}
}
The 401 headers you are getting back may be due to passing in the wrong id and secret, I presume there is a way for you to get test credentials.
I'm facing a strange error with the usage of the GITHUB API.
When I contact them with cURL it's like:
curl.exe -H "Accept: application/vnd.github.cloud-9-preview+json+scim" -H "Authorization: Bearer TOKEN" https://api.github.com/scim/v2/organizations/[ORG]/Users
When I try to take it to C#, if became:
using (var cl = new HttpClient())
{
cl.DefaultRequestHeaders.Add("Accept", "application/vnd.github.cloud-9-preview+json+scim");
cl.DefaultRequestHeaders.Add("Authorization", "Bearer " + "TOKEN");
var val = cl.GetStringAsync("https://api.github.com/scim/v2/organizations/[ORG]/Users").Result;
}
When I run my cURL everything works fine but when I try the same on C# I got a 403 Error.
Could it be related to the "Accept" non standard field?
I find out that the GITHUB API requires to have the User-Agent header Set.
Setting it as "curl" made it.
using (var cl = new HttpClient())
{
cl.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/vnd.github.cloud-9-preview+json+scim"));
cl.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "token");
cl.DefaultRequestHeaders.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue("curl", "7.46.0"));
var val = cl.GetStringAsync("https://api.github.com/scim/v2/organizations/[ORG]/Users").Result;
}
I'm trying to write a specific curl request in C#, and I keep getting a 500 server error response from the server. This curl request essentially makes a post request to an API by the company Highwinds. This request sends json data, and sets the Auth Bearer token header.
This is the curl request that works fine (note that I've replaced my actual bearer token with {token} and my actual account id with {accountId} to obfuscate that info):
curl -H "Authorization: Bearer {token}" -H "Content-Type: application/json" -d "#data.json" "https://striketracker.highwinds.com/api/accounts/{accountId}/purge"
Here's the C# code that gives me a generic 500 server error from the Highwinds API (note that I've replaced my actual bearer token with {token}, my actual account id with {accountId}, and the url in the json string with {url}, in order to obfuscate that personal info):
var accountId = "{accountId}";
var purgeURI = string.Format("https://striketracker.highwinds.com/api/accounts/{0}/purge", {accountId});
var query =
#"{""list"": [{""url"": ""{url}"",""recursive"": true}]}";
var token = {token};
using (var httpClient = new HttpClient())
{
var url = new Uri(purgeURI);
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url))
{
httpRequestMessage.Headers.Add(System.Net.HttpRequestHeader.Authorization.ToString(),
string.Format("Bearer {0}", token));
httpRequestMessage.Content = new StringContent(query,
Encoding.UTF8,
"application/json");
await httpClient.SendAsync(httpRequestMessage).ContinueWith(task =>
{
var response = task.Result;
var blah = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
});
}
}
Thanks!
*Update: The following line of code was added to remove the Expect header that HttpRequest adds to a request by default. After removing this header I was able to get Highwinds API to accept the request without bombing.
"request.ServicePoint.Expect100Continue = false;"
My best recommendation would be to proxy both requests through something like tcpmon http://archive.apache.org/dist/ws/tcpmon/1.0/ (Basically run the server and point to local host and have tcpmon redirect the request to striketracker.highwinds.com). Try it from curl and from your source and you should be able to see what's different between the requests.
How do you convert a curl to be used in C# using HttpClient?
Here is the curl call that I need to use:
Request:
curl -i \
-X POST \
-H "X-Version: 1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Your Authorization Token" \
-H "Accept: application/json" \
-d '{"text":"Test Message","to":["Recipients Mobile Number"]}' \
-s \
https://api.clickatell.com/rest/message
I have basic knowledge of HttpClient and I know nothing of curl calls so this is what I could figure from Googling. Below is my code, not sure if it is correct?
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "abcdefghij0123456789");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Add("X-Version", "1");
StringContent stringContent = new StringContent("{\"text\":\"Test Message\",\"to\":[\"27936906909\"]}");
stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync("https://api.clickatell.com/rest/message", stringContent);
if (httpResponseMessage.IsSuccessStatusCode)
{
}
else
{
string failureMsg = "HTTP Status: " + httpResponseMessage.StatusCode.ToString() + " - Reason: " + httpResponseMessage.ReasonPhrase;
}
//string sjson = await httpResponseMessage.Content.ReadAsAsync<string>();
//return sjson;
}
Everything looks correct to be but when I run it then I keep on getting a bad request. I'm not sure how to fix this? Not sure if I missed something from the curl call?
I'll reply the same thing I always reply when someone is trying to debug network issues. Install wireshark, create a session with the traffic you want to mimic, then create another one with your own code. This will allow you to see exactly what is going on and which header are not transmitted correct.