RestSharp HttpBasicAuthentication - example - c#

I have a WPF client using RestSharp and WEB API Service. I try to use HttpBasicAuthenticator as follows:
RestRequest login = new RestRequest("/api/users/login", Method.POST);
var authenticator = new HttpBasicAuthenticator("admin","22");
authenticator.Authenticate(Client, login);
IRestResponse response = Client.Execute(login);
The POST request looks like this:
POST http://localhost/api/users/login HTTP/1.1
Authorization: Basic YWRtaW46MjI=
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp/105.1.0.0
Host: dellnote:810
Content-Length: 0
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
How do I process this field, Authorization: Basic YWRtaW46MjI= on the server side? Do I get username and password from this header?
How do I return security token from server to client and save it on the client side?
I need to get simple authentication based on security token but cannot find example that describes all sides of this process. Can someone point me to some full example that includes client and server side (and uses RestSharp).

new SimpleAuthenticator("username", username, "password", password) did NOT work with me.
The following however worked:
var client = new RestClient("http://example.com");
client.Authenticator = new HttpBasicAuthenticator(userName, password);
var request = new RestRequest("resource", Method.GET);
client.Execute(request);

From RestSharp documentation:
var client = new RestClient("http://example.com");
client.Authenticator = new SimpleAuthenticator("username", "foo", "password", "bar");
var request = new RestRequest("resource", Method.GET);
client.Execute(request);
The URL generated for this request would be http://example.com/resource?username=foo&password=bar
So you get the password just as any other parameter (although, it's recommended to use POST method then GET, for security reasons).
As for the cookies, check this out:
https://msdn.microsoft.com/en-us/library/system.windows.application.setcookie.aspx
https://msdn.microsoft.com/en-us/library/system.windows.application.getcookie.aspx
Hope it helps

The following worked for me:
private string GetBearerToken()
{
var client = new RestClient("http://localhost");
client.Authenticator = new HttpBasicAuthenticator("admin", "22");
var request = new RestRequest("api/users/login", Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{ \"grant_type\":\"client_credentials\" }", ParameterType.RequestBody);
var responseJson = _client.Execute(request).Content;
var token = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseJson)["access_token"].ToString();
if(token.Length == 0)
{
throw new AuthenticationException("API authentication failed.");
}
return token;
}

RestClient restClient = new RestClient(baseUrl);
restClient.Authenticator = new RestSharp.Authenticators.HttpBasicAuthenticator("admin","22");
RestRequest login = new RestRequest("/api/users/login", Method.POST);
IRestResponse response = restClient.Execute(login);

Alternative answer your first question about retrieval of Auth Header values (Server Side) from How can I retrieve Basic Authentication credentials from the header?:
private UserLogin GetUserLoginCredentials()
{
HttpContext httpContext = HttpContext.Current;
UserLogin userLogin;
string authHeader = httpContext.Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
int seperatorIndex = usernamePassword.IndexOf(':');
userLogin = new UserLogin()
{
Username = usernamePassword.Substring(0, seperatorIndex),
Password = usernamePassword.Substring(seperatorIndex + 1)
};
}
else
{
//Handle what happens if that isn't the case
throw new Exception("The authorization header is either empty or isn't Basic.");
}
return userLogin;
}
Usage of this method might be:
UserLogin userLogin = GetUserLoginCredentials();
Also have a look at: A-WebAPI-Basic-Authentication-Authorization-Filter
Alternative answer on second question about returning the token (Server Side):
var httpResponseMessage = Request.CreateResponse();
TokenResponse tokenResponse;
bool wasAbleToGetAccesToken = _identityServerHelper.TryGetAccessToken(userLogin.Username, userLogin.Password,
platform, out tokenResponse);
httpResponseMessage.StatusCode = wasAbleToGetAccesToken ? HttpStatusCode.OK : HttpStatusCode.Unauthorized;
httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(tokenResponse),
System.Text.Encoding.UTF8, "application/json");
return httpResponseMessage;

Related

WebException: The request was aborted: Could not create SSL/TLS secure channel but working with POSTMAN

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

C# REST Api always return 401 status code when i am calling API by HttpClient

I am working with Nasdaq Fund Network Data Service first time. i am calling their one of the API where passing user id,pwd and access key but always getting 401 status code. i am not able to figure out what is wrong in my http call. please some one have a look at the code and tell me where i made the mistake for which i am getting 401 status code instead of right response.
here is my sample code where i could not share actual credentials and access key.
giving the code
string url = "sample url";
Uri u = new Uri(url);
string username = "test1";
string password = "test2";
string accessKey = "myaccesskey";
var payload = new Dictionary<string, string>
{
{"username", username},
{"password", password},
{ "accessKey", accessKey}
};
string strPayload = JsonConvert.SerializeObject(payload);
//HttpContent c = new StringContent(strPayload, Encoding.UTF8, "application/json");
HttpContent c = new StringContent(strPayload, Encoding.UTF8, "application/x-www-form-urlencoded");
var response = string.Empty;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
using (var client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = u,
Content = c
};
var result = client.SendAsync(request).Result;
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}
This Error i am getting
{StatusCode: 401, ReasonPhrase: 'Check Username/Password or Access
Key', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: {
Pragma: no-cache X-Frame-Options: SAMEORIGIN Cache-Control:
no-cache Date: Wed, 10 Aug 2022 11:55:36 GMT Content-Length: 0
Expires: -1 }}
Try the following in order to extract the JWT token you receive as a response.
var url = "https://nfn.nasdaq.com/servicecall/tempsession";
var formDataDictionary = new Dictionary<string, string>
{
{ "username", "test1"},
{ "password", "test2"},
{ "accessKey", "myaccesskey"}
};
var formData = new FormUrlEncodedContent(formDataDictionary);
using (var client = new HttpClient())
{
var response = await client.PostAsync(url, formData);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
var responseBody = JObject.Parse(result);
var accessToken = responseBody["data']"].Value<string>();
}

How can i include Proxy Server authentication in a Rest request?

I have a rest request as follows
var client = new RestClient(url);
var request = new RestRequest { Method = Method.GET, Resource = $"v2/userdetails" };
request.AddHeader("Authorization", $"Bearer {token}");
var response = client.Execute(request);
if (response.StatusCode == HttpStatusCode.OK)
return JsonConvert.DeserializeObject<List<UserDetails>>(response.Content);
return null;
It returns null, I was informed that there is a Proxy Server in the middle.
So do I need to include the proxy server settings in the request and authenticate first ?
If so how can i do that ?

Get OAuth2.0 Bearer Token from AuthURL and ClientID

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

Converting HttpClient to RestSharp

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));
}

Categories