cURL and .Net (c#) API Token (Token is Invalid) - c#

I've searched all over the internet and stackoverflow...can't really figure out if it's a code problem or the API is not valid anymore with some tokens...
I've looked through this Stackoverflow thread and tried it out and nothing. The only thing that returns is "TOKEN is invalid".
I'm trying to list the users from this event which has an API here.
This is my code:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://services.sapo.pt/Codebits/user/1/");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("&token=NTUyI0FmY29zdGEjYW5kcmVjb3N0NEBnbWFpbC5jb20jZDkwMDdhNWUxOTNiN2VhMzcwMWJjNjI3MjMwMmI2YTQjMTQzMjU2NDU1NSNhMTc3YTdkZjNlYzk2MTg3ZjZmNzk1NTc3YjEwMDExOTcwNDE1ZTZj").Result;
HttpContent responseContent = response.Content;
// //// Get the stream of the content.
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
// // return (await reader.ReadToEndAsync());
if (response.IsSuccessStatusCode)
{
tb1.Text = await reader.ReadToEndAsync();
}
else
{
tb1.Text = "x";
}
}
Since i'm kinda noob, I hope and think it is my problem but I just can't figure it out.
Thanks in advance!

What part of "TOKEN is invalid" is unclear?
Their API help page mentions:
AUTHENTICATION AND USERS
AUTH TOKEN
https://services.sapo.pt/Codebits/gettoken?user=wookiee#sapo.pt&password=grumph
Get the auth token. Will be used as a &token= argument with all the methods that require authentication. Please be aware that tokens may expire (due to timeout, IP change or others). The correct procedure for an app is to ask for a new token if the one it has fails in any of the methods that require authentication.
So when a call fails with "TOKEN is invalid", first make a gettoken call to obtain a valid token.

Related

How to call a web api that has Oauth 2.0

Hi so we have an external web api we want to call to get data out. It is using oauth 2.0. Can somebody please explain how we would go about doing this in .NET either vb.net or c#. I have in the past created api, however this one seems very complicated. Firstly you have to be signed into their oauth web page they have which generates some cookies, using these cookies by syncing them up in postman we can see the data, however we need this to be within our .net app. Can somebody please help how we go about this. Some code would be useful.
Thanks
This is how usually OAuth 2 authentication works.
You basically log in with username and password (optional second factor) and then you receive a token, the so called Json Web Token or JWT (it holds encrypted information about your user, your access roles or groups you are member of as well as some timestamp which is the expiration time of the token).
In every subsequent request you make to the server, you pass this token in the request header (or in your case as cookie).
Example code:
Login request:
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, new Uri(_baseUrl, "token"));
string body = JsonConvert.SerializeObject(new
{
Username = _userName,
Password = _password,
secondFactor = secondFactor
});
httpRequest.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(httpRequest);
var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
TokenResult r = JsonConvert.DeserializeObject<TokenResult>(responseContent);
if (!string.IsNullOrWhiteSpace(r.token))
{
_token = r.token;
_tokenValidity = r.expirationDate;
_refreshToken = r.refreshToken;
_refreshTokenValidity = r.refreshTokenExpirationDate;
return _token;
}
else
{
throw new Exception($"Failed to get token from server.\r\n{responseContent}");
}
}
Now you use the _token in subsequent requests in the request header:
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
using HttpResponseMessage response = await client.GetAsync(new Uri(_baseUrl, relativePath));
if (response.IsSuccessStatusCode)
{
using var stream = await response.Content.ReadAsStreamAsync();
stream.Position = 0;
using var reader = new StreamReader(stream);
reader.ReadToEnd();
}
Please note, that usually the token has a certain lifetime after which it is basically useless. Some APIs offer a refresh token with which a new token can be requested without the user having to log in again with username and password, but that's beyond the scope of this question.
You said you have to use the token as cookie? Well there are APIs which work like this but personally I've never seen one like this, which is why I can't you help very much, but it shouldn't be much more than putting the token you got into a cookie with a certain name.
Hope this helps.
Not sure what you are asking. I have a controller code where I use web api call to authenticate user. You can use your own model to pass the data. If your web api expects token for request, then you might have to get the token first to give a call to any method. Hope this helps.
OktaUserDetailsModel Model = new OktaUserDetailsModel();
Model.username = model.UserName;
Model.password = model.Password;
using (var httpClient = new HttpClient())
{
HttpContent inputContent = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(Model), System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = httpClient.PostAsync(ConfigurationManager.AppSettings["OktaAPIuri"], inputContent).Result;
if (response.IsSuccessStatusCode)
{
string strResponse = (new JavaScriptSerializer()).Deserialize<string>(response.Content.ReadAsStringAsync().Result);
if (strResponse.ToUpper() == "TRUE")
return OktaSingleSignOnLogin(astrReturnUrl, model.UserName);
else
return ErrorPage();
}
else
{
return ErrorPage();
}
}

OpenID Connect Authentication Successful. Now what?

I'm writing a windows service in C# that needs to authenticate with an API and make some calls. I'm able to authenticate successfully with this API I'm talking to, but I can't seem to figure out how to use the response. The response looks like this:
{"access_token":"Es-Zjs_LI0tcXyLe3aEfgKPNLHN7CwyUhTss-cTld1A","expires_in":1800,"token_type":"Bearer","scope":"example","auth_state":1,"company":"examplecompany"}
I can get the access token out of that string if I want, but no matter how I pass it to a request, I get a 401 error. This is what my current iteration looks like:
string results = "";
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",token);
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://example.ca/endpoint"),
//Headers =
//{
// { "authorization", "Bearer"},
//},
};
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
results = body;
}
}
catch (Exception ex)
{
results = "ERROR: " + ex.Message;
}
return results;
Where "token" is the string "Es-Zjs_LI0tcXyLe3aEfgKPNLHN7CwyUhTss-cTld1A" in this example. I had previously tried stitching the access_token value as a string to the "Bearer" string in the commented out section in the middle there. What am I doing wrong? Do I need to make a JwtSecurityToken out of the response?
AuthenticationResult authResult = await daemonClient.AcquireTokenForClient(new[] { MSGraphScope })
.ExecuteAsync();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
I've used the authResult.AccessToken. Not sure if it works in your scenario. The return type in my case was Microsoft.Identity.Client.AuthenticationResult type when I retrieved the token for a Graph API that I was using.
Be aware that the token you have received ("Es-Zjs_LI0tcXyLe3aEfgKPNLHN7CwyUhTss-cTld1A") is a reference token and not a JWT-token. Make sure your API accepts that type of token.
To use the token effectively in production then I would consider using the various helper methods found in the IdentityModel library and especially the Worker application helpers.
While I understand it's largely situational depending on what API you're trying to connect to, for me the solution was to use this method to pass in the authentication token:
request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + token);

Why getting 401 when trying validating Token

I have a Bearer token and need to validate it against a api and validateToken endpoint. The endpoint aspects a json like that:
{
"jwtToken": "my token"
}
At the swagger I try successful this endpoint using url
http://10.212.226.31:5022/api/v1/validateToken
But I need to validate from code and there I get a 401 'Unauthorized'.
HttpClient client = new HttpClient
{
BaseAddress = new Uri("http://10.212.226.31:5022/")
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
string token = accessToken.Replace("Bearer ", "");
HttpResponseMessage response = await client.PostAsJsonAsync(
"api/v1/validateToken", token);
At the response object I get the 401.
What is wrong? Some thing about the json?
How to hand over the right stuff to the endpoint?
Additions:
I work remote on a virtual machine from a costumer and he does not allow installing software. Fiddler and co is not available.
I tried also this, but it's not working:
ValidateTokenRequest tokenJson = new ValidateTokenRequest
{
jwtToken = token
};
HttpResponseMessage response = await client.PostAsJsonAsync(
"api/v1/validateToken", tokenJson);
I needed to authenticate my self at the endpoint, to add the token to the header.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
Now it works. Thanks to everybody!

404 when accessing Design Automation API v3 through HttpClient

Running calls to the Design Automation API in Postman works just fine but when I try to make the same calls in C# using HttpClient they fail with a 404 that seems to actually hide an authentication error:
{
"developerMessage":"The requested resource does not exist.",
"userMessage":"",
"errorCode":"ERR-002",
"more info":"http://developer.api.autodesk.com/documentation/v1/errors/err-002"
}
That link leads to an authentication error:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>1F52E60A45AEF429</RequestId>
<HostId>
[ Some base64 ]
</HostId>
</Error>
I'm following examples for how to use HttpClient, but I may be missing something. I successfully get the access token, run
var client = new HttpClient
{
BaseAddress = new Uri("https://developer.api.autodesk.com/da/us-east")
};
client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue(TokenType, AccessToken);
then
var result = await client.GetAsync("/v3/forgeapps/me");
and the above json is the result's content. I use the same access token in Postman and it works.
I would wrap up the endpoint, headers, and httpmethod in the HttpRequestMessage. Then send it and assign it to HttpResponseMessage.
var client = new HttpClient
{
BaseAddress = new Uri("https://developer.api.autodesk.com/da/us-east/")
};
//throw the endpoint and HttpMethod here. Could also be HttpMethod.Post/Put/Delete (for your future reference)
var request = new HttpRequestMessage(HttpMethod.Get, "v3/forgeapps/me");
//also maybe try throwing the headers in with the request instead of the client
request.Headers.Add(TokenType, AccessToken);
// send the request, assign to response
HttpResponseMessage response = await client.SendAsync(request);
//then, we can grab the data through the Content
string result = await response.Content.ReadAsStringAsync();

Web API Call from a C# console application with credentials

I am trying to write a Web API site with a Get method that is Authorized. The site is a default template site, using Individual Accounts. So it stores the username and password in a database. I am attempting to call this Web API site and pass along a username and password in a console application via HttpClient. I have tried several ways of going about this. I think* i have CORS enabled on my API site. I keep getting Unauthorized results. Here is the HttpClient code I am running, I feel like it is completely valid, and I think something needs to be configured to handle this username and password on the API side, but I am completely unsure how to go about it if that is the case.
using (var client = new HttpClient())
{
var byteArray = Encoding.ASCII.GetBytes("sampleUser:Test123!");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
client.BaseAddress = new Uri("http://localhost:15198/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage response = await client.GetAsync("api/Query");
if (response.IsSuccessStatusCode)
{
thing = response.Content.ToString();
}
}
catch (HttpRequestException e)
{
var test = e.Message;
}
}
you would need to impersonate and pass the credentials assuming your running windows authentication on your server.
using (new Impersonator(UserName, Domain, Pwd))
{
...http request
}
See thread

Categories

Resources