I am trying to make a post request using RestClient with Digest Authentication .
But I keep getting error :
Cannot load all required data from authenticateHeader. Data: Realm="api domain"&Nonce="7fe0990c20aaa812c5a0a725e3a01423"&Qop="""
My code
var client = new RestClient("ApiUrlPath");
client.Authenticator = new DigestAuthenticator("username","Password");
client.UseUtf8Json();
client.Timeout = -1;
var request = new RestRequest();
request.AlwaysMultipartFormData = true;
request.AddParameter("id", "2");
var response = client.Execute(request);
The request works in postman
Related
I am calling Power school API to fetch student data. Using the below code.
public Token GetAuthToken(string baseUrl, string authKey)
{
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
var client = new HttpClient();
client.BaseAddress = new Uri(_url);
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var values = new Dictionary<string, string> { { "grant_type", "client_credentials" } };
var content = new FormUrlEncodedContent(values);
client.DefaultRequestHeaders.Add("Authorization", $"Basic {authKey}");
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
Content = content,
};
request.Headers.Add("Authorization", $"Basic {authKey}");
var response = client.PostAsync(baseUrl+ "/oauth/access_token", content).Result;
var responseString = response.Content.ReadAsStringAsync().Result;
var token = JsonConvert.DeserializeObject<Token>(responseString);
return token;
}
catch (Exception e)
{
throw;
}
finally
{
}
}
This code was working fine 3 months ago but now started giving error WebException: The request was aborted: Could not create SSL/TLS secure channel.
I tried to post the same request from POSTMAN and it was able to connect and get data. Postman shows TLS 1.2. See the below Image
I also tried the code generated from the POSTMAN and it was giving the same error. Below is the code generated from POSTMAN
var client = new RestClient("<MY URL HERE>");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Basic <MY KEY HERE>");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
I am using these on Windows Server 2012 R2. POSTMAN is able to connect while C# (.Net Framework 4.8) is failing.
What could be the issue? I tried a combination of all TLS versions available from TLS to TLS13
EDIT
When I check event logs, I am getting below error
Having a hard time converting a successful Postman request to a successful request in C#. Showing my code using HttpClient, but have also tried with PostSharp and HttpRequest. I am using a local pfx certificate file which has a password.
In Postman:
Added the PFX cert to Client Certificates
Authorization tab has username and password (Basic Auth)
Authorization header automatically generates based on above ("Basic <encoded username/password>")
Body is "{}"
Sends successfully (200).
Using HttpClient:
var host = #"https://thehost/service/verb?param1=blah¶m2=1111111";
const string certName = #"C:\Key.pfx";
const string userName = "userName";
const string certPassword = "password1";
const string authPassword = "password2";
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
// tried many combinations here
handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 |
SslProtocols.Tls12 | SslProtocols.Tls13;
var cert = new X509Certificate2(certName, certPassword);
handler.ClientCertificates.Add(cert);
//not sure if this is needed
handler.ServerCertificateCustomValidationCallback += (message, certificate2, arg3, arg4) => true;
var client = new HttpClient(handler);
//not sure if these are needed
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.ConnectionClose = true;
// added this to both the request and the client.
// Also tried "*/*" for both
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage();
request.RequestUri = new Uri(host);
request.Headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
request.Content = new StringContent("{}", Encoding.UTF8,
"application/json");
request.Method = HttpMethod.Post;
//basic auth header
var authenticationString = $"{userName}:{authPassword}";
var base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.UTF8.GetBytes(authenticationString));
var authHeader = new AuthenticationHeaderValue("Basic",
base64EncodedAuthenticationString);
request.Headers.Authorization = authHeader;
try
{
var httpResponseMessage = client.SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult();
}catch (Exception e){
Console.WriteLine(e);
throw;
}
This returns Unauthorized (401). The response text contains "Invalid user name or password."
Any thoughts on what might not be matching up between the two requests?
Have you tried using the Postman code snippets to auto-generate the code? It uses the RESTSharp REST API client library for C#.
Click on the </> icon and choose "C# - RestSharp" and it should give you code.
https://learning.postman.com/docs/sending-requests/generate-code-snippets/
In Postman I am able to generate the Bearer token using
Callback URL
Auth URL
Client ID
How do I do the same using C# code?
This is the code I am running but the response body does not have the bearer token.
var client = new RestClient("AuthURL");
var requestToken = new RestRequest(Method.POST);
requestToken.AddHeader("cache-control", "no-cache");
requestToken.AddHeader("content-type", "application/x-www-form-urlencoded");
requestToken.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&client_id=123", ParameterType.RequestBody);
IRestResponse response = client.Execute(requestToken);
string res = response.Content;
where is your username and password?
var client = new RestClient("http://example.com");
client.Authenticator = new HttpBasicAuthenticator(userName, password);
var request = new RestRequest("resource", Method.GET);
client.Execute(request);
might be a duplicate of this question
RestSharp HttpBasicAuthentication - example
I have Httpclient functions that I am trying to convert to RestSharp but I am facing a problem I can't solve with using google.
client.BaseAddress = new Uri("http://place.holder.nl/");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",access_token);
HttpResponseMessage response = await client.GetAsync("api/personeel/myID");
string resultJson = response.Content.ReadAsStringAsync().Result;
This Code is in my HttpClient code, which works good, but I can't get it to work in RestSharp, I always get Unauthorized when using RestSharp like this:
RestClient client = new RestClient("http://place.holder.nl");
RestRequest request = new RestRequest();
client.Authenticator = new HttpBasicAuthenticator("Bearer", access_token);
request.AddHeader("Accept", "application/json");
request.Resource = "api/personeel/myID";
request.RequestFormat = DataFormat.Json;
var response = client.Execute(request);
Am I missing something with authenticating?
This has fixed my problem:
RestClient client = new RestClient("http://place.holder.nl");
RestRequest request = new RestRequest("api/personeel/myID", Method.GET);
request.AddParameter("Authorization",
string.Format("Bearer " + access_token),
ParameterType.HttpHeader);
var response = client.Execute(request);
Upon sniffing with Fiddler, i came to the conclusion that RestSharp sends the access_token as Basic, so with a plain Parameter instead of a HttpBasicAuthenticator i could force the token with a Bearer prefix
Try this
RestClient client = new RestClient("http://place.holder.nl");
RestRequest request = new RestRequest("api/personeel/myID",Method.Get);
request.AddParameter("Authorization",$"Bearer {access_token}",ParameterType.HttpHeader);
request.AddHeader("Accept", "application/json");
request.RequestFormat = DataFormat.Json;
var response = client.Execute(request);
If anyone happens on this, it looks like as of V 106.6.10 you can simply add default parameters to the client to save yourself from having to add your Auth token to every request method:
private void InitializeClient()
{
_client = new RestClient(BASE_URL);
_client.DefaultParameters.Add(new Parameter("Authorization",
string.Format("Bearer " + TOKEN),
ParameterType.HttpHeader));
}
I am using Facebook C# SDK with RestClient and RestRequest Classes, in order to connect to facebook.
But every few calls I am getting the following error from facebook:
An active access token must be used to query information about the
current user
this is my code:
var client = new RestClient { Authority = "https://graph.facebook.com/v2.1/oauth/" };
var request = new RestRequest { Path = "access_token" };
request.AddParameter("client_id", Storage.FacebookClientId);
request.AddParameter("redirect_uri", CallbackUrl);
request.AddParameter("client_secret", Storage.FacebookApplicationSecret);
request.AddParameter("code", code);
RestResponse response = client.Request(request);
// A little helper to parse the querystrings.
StringDictionary result = ParseQueryString(response.Content);
sAccessToken = result["access_token"];
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
var client = new RestClient { Authority = "https://graph.facebook.com/v2.1/" };
var request = new RestRequest { Path = "me" };
request.AddParameter("access_token", sAccessToken);
RestResponse response = client.Request(request);
Dictionary<string, object> result = _serializerService.Deserialize(response.Content);
Any Ideas please?