I'm trying to read all accounts my user is associated with. The Documentation claims that this should be possible by calling:
GET https://app.vssps.visualstudio.com/_apis/accounts?api-version=5.1
Because the docs are kind of confusing it could be that I have to call
GET https://app.vssps.visualstudio.com/_apis/accounts?ownerId={GUID}&api-version=5.1
instead.
I'm using OAuth-Authentication. In order to get it work I created an ASP.NET Core application. I created an app registration in DevOps and I retrieve an OAuth token with the following scopes without any problem:
vso.auditlog
vso.connected_server
vso.dashboards
vso.entitlements
vso.environment_manage
vso.graph
vso.identity
vso.loadtest
vso.machinegroup_manage
vso.memberentitlementmanagement
vso.profile
vso.project
vso.securefiles_read
vso.security_manage
vso.taskgroups_read
vso.tokenadministration
vso.tokens
vso.variablegroups_read
vso.wiki
According to the docs only vso.profile should be necessary for this request.
However the result I receive is always:
HttpRequestException: Response status code does not indicate success: 401 (TF400813: The user '{AZURE_TENANT_ID}\{MY_MAIL_ADDRESS}' is not authorized to access this resource.).
Other requests are working just fine e.g.:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.1
The accounts-request is special because it can be sent without setting the context to a specific organisation or project. I guess this the reason for the different results.
EDIT
After trying ot today using the both URLs mentioned above I now get 400 as the response status code. This is a sample Bearer-Token I got after I decoded it:
{
"nameid": "1340eb0b-cabf-476c-a950-a070c34ca367",
"scp": "vso.profile",
"aui": "a2d8bdf0-9406-415a-aa79-bee9e2600c37",
"appid": "e1bea2a2-****-****-****-************",
"iss": "app.vstoken.visualstudio.com",
"aud": "app.vstoken.visualstudio.com",
"nbf": 1587395030,
"exp": 1587398630
}
Here is some simplified C# code I use:
HttpClient client = _clientFactory.CreateClient("DevOps");
var token = await _authHelper.GetTokenAsync(tokenType);
client.DefaultRequestHeaders.Add("Authorization", $"Bearer { token.AccessToken}");
var uri = "https://app.vssps.visualstudio.com/_apis/accounts?api-version = 5.1";
try
{
var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
// ex.Message = Response status code does not indicate success: 400 (Bad Request).
// ...
throw;
}
Related
I have implemented webhook for revenuecat in .net core C#. But for some reason I am getting 400 badrequest with empty response. I am mostly sure that I am not getting the json response in webook through revenuecat for any of the event occurring.
I have also added endpoint on revenue cat webhook with authentication. I have tried several time and as I have not way to test this on local machine. I need help from revenue cat team to provide some reference doc with sample implementation just to get proper json response. Below is the code snippet that I am using to get json response from the webhook endpoint added in revenuecat.
var webHookSecret = _configuration[Constants.RevenueCatWebHookSecret]; var headerAuthorization = HttpContext.Request.Headers["Authorization"].ToString(); #region Check authorization if (webHookSecret == headerAuthorization) { json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync(); } else { _logger.Information($"Un-Authorized token access in revenuecat webhook. Returning BadRequest response."); throw new APIException(HttpStatusCode.Unauthorized, new APIError(_configuration, "InternalServerError")); }
I am using the Xero Api with Nodejs and the xero-node library.
I have completed the oAuth flow and saved the token to the database. The issue i am now having is continually getting a 403 forbidden error when attempting to get anything from Xero be that Contacts, Accounts or Users. Sample code is below
I can get tenants ok without an issue however anything else doesn't work. I have checked the scopes to make sure when I am setting up the client they are correct which they are.
var getStuff = async(tokenSet) => {
await xero.setTokenSet(tokenSet);
const tenants = await xero.updateTenants();
const xeroTenantId = tenants[0].id // {String} Xero identifier for Tenant
const ifModifiedSince = new Date("2020-02-06T12:17:43.202-08:00");
const where = 'IsSubscriber==true'; // {String} Filter by an any element
const order = 'LastName ASC'; // {String} Order by an any element
console.log(tenants);
try {
const response = await xero.accountingApi.getUsers(xeroTenantId, ifModifiedSince, where, order);
console.log(response.body || response.response.statusCode)
}
catch (err) {
/// console.log(err);
console.log(`There was an ERROR! \n Status Code: ${err.response.statusCode}.`);
console.log(`ERROR: \n ${JSON.stringify(err.response.body, null, 2)}`);
}
}
Which scopes have been added to the access token you are passing through? You can decode your token here https://jwt.io/
Also - you need to pass the ‘tenant.tenantId’ to the function. I believe the tenant.id actually relates to the connection id which is coming back from the /connections endpoint.
My hunch is that is the issue. Also curious how that’s working, as updateTenants() should have the empty function call on the end. Is that working for you?
I got an api keys for Azure Cognitive services, but I can't find any documentation how I am calling this service through postmen. Anybody has experience with this?
Seems you are trying to call Text To Speech service with your keys. There are two steps for that.
1. Need Access Token
You have to get your token like this format:
Request URL: https://YourResourceEndpoint/sts/v1.0/issuetoken
Method: POST
Hearder: Content-Type:application/x-www-form-urlencoded
Ocp-Apim-Subscription-Key:YourKeys
See The Screen shot for clarity:
Code Snippet:
public async Task<string> GetSpeechServiceToken()
{
try
{
string tokenUrl = $"https://YourServiceURL.cognitiveservices.azure.com/sts/v1.0/issuetoken";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
tokenRequest.Headers.Add("Ocp-Apim-Subscription-Key", "subscriptionKey");
using (var client = new HttpClient())
{
var tokenResponse = await client.SendAsync(tokenRequest);
var token = await tokenResponse.Content.ReadAsStringAsync();
return token;
}
}
catch (Exception ex)
{
ex.Message.ToString();
}
return null;
}
You could have a look on official Docs
2. Get List Of Voices With Token You Have Received Earlier
You can request for Text To Speech voice list Like below:
Request URL: https://centralus.tts.speech.microsoft.com/cognitiveservices/voices/list
Method : GET
Authorization: Bearer Token Paste Your Token Here
See the screen shot for clarity
You could find more details here
Note: In case of your test account You can create here
Update:
I would sent a request and somehow I got an uri or something where I can hear it? is this possible?
Yeah its possible. But in that case you have to use sdk. Here Is the complete sample.
Visual Studio 2019, .NET 3.0 preview, Created a blazor application. Trying to get weather data from https://api.weather.gov/gridpoints/ALY/59,14/forecast.
I am using HttpClient in C#. This is getting forbidden (403) response
Tried to add CORS policty
private async Task<IWeatherDotGovForecast> RetrieveForecast()
{
string url = #"https://api.weather.gov/gridpoints/ALY/59,14/forecast";
var response = await _httpClient.GetAsync(url);
if (response != null)
{
var jsonString = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<WeatherDotGovForecast>(jsonString);
}
//return await _httpClient.GetJsonAsync<WeatherDotGovForecast>
// ("https://api.weather.gov/gridpoints/ALY/59,14/forecast");
return null;
}
I expected JSON data from https://api.weather.gov/gridpoints/ALY/59,14/forecast
Instead, I am getting Forbidden (403) status code
Your problem is not related to Blazor but weather.gov requires a User-Agent header in any HTTP request.
Applications accessing resources on weather.gov now need to provide a User-Agent header in any HTTP request. Requests without a user agent are automatically blocked. We have implemented this usage policy due to a small number of clients utilizing resources far in excess of what most would consider reasonable.
Use something like this:
var _httpClient = new HttpClient();
string url = #"https://api.weather.gov/gridpoints/ALY/59,14/forecast";
_httpClient.DefaultRequestHeaders.Add("User-Agent", "posterlagerkarte");
var response = await _httpClient.GetAsync(url);
I've a ton of SO post about this error, but I checked everything and still don't find why Azure Blob Storage keep failing authenticate my upload request.
I use Fine-Uploader to generate the request :
var uploaderInstance = $('#baz-fine-uploader').fineUploaderAzure({
template: 'qq-template-manual-trigger',
debug: true,
request: {
containerUrl: 'https://{MYACCOUNT}.blob.core.windows.net/client1',
endpoint: 'https://{MYACCOUNT}.blob.core.windows.net/client1'
},
// for Azure
signature: {
endpoint: "/api/upload/sas"
},
uploadSuccess: {
endpoint: "/api/upload/success"
},
cors: {
//all requests are expected to be cross-domain requests
expected:true
}
});
I generate the SAS URI with the Azure SDK, following what is recommended by Fine-uploader :
public string GetBlobSAS(string bloburi, string method)
{
try
{
var credentials = new StorageCredentials(STORAGE_ACCOUNT_NAME, STORAGE_ACCOUNT_KEY);
CloudBlockBlob blob = new CloudBlockBlob(new Uri(bloburi), credentials);
var sas = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Create,
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15)
});
return string.Format(CultureInfo.InvariantCulture, "{0}{1}", bloburi, sas);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
throw ex;
}
}
I created a CORS access policy through the Azure portal, and for test purpose, I set "everything" allowed, especially the "Allowed-Origin" field to "*", as I'm testing from my locahost :
Finally, Fine-uploader ask me for the SAS, fetch it and BOUM, the server answers :
OPTIONS https://{MYACCOUNT}.blob.core.windows.net/client1/5f89f3ae-2d10-4e4e-8f3f-25d…QAY40QjKGoJcDsHolt8KXjB86chaTWg0f4t4%3D&se=2016-12-20T14%3A34%3A58Z&sp=rcw 403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)
XMLHttpRequest cannot load https://{MYACCOUNT}.blob.core.windows.net/client1/5f89f3ae-2d10-4e4e-8f3f-25d…QAY40QjKGoJcDsHolt8KXjB86chaTWg0f4t4%3D&se=2016-12-20T14%3A34%3A58Z&sp=rcw. Response for preflight has invalid HTTP status code 403
The server response is
<Error>
<Code>AuthenticationFailed</Code>
<Message>
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:71041c4f-0001-00cf-69cc-5aa7de000000 Time:2016-12-20T14:21:35.7541369Z
</Message>
<AuthenticationErrorDetail>
Signature did not match. String to sign used was rcw 2016-12-20T14:34:58Z /blob/{MYACCOUNT}/client1/5f89f3ae-2d10-4e4e-8f3f-25d7b4760965.PNG 2015-12-11
</AuthenticationErrorDetail>
</Error>
Really don't know what else I can do now..
According to whatever SO post, I also tried to add a "&comp=list&restype=container" at the end of my SAS URI, tried several combinations with that, none of them worked...
Any ideas??