Unauthorized Http Response - azure

I am using an Azure Authentication in my Xamarin.Form project, the token received is used for making API calls for authentication purpose.
After some time after the keeping the app in background, again I try to make the API calls it returns "unauthorised".
The token expiration time is set to 30 min. But unauthorised error is not consistent some time it happens as soon as keep the app in background and some time it works fine.
Has anyone faced the same issue.
public async Task<Response> AuthenticatedGet(string uri, string accessToken, string content = null)
{
Uri restUri = new Uri(uri, UriKind.RelativeOrAbsolute);
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(60);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, restUri.ToString());
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization",
string.Format("Bearer {0}", accessToken));
var result = await client.SendAsync(request);
//HttpClient client = new HttpClient();
//client.Timeout = TimeSpan.FromSeconds(60);
//var result = await client.SendAsync(request);
Response sr = new Response();
if (result.IsSuccessStatusCode)
{
string responseString = await result.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(responseString))
{
sr.ResponseData = responseString;
sr.IsSuccess = true;
sr.StatusCode = (int)result.StatusCode;
}
}
else if (result.StatusCode == HttpStatusCode.NotFound)
{
sr.ResponseData = $"Service not found at the specifed uri {uri}";
sr.IsSuccess = false;
sr.StatusCode = (int)result.StatusCode;
}
else
{
//var responseString = await result.Content.ReadAsStringAsync();
//JObject jObject = JObject.Parse(responseString);
//var messageProperty = jObject.Property("Message");
//if (messageProperty != null && result.StatusCode == HttpStatusCode.Unauthorized)
//{
// var message = messageProperty.Value?.ToString();
// sr.Message = !string.IsNullOrEmpty(message) ? message : result.ReasonPhrase;
// LogoutUnauthorisedUser?.Invoke(message);
// throw new UnauthorizedAccessException(message);
//}
//sr.Message = result.ReasonPhrase;
//sr.IsSuccess = false;
//sr.StatusCode = (int)result.StatusCode;
//TODO: Handle Unauthorized user
}
return sr;
}
public async Task<ObservableCollection<NIODetails>> GetABCServiceAsync()
{
var uri = string.Format(_hostConfiguration.ABCHostName + _hostConfiguration.ABC, Configuration.ABC);
var resonse = await _httpService.AuthenticatedGet(uri, Constant.ADToken, null);
if (resonse.IsSuccess)
{
var list = JsonConvert.DeserializeObject<ObservableCollection<ABCDetails>>(resonse.ResponseData);
return list;
}
else
{
return null;
}
}

Related

Titanium http request leak

I have to make a load of subsequent http requests to load product images into the app as it has to function in an offline mode.
Around 2000 calls.
The http client seems toi have a memory leak which causes the persistent mbytes in "instruments" to rise to around 200 without being garbaged.
After use of the http client it is being set to null.
I have tried setting the file property of the httpclient without any success
I have set the unload function to only call the callback function which in turn calls the http send function again (thus looping through the 2000 products to get the respective pictures)
I changed from SDK 7.5.0.v20180824022007 to SDK 8.1.0.v20190423134840 and even SDK 9.0.0.v20181031080737 but the problem remains
the code of my http common module:
function HttpClient(options = {}) {
this.root = options.root || "ROOT_OF_API";
this.endpoint = options.endpoint || false;
this.needsChecksum = options.needsChecksum || false;
this.data = {};
this.method = options.method || "Post";
this.timeout = options.timeout || 5000;
this.calculateChecksum = function () {
var moment = require('alloy/moment');
if (!Alloy.Models.user.authenticated()) {
return false;
}
var sp = (moment().unix() - Alloy.Models.meta.get("timeDiff"))
var hash = Ti.Utils.md5HexDigest("nX" + sp + "FossilSFAapp" + Alloy.Models.user.get('token').substring(10, 14) + "CS")
var checksum = sp + "-" + hash.substring(4, 8)
this.data.checksum = checksum
}
};
HttpClient.prototype.setData = function (data) {
this.data = data
};
HttpClient.prototype.send = function (callback) {
// set new checksum for request if is needed
if (this.needsChecksum) {
this.calculateChecksum()
}
// add app version
if (this.method === "POST") {
this.data.appversion = Ti.App.version;
}
// send
var client = Ti.Network.createHTTPClient({
onload: function () {
callback({
success: true
})
},
onerror: function(e) {
callback({
message: e.messgae,
success: false
})
},
timeout: this.timeout
});
client.open(this.method, this.root + this.endpoint);
if (this.setFile) {
client.file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, this.fileName);
}
client.setRequestHeader('Content-Type', 'application/json');
client.send(JSON.stringify(this.data));
client = null;
};
module.exports = HttpClient;
and then the module is used in the product model like so:
var HttpClient = require('./HttpClient');
var httpClient = new HttpClient();
function getImage (i) {
if (collection.at(i) && collection.at(i).get('iimage0') && collection.at(i).needsImageUpdate()) {
httpClient.endpoint = collection.at(i).get('acarticlenumber') +".jpg";
httpClient.fileName = 'productImages/' + collection.at(i).get('acarticlenumber') + '.jpg'
httpClient.send(function(e){
if (i < collection.length) {
i++
getImage(i)
} else {
finished()
}
});
} else {
if (i < collection.length) {
i++
getImage(i)
} else {
finished()
}
}
}
// start getting images at index 0
getImage(0)
anyone have an idea why these memory leaks appear ?
It only ever occurs when actually sending the http request.

Dialogflow Webhook Response c# gives error on invoke

I'm trying to create a webhook for Dialogflow in C# (on Azure). Everytime I see the same example but my DialogFlows keeps geting an error with this response"
Here's what I did:
Created a new ASP.Net Web Project (WebAPI)
installed NuGet Google.Cloud.DialogFlow V2 (v1.0.0.beta02)
updated System.Net.Http to 4.3.3
Created a new controller
[System.Web.Http.HttpPost]
public dynamic DialogAction([FromBody] WebhookRequest dialogflowRequest)
{
var intentName = dialogflowRequest.QueryResult.Intent.DisplayName;
var actualQuestion = dialogflowRequest.QueryResult.QueryText;
var testAnswer = $"Dialogflow Request for intent {intentName} and question {actualQuestion}";
var parameters = dialogflowRequest.QueryResult.Parameters;
var dialogflowResponse = new WebhookResponse
{
FulfillmentText = testAnswer,
FulfillmentMessages =
{ new Intent.Types.Message
{ SimpleResponses = new Intent.Types.Message.Types.SimpleResponses
{ SimpleResponses_ =
{ new Intent.Types.Message.Types.SimpleResponse
{
DisplayText = testAnswer,
TextToSpeech = testAnswer,
}
}
}
}
}
};
var jsonResponse = dialogflowResponse.ToString();
return new ContentResult
{
Content = jsonResponse,
ContentType = "application/json"
};
Published the app to Azure so there's a webhook URl.
Now, when I test it in dialogflow, the response is:
"Webhook call failed. Error: Failed to parse webhook JSON response: Cannot find field: Content in message google.cloud.dialogflow.v2.WebhookResponse."
Which I do not understand.....what am I missing here?
(here's the screenshot of the response:)
The solution to this problem is to return JsonResult instead of the ContentResult.
[System.Web.Http.HttpPost]
public JsonResult DialogAction([FromBody] WebhookRequest dialogflowRequest)
{
var intentName = dialogflowRequest.QueryResult.Intent.DisplayName;
var actualQuestion = dialogflowRequest.QueryResult.QueryText;
var testAnswer = $"Dialogflow Request for intent {intentName} and question {actualQuestion}";
var parameters = dialogflowRequest.QueryResult.Parameters;
var dialogflowResponse = new WebhookResponse
{
FulfillmentText = testAnswer,
FulfillmentMessages =
{ new Intent.Types.Message
{ SimpleResponses = new Intent.Types.Message.Types.SimpleResponses
{ SimpleResponses_ =
{ new Intent.Types.Message.Types.SimpleResponse
{
DisplayText = testAnswer,
TextToSpeech = testAnswer,
}
}
}
}
}
};
var jsonResponse = dialogflowResponse.ToString();
return Json(jsonResponse);

Node JS Soap to send a file to sharepoint based webserver using CopyIntoItems

I am writing a Node JS SOAP client using Node-Soap module to send a file to a remote SharePoint based Web Services.
The machine client requires a proxy to access Internet and the SharePoint WS requires an account (user, pwd). Below are the code source.
However, I always have the error "(node:20857) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Cannot parse response".
Someone can help me, please?
var process = require('process');
var fs = require('fs');
var request = require('request')
var soap = require('soap');
var apiWSDL = '.../test-collab/WS/_vti_bin/copy.asmx?wsdl';
function sendFile() {
var p = new Promise(function (resolve, reject) {
request_with_defaults = request.defaults({
'proxy': 'http://***:***#10.115.108.109:8080',
'timeout': 50000,
'connection': 'keep-alive'
});
var options = {
'request': request_with_defaults,
endpoint: 'https://.../test-collab/WS/_vti_bin/copy.asmx',
}
var byteArray = fs.readFileSync('test.txt').toString('base64');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
//process.env.https_proxy = 'http://***#***:10.115.108.109:8080';
soap.createClient(apiWSDL, options, function (err, client) {
if (err) throw new Error(err);
var args = {
DestinationUrls: 'https://.../test-collab/WS/CAS/test.txt',
Stream: byteArray
}
client.setSecurity(new soap.ClientSSLSecurity(null, null, null, { /*default request options like */
strictSSL: false,
rejectUnauthorized: false,
// hostname: 'some-hostname'
//secureOptions: constants.SSL_OP_NO_TLSv1_2,
forever: true,
}));
client.addHttpHeader('vm6_webapp', 'SERVICE');
client.addHttpHeader('vm6_password', '***');
client.addHttpHeader('vm6_user', '***');
client.CopyIntoItems(args, function (err, result) {
//console.log(err);
if (err) {
console.log(err);
reject(err);
}
var sets;
try {
console.log(result);
if (result.length) {
resolve(result);
} else {
reject(result);
}
} catch (error) {
console.log("error");
reject("error und")
}
});
});
});
return p;
}
As the error message is Cannot parse response, two possibilities can happen:
either the response is not in XML format
or the XML response is not acceptable by SOAP response message defined in wsdl.
Can you redo the SOAP request by using an existing client, such as, SoapUI to confirm?
Otherwise, I propose to use console.error( err.stack ) rather than console.log( err ) to get the full execution trace of err.
Thank Nghia for your reply.
In fact, I've written a SOAP client in Java for this WebServers before and it works. That means the paramters are ok as well as the XML response is ok.
Here are the code in Java:
MoccaClient clientWSMocca = new MoccaClient();
CopySoap copySoap = (CopySoap)clientWSMocca.getClient(site_soap_url,
proxy_host, proxy_port, proxy_user, proxy_password,
mocca_user, mocca_password, mocca_web_app,
CopySoap.class);
// Récupération sous forme de tableau de bytes du fichier
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
InputStream in = new BufferedInputStream(new FileInputStream(file_path));
BufferedOutputStream bufOut = new BufferedOutputStream(out);
for (int b = in.read(); b != -1; b = in.read()) {
bufOut.write(b);
}
in.close();
bufOut.close();
} catch (Exception e) {
e.printStackTrace();
}
// Initialisation des variables de contexte
FieldInformation fieldInformation = new FieldInformation();
String destinationUrl = site_url + file_name;
DestinationUrlCollection destinationUrlCollection = new DestinationUrlCollection();
destinationUrlCollection.getString().add(destinationUrl);
FieldInformationCollection fieldInformationCollection = new FieldInformationCollection();
fieldInformationCollection.getFieldInformation().add(fieldInformation);
Holder<CopyResultCollection> copyResult= new Holder<CopyResultCollection>();
Holder<Long> getItemResult = new Holder<Long>();
copySoap.copyIntoItems(file_path, destinationUrlCollection, fieldInformationCollection, out.toByteArray(), getItemResult, copyResult);
MoccaClient.java
public class MoccaClient {
public Object getClient(String url,
String proxyhost, int proxyport, String userproxy, String passwordproxy,
String moccauser, String moccapassword, String moccawebapp,
Class<?> serviceclass) {
System.setProperty("org.apache.cxf.JDKBugHacks.defaultUsesCaches", "true");
boolean bssl = false;
if (url.startsWith("https")) {
bssl = true;
}
if (url.startsWith("HTTPS")) {
bssl = true;
}
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.getInInterceptors().add(new MyInterceptor());
factory.setServiceClass(serviceclass);
factory.setAddress(url);
Object client = factory.create();
Client clientDuProxy = ClientProxy.getClient(client);
Map<String, List<String>> headers = new HashMap();
headers.put("vm6_user", Arrays.asList(moccauser));
headers.put("vm6_password", Arrays.asList(moccapassword));
headers.put("vm6_webapp", Arrays.asList(moccawebapp));
clientDuProxy.getRequestContext().put(Message.PROTOCOL_HEADERS, headers);
HTTPConduit http = (HTTPConduit)clientDuProxy.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
http.setClient(httpClientPolicy);
if (proxyhost != null) {
http.getClient().setProxyServer(proxyhost);
http.getClient().setProxyServerPort(proxyport);
}
if (userproxy != null) {
http.getProxyAuthorization().setUserName(userproxy);
http.getProxyAuthorization().setPassword(passwordproxy);
}
if (bssl) {
TrustManager[] trustCerts = new TrustManager[]{new AllTrust()};
TLSClientParameters tcp = new TLSClientParameters();
tcp.setTrustManagers(trustCerts);
tcp.setSecureSocketProtocol("TLS");
tcp.setDisableCNCheck(true);
http.setTlsClientParameters(tcp);
}
return client;
}
}

Azure Search using REST c#

I am trying to run the following code:
public class Item
{
[JsonProperty(PropertyName = "api-key")]
public string apikey { get; set; }
}
[[some method]]{
var url = "https://[search service name].search.windows.net/indexes/temp?api-version=2016-09-01";
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Put,url))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var sItem = new Item { apikey = [AzureSearchAdminKey] };
var tststring = JsonConvert.SerializeObject(sItem);
var body=new StringContent(tststring, Encoding.UTF8,"application/json" );
request.Content = body;
request.Method = HttpMethod.Put;
using (HttpResponseMessage response = httpClient.SendAsync(request).Result)
{
var stringr = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(stringr);
Console.ReadLine();
}
}
}
}
I get the following error:
"Error reading JObject from JsonReader. Path '', line 0, position 0."
Could someone from search team tell me what I did wrong?
The api key should be in the HTTP header, and the index definition should be in the HTTP body.
Here's some sample code for creating a data source, index, and indexer, which reads from an Azure SQL DB and indexes its rows.
class Program
{
static void Main(string[] args)
{
var searchServiceName = "[search service name]";
var apiKey = "[api key]";
var dataSourceName = "[data source name]";
var indexName = "[index name]";
var indexerName = "[indexer name]";
var azureSqlConnectionString = "[Azure SQL connection string]";
var azureSqlTableName = "[table name]";
using (var httpClient = new HttpClient())
{
var dataSourceDefinition = AzureSqlDatasourceDefinition(azureSqlConnectionString, azureSqlTableName);
var putDataSourceRequest = PutDataSourceRequest(searchServiceName, apiKey, dataSourceName, dataSourceDefinition);
Console.WriteLine($"Put data source {putDataSourceRequest.RequestUri}");
Console.WriteLine();
var putDataSourceResponse = httpClient.SendAsync(putDataSourceRequest).Result;
var putDataSourceResponseContent = putDataSourceResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine(putDataSourceResponseContent);
Console.WriteLine();
var indexDefinition = IndexDefinition();
var putIndexRequest = PutIndexRequest(searchServiceName, apiKey, indexName, indexDefinition);
Console.WriteLine($"Put index {putIndexRequest.RequestUri}");
Console.WriteLine();
var putIndexResponse = httpClient.SendAsync(putIndexRequest).Result;
var putIndexResponseContent = putIndexResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine(putIndexResponseContent);
Console.WriteLine();
var indexerDefinition = IndexerDefinition(dataSourceName, indexName);
var putIndexerRequest = PutIndexerRequest(searchServiceName, apiKey, indexerName, indexerDefinition);
Console.WriteLine($"Put indexer {putIndexerRequest.RequestUri}");
Console.WriteLine();
var putIndexerResponse = httpClient.SendAsync(putIndexerRequest).Result;
var putIndexerResponseContent = putIndexerResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine(putIndexerResponseContent);
Console.WriteLine();
var runIndexerRequest = RunIndexerRequest(searchServiceName, apiKey, indexerName);
Console.WriteLine($"Run indexer {runIndexerRequest.RequestUri}");
Console.WriteLine();
var runIndexerResponse = httpClient.SendAsync(runIndexerRequest).Result;
Console.WriteLine($"Success: {runIndexerResponse.IsSuccessStatusCode}");
Console.ReadLine();
}
}
static HttpRequestMessage PutDataSourceRequest(string searchServiceName, string apiKey, string dataSourceName,
string datasourceDefinition)
{
var request = new HttpRequestMessage(HttpMethod.Put,
$"https://{searchServiceName}.search.windows.net/datasources/{dataSourceName}?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
var body = new StringContent(datasourceDefinition, Encoding.UTF8, "application/json");
request.Content = body;
return request;
}
static HttpRequestMessage PutIndexRequest(string searchServiceName, string apiKey, string indexName,
string indexDefinition)
{
var request = new HttpRequestMessage(HttpMethod.Put,
$"https://{searchServiceName}.search.windows.net/indexes/{indexName}?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
var body = new StringContent(indexDefinition, Encoding.UTF8, "application/json");
request.Content = body;
return request;
}
static HttpRequestMessage PutIndexerRequest(string searchServiceName, string apiKey, string indexerName,
string indexerDefinition)
{
var request = new HttpRequestMessage(HttpMethod.Put,
$"https://{searchServiceName}.search.windows.net/indexers/{indexerName}?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
var body = new StringContent(indexerDefinition, Encoding.UTF8, "application/json");
request.Content = body;
return request;
}
static HttpRequestMessage RunIndexerRequest(string searchServiceName, string apiKey, string indexerName)
{
var request = new HttpRequestMessage(HttpMethod.Post,
$"https://{searchServiceName}.search.windows.net/indexers/{indexerName}/run?api-version=2016-09-01");
request.Headers.Add("api-key", apiKey);
return request;
}
static string AzureSqlDatasourceDefinition(string connectionString, string tableName)
{
return #"
{
""description"": ""azure sql datasource"",
""type"": ""azuresql"",
""credentials"": { ""connectionString"": """ + connectionString + #""" },
""container"": { ""name"": """ + tableName + #""" },
""dataChangeDetectionPolicy"": {
""#odata.type"": ""#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy"",
""highWaterMarkColumnName"": ""highwatermark""
},
""dataDeletionDetectionPolicy"": {
""#odata.type"": ""#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy"",
""softDeleteColumnName"": ""deleted"",
""softDeleteMarkerValue"": ""true""
}
}
";
}
static string IndexDefinition()
{
return #"
{
""fields"": [
{
""name"": ""id"",
""type"": ""Edm.String"",
""key"": true,
""searchable"": true,
""sortable"": true,
""retrievable"": true
},
{
""name"": ""field1"",
""type"": ""Edm.String"",
""searchable"": true,
""retrievable"": true
},
{
""name"": ""field3"",
""type"": ""Edm.Int32"",
""retrievable"": true
}
]
}
";
}
static string IndexerDefinition(string dataSourceName, string indexName)
{
return #"
{
""description"": ""indexer for azure sql datasource"",
""dataSourceName"": """ + dataSourceName + #""",
""targetIndexName"": """ + indexName + #""",
""schedule"": { ""interval"": ""P1D"" }
}
";
}
}
The indexer is scheduled to run once per day. You can set it to run more frequently if the data changes often, but it might affect your search throughput.
This is the table definition if you're interested
CREATE TABLE [dbo].[testtable](
[id] [int] IDENTITY(1,1) NOT NULL,
[field1] [nchar](10) NULL,
[field2] [nchar](10) NULL,
[field3] [int] NULL,
[highwatermark] [timestamp] NOT NULL,
[deleted] [bit] NOT NULL
) ON [PRIMARY]
INSERT INTO [dbo].[testtable] (field1, field2, field3, deleted) VALUES ('abc', 'def', 123, 0)
It looks like you're trying to modify your index definition, but the body of the request contains the api-key instead of the JSON for the index definition. The api-key needs to be in the request headers, not the body.
You might find it simpler to use the Azure Search .NET SDK instead of calling the REST API directly.

How to wait a request response and return the value?

When I use a request module in node.js server, I have some problem such as wait and return.
I would like to receive a "responseObject" value at requestController.
To solve this problem, I have search the best way but I still do not find it.
How can solve this problem?
Thank in advance!! :)
=========================================================================
var requestToServer = require('request');
function getRequest(requestObject) {
var urlInformation = requestObject['urlInformation'];
var headerInformation = requestObject['headerInformation'];
var jsonObject = new Object( );
// Creating the dynamic body set
for(var i = 0; i < headerInformation.length; i++)
jsonObject[headerInformation[i]['headerName']] = headerInformation[i]['headerValue'];
requestToServer({
url : urlInformation,
method : 'GET',
headers : jsonObject
}, function(error, response ,body) {
// todo response controlling
var responseObject = response.headers;
responseObject.body = body;
});
}
// Controlling the submitted request
exports.requestController = function(requestObject) {
var method = requestObject['methodInformation'];
var resultObject = null;
// Selecting the method
if(method == "GET")
resultObject = getRequest(requestObject);
else if(method =="POST")
resultObject = postRequest(requestObject);
else if(method == "PUT")
resultObject = putRequest(requestObject);
else if(method == "DELETE")
resultObject = deleteRequest(requestObject);
console.log(JSON.stringify(resultObject));
}
You can use callbacks in the following way.
function getRequest(requestObject, callback) {
// some code
requestToServer({
url : urlInformation,
method : 'GET',
headers : jsonObject
}, function(error, response ,body) {
// todo response controlling
var responseObject = response.headers;
responseObject.body = body;
callback(responseObject);
});
}
And
// Controlling the submitted request
exports.requestController = function(requestObject) {
var method = requestObject['methodInformation'];
// Selecting the method
if(method == "GET")
getRequest(requestObject, function(resultObject){
console.log(JSON.stringify(resultObject));
});
//some code
}
Hope, it helps.

Resources