I'm getting error 401 (unauthorized) while trying to make a GET request from my API that has a JWT token - api

Here is my GETRequest method...
HttpClient client = new HttpClient();
var dashboardEndpoint = Helper.GetUsersurl;
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Authorization", "Bearer"+Helper.userprofile.token);
var result = await client.GetStringAsync(dashboardEndpoint);
var UsersList = JsonConvert.DeserializeObject<AddedUsers>(result);
//Users = new ObservableCollection<AddedUsers>(UsersList);
Emplist.ItemsSource = UsersList.data;
}
I've tried different method but the token isn't being sent alongside my request and therefore the API is throwing an error 401 at me. Any help will be gladly appreciated please...

So, i later studied the pattern and also the response on postman then i realize I'm supposed to pass only the key and the value. In this context,
HttpClient client = new HttpClient();
var dashboardEndpoint = Helper.GetUsersurl;
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Authorization", Helper.userprofile.token);
var result = await client.GetStringAsync(dashboardEndpoint);
var UsersList = JsonConvert.DeserializeObject<AddedUsers>(result);
//Users = new ObservableCollection<AddedUsers>(UsersList);
Emplist.ItemsSource = UsersList.data;
I only needed to pass Authorization as the key and token as the value. thanks everyone

As #jason said, try to add a space between Bearer and the Token
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Helper.userprofile.token);

Related

'Restclient' does not contain a 'BaseUrl' Error

I am working on Asp.net core project. trying to send mail using mailgun. used mailgun C# code given in https://documentation.mailgun.com/en/latest/user_manual.html#sending-via-api
But getting an error "RestClient" does not contain a "BaseUrl" error.
I saw your Comment Code, I think You have to Change this to get the Output.
var client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v3";
client.Authenticator = new HttpBasicAuthenticator("api", "YOUR_API_KEY");
var request = new RestRequest();
request.Resource = "/address/validate";
request.AddParameter("address", "address#domain.com");
//Change Resource and AddParameter as per need
var response = client.Execute(request);
dynamic content = Json.Decode(response.Content);
var client = new RestClient(new Uri("yourbaseurl"));

.net core 2.2 httpclient Factory not giving Full data as response

I am using .net core 2.2 for my flight listing application and i am using wego api for that. but while i am using the below code for getting flights from wego api i am not getting the complete response, but in postman i am getting full result set at one request.
public async Task<SearchResultMv> GetFlights(FlightParam flightParam, AuthResult auth)
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://srv.wego.com/metasearch/flights/searches/" + flightParam.SearchId + "/results?offset=0&locale=" + flightParam.locale + "&currencyCode=" + flightParam.currencyCode);
request.Headers.Add("Bearer", auth.access_token);
request.Headers.Add("Accept", "application/json");
var client = _httpClient.CreateClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", auth.access_token);
var response = await client.SendAsync(request).ConfigureAwait(false);
SearchResultMv json = new SearchResultMv();
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsAsync<SearchResultMv>().ConfigureAwait(false);
return json;
}
}
Some time I am not getting any result set by the above code. Wego api is not providing any pagination or filtration on this api. so Please help me to achieve this. Thanks for advance.
According the their documentation you need to poll their API to get the results gradually. You also need to increment the offset as the results are returned.
For example, if the first set of results gives you 100 results, the following request should have the offset value set as 100. offset=100.
Documentation:
https://developers.wego.com/affiliates/guides/flights
Edit - Added sample solution
Sample code that polls the API every second until reaching the desired number of results. This code hasn't been tested so you'll need to adjust it to your needs.
const int numberOfResultsToGet = 100;
var results = new List<SearchResultMv>();
while (results.Count < numberOfResultsToGet)
{
var response = await GetFlights(flightParam, auth);
results.AddRange(response.Results);
// update offset
flightParam.Offset += response.Results.Count;
// sleep for 1 second before sending another request
Thread.Sleep(TimeSpan.FromSeconds(1));
}
Change your request to use a dynamic Offset value. You can add the Offset property to the FlightParam class.
var request = new HttpRequestMessage(
HttpMethod.Get,
$"https://srv.wego.com/metasearch/flights/searches/{flightParam.SearchId}/results?" +
$"offset={flightParam.Offset}" +
$"&locale={flightParam.locale}" +
$"&currencyCode={flightParam.currencyCode}");

How to get microsoft account profile photo after login with application in mvc

With the help of claimprincipal, I'm able to get the details of signedin user as below but its not giving any pic related information as google does:
https://apis.live.net/v5.0/{USER_ID}/picture?type=large
which says The URL contains the path '{user_id}', which isn't supported.
Even tried
https://graph.microsoft.com/v1.0/me/photo/$value
which is asking for access token, but I am not sure what have to be passed
string userName = ClaimsPrincipal.Current.FindFirst("name").Value;
string userEmail = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
Wanted an image which was added in any outlook account
For Image to show.. We have to use beared token and have to convert the image into memory stream and then have to used it.. I have done it in below ways. Hope this help ...
var client = new RestClient("https://login.microsoftonline.com/common/oauth2/token");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", $"code={code}&client_id={OutClientId}&client_secret={SecretKey}&redirect_uri={OutRedirectUrl}&grant_type=authorization_code", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Token jsonContent = JsonConvert.DeserializeObject<Token>(response.Content);
var Token = jsonContent.AccessToken;
var TokenType = jsonContent.TokenType;
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token);
HttpResponseMessage response1 = await httpClient.GetAsync("https://graph.microsoft.com/v1.0/me/photos/96x96/$value");
if (response1.StatusCode == HttpStatusCode.OK)
{
using (Stream responseStream = await response1.Content.ReadAsStreamAsync())
{
MemoryStream ms = new MemoryStream();
responseStream.CopyTo(ms);
byte[] buffer = ms.ToArray();
string result = Convert.ToBase64String(buffer);
HttpContext.Session[AppConstants.UserImage] = String.Format("data:image/gif;base64,{0}", result);
responseStream.Close();
}
}
Is there any reason you are using the live.net apis? Instead of the Microsoft Graph APIs? Microsoft Graph APIs are the future for all user data within Microsoft 365 consumer and commercial accounts.
You can get the Users photo very easily as described here https://learn.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0
GET /me/photo/$value
As you are using ASP.NET MVC, there is an SDK you can use that makes this very easy too.
https://learn.microsoft.com/en-us/graph/sdks/sdks-overview?context=graph%2Fapi%2F1.0&view=graph-rest-1.0

OneDrive Service don't get a refresh token

I use Xamarin.Auth to authenticate with the OneDrive Service. This worked fine for a while now, but I seems there where changes on the service so it stopped working..
I upgraded to the new version 2.0 and try to make it work again. The Initial authentication works well so far. But after a while it always started to crash. I realized that there isn't any refrehs token sent back from the onedrive service.
This is the code to call the Auth UI:
private Task<IDictionary<string, string>> ShowWebView()
{
var tcs = new TaskCompletionSource<IDictionary<string, string>>();
var auth = new OAuth2Authenticator(ServiceConstants.MSA_CLIENT_ID,
string.Join(",", ServiceConstants.Scopes),
new Uri(GetAuthorizeUrl()),
new Uri(ServiceConstants.RETURN_URL));
auth.Completed +=
(sender, eventArgs) =>
{
tcs.SetResult(eventArgs.IsAuthenticated ? eventArgs.Account.Properties : null);
};
var intent = auth.GetUI(Application.Context);
intent.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(intent);
return tcs.Task;
}
private string GetAuthorizeUrl()
{
var requestUriStringBuilder = new StringBuilder();
requestUriStringBuilder.Append(ServiceConstants.AUTHENTICATION_URL);
requestUriStringBuilder.AppendFormat("?{0}={1}", ServiceConstants.REDIRECT_URI,
ServiceConstants.RETURN_URL);
requestUriStringBuilder.AppendFormat("&{0}={1}", ServiceConstants.CLIENT_ID,
ServiceConstants.MSA_CLIENT_ID);
requestUriStringBuilder.AppendFormat("&{0}={1}", ServiceConstants.SCOPE,
WebUtility.UrlEncode(string.Join(" ", ServiceConstants.Scopes)));
requestUriStringBuilder.AppendFormat("&{0}={1}", ServiceConstants.RESPONSE_TYPE, ServiceConstants.CODE);
return requestUriStringBuilder.ToString();
}
The Authorize URI is:
https://login.live.com/oauth20_authorize.srf?redirect_uri=https://login.live.com/oauth20_desktop.srf&client_id=["id"]&scope=onedrive.readwrite+wl.offline_access+wl.signin&response_type=code
The response I get contains 6 Elements:
access_token: "EwAIA..."
token_type: "bearer"
expires_in: "3600"
scope: "onedrive.readwrite wl.offline_access wl.signin wl.basic wl.skydrive wl.skydrive_update onedrive.readonly"
user_id: "41...."
state: "ykjfmttehzjebqtp"
When I check it with the Documentation (https://dev.onedrive.com/auth/msa_oauth.htm) I can't see what's wrong here. Any ideas?
I called wrong constructor. This one works:
authenticator = new OAuth2Authenticator(ServiceConstants.MSA_CLIENT_ID,
ServiceConstants.MSA_CLIENT_SECRET,
string.Join(",", ServiceConstants.Scopes),
new Uri(ServiceConstants.AUTHENTICATION_URL),
new Uri(ServiceConstants.RETURN_URL),
new Uri(ServiceConstants.TOKEN_URL));
With these constants:
Scopes = {"onedrive.readwrite", "wl.offline_access", "wl.signin"};
RETURN_URL = "https://login.live.com/oauth20_desktop.srf";
AUTHENTICATION_URL = "https://login.live.com/oauth20_authorize.srf";
TOKEN_URL = "https://login.live.com/oauth20_token.srf";

Get string returned from a PostAsync event

I'm using HttpClient like this in my console app:
using (var http = new HttpClient(handler))
{
http.BaseAddress = new Uri("http://127.0.0.1:34323/");
var response = await http.PostAsync("/api/generate", new StringContent(
JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"));
Console.WriteLine(response.Content.ToString());
}
In debug mode, I can see that the controller is returning a string of JSON.
However, I only get this written to the console:
System.Net.Http.StreamContent
How can I get it to write the actual JSON that's being returned?
Thanks!
Try below line:
Console.WriteLine(response.Content.ReadAsStringAsync().Result.ToString());