Webservice client - c#

I'm trying to access a soap webservice i .net Core 3.1
I did add the service via Microsoft WCF Web Service Reference Provider (I typed username and password to get access.)
But I have some login issues with it.
If I try a simpel HttpClient it works fine and I get access like this:
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new Uri("http://xxx"), "Negotiate", new NetworkCredential(strUserName, strPassword, strDomain));
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = credentialCache;
var httpClient = new HttpClient(handler);
But with the WCF Web Service Reference I get this error:
One or more errors occurred. (The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate'.)'
var client = new xxClient();
var task = Task.Run(async () => await client.GetContactsFromEmailAsync(_test).ConfigureAwait(false)) ;
Console.WriteLine(task.Result.ToString());
So how do I make my client "Negotiate" ?
Or what else do I need to do?

Related

secure access to external web API .NET CORE

I have two web APIs applications developed in .Net core. I need to import Json data from the second application to the first. However,I have a security issue. I need to secure the access to the external API. How should I securely manage the connection between these two APIs.
For example, I need to secure the access to the URL in the code bellow => securely access to the covid API without another authentication.
PS: I'm using JWT token authentication in both applications
Best regards.
using (var client = new HttpClient())
{
string url = string.Format("https://covid19.mathdro.id/api");
var response = client.GetAsync(url).Result;
string responseAsString = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<CovidResult>(responseAsString);
}
If both APIs are protected by the same accessToken, then you can read the authorization header from the first request and pass it to the second request.
Something like this to read the header:
var authHeader = context.Request.Headers.Get("Authorization");
You should end up with authHeader equal to "Bearer ey...(a bunch of base64)"
Then add the auth header to the client:
var request = new HttpRequestMessage() {
RequestUri = new Uri("http://https://covid19.mathdro.id/api"),
Method = HttpMethod.Get,
};
...
request.Headers.Authorization.Add(new AuthenticationHeaderValue(authHeader));
var task = client.SendAsync(request)

HttpClient calling API doesnt not pass cookie auth

Trying to call an API from a controller using HttpClient and the API does not recognize the user as authenticated and logged in. When calling the API from JS I have no issue. I noticed the HttpClient was only sending via HTTP 1.1 and so I upgraded to 2.0 settings the DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER flag but this made no difference. I have tried all combinations of the HttpClientHandler properties including UseCookies and the request is never authenticated.
using (var handler = new HttpClientHandler {UseDefaultCredentials = true})
{
using (var httpClient = new HttpClient(handler))
{
var response = httpClient.GetStringAsync(new Uri($"https://localhost:64366/api/")).Result;
}
}
Will move to token based auth in the future but for now would like to understand why there is a difference between calling the API from C# vs JS. This is all HTTPS on localhost using asp net core 2.2.
Difference between JS and C# is that browsers attach cookies automatically to requests and you have to attach cookies manually in C# as juunas mentioned.
To obtain and use authentication cookie you may use the following pattern
CookieContainer cookies = new CookieContainer(); //this container saves cookies from responses and send them in requests
var handler = new HttpClientHandler
{
CookieContainer = cookies
};
var client = new HttpClient(handler);
string authUrl = ""; //your auth url
string anyUrl = ""; //any url that requires you to be authenticated
var authContent = new FormUrlEncodedContent(
new List<KeyValuePair<string, string>> {
new KeyValuePair<string, string>("login", "log_in"),
new KeyValuePair<string, string>("password", "pass_word")
}
);
//cookies will be set on this request
HttpResponseMessage auth = await client.PostAsync(authUrl, authContent);
auth.EnsureSuccessStatusCode(); //retrieving result is not required but you will know if something goes wrong on authentication
//and here retrieved cookies will be used
string result = await client.GetStringAsync(anyUrl);

Is it possible to use an HTTPClient with Windows authentication within an AWS Lambda function?

Is it possible to specify Windows credentials to HttpClient within an AWS Lambda function?
For example:
var handler = new HttpClientHandler {
Credentials = new NetworkCredential("username", "password", "domain")
};
var httpClient = new HttpClient(handler);
var content = new StringContent("<test>test</test>", Encoding.UTF8, "application/xml");
var response = await httpClient.PostAsync("http://someurl", "content");
The target url returns 401 Unauthorized and it looks like the NetworkCredentials haven't been passed through.
The Lambda has been granted the role AWSLambdaFullAccess.
When executed locally, this code with the same credentials works as expected.

401 Unauthorized after release site

I have my web api which uses such code to get data from other api and do some operations with it :
var credential = new NetworkCredential("login", "password");
var myCache = new CredentialCache();
myCache.Add(uri, "Negotiate", credential);
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.Credentials = myCache;
var httpClient = new HttpClient(handler);
var response = await httpClient.GetStringAsync(GetEmployeesUrl);
employees = JsonConvert.DeserializeObject<IEnumerable<EmployeeDto>>(response);
When I was debugging this code with IIS Express on my local host it's pretty good works and give me OK response from server. When I tried to deploy my api to real IIS this var response = await httpClient.GetStringAsync(GetEmployeesUrl);always returns 401 Unauthorized error.
Have someone some ideas what it can be? I have used webclient and webrequest they worked on my local machine but answer after deploy on server was the same.

System.TypeLoadException when submitting HTTP request through Httpclient

I am attempting to use the PayPal RESTful API through Xamarin Forms and am running into trouble when I try and obtain the OAuth token. Here is the code I am running, and error occurs when on Android. The authentication header I have changed here so that my client id and secret are not openly available. This is the curl command I am basing this HTTP request on also: https://developer.paypal.com/docs/integration/direct/make-your-first-call/. Thank you.
var getToken = new HttpClient(new NativeMessageHandler());
getToken.BaseAddress = new Uri("https://api.sandbox.paypal.com/v1/oauth2/token");
getToken.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
getToken.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en_US"));
getToken.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("**client_id**", "**secret**");
getToken.DefaultRequestHeaders.TryAddWithoutValidation("content-type", "application/x-www-form-urlencoded");
OAuthDetails clientCredentials = new OAuthDetails("client_credentials");
HttpResponseMessage tokenResponse = await getToken.PostAsJsonAsync("/v1/oauth2/token", clientCredentials);
AccessResponse accessInfo = await tokenResponse.Content.ReadAsAsync<AccessResponse>();
The way to send a post request with application/x-www-form-urlencoded is like this: instead of TryAddWithoutValidation you need to do this and then include this as the content in the request instead of client credentials like I did previously.
var tokenContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "client_credentials"
});

Categories