D2C message using IoT Hub - azure

I’d like to ask you a favor. I do have a problem confirming previously readed D2C message using IoT Hub. I am using REST API to pick up message like (I have replace SIG)
Request:
GET https://iot-hub-pospa.azure-devices.net/devices/18596c88-01e6-3f16-427b-10028d7305c5/messages/devicebound?api-version=2015-08-15-preview HTTP/1.1
IoTHub-MessageLockTimeout: 3600
Accept: application/json
Authorization: SharedAccessSignature sr=iot-hub-pospa.azure-devices.net&sig={sig}&se=1485558838&skn=iothubowner
Host: iot-hub-pospa.azure-devices.net
If-None-Match: "1c5006a4-2288-4a2f-b7ea-dcdf9b5bbc99"
Connection: Close
X-P2P-PeerDist: Version=1.1
X-P2P-PeerDistEx: MinContentInformation=1.0, MaxContentInformation=2.0
Accept-Encoding: peerdist
Response:
HTTP/1.1 200 OK
Content-Length: 35
ETag: "dfc78580-d251-4156-a5f6-c2a30811a504"
Server: Microsoft-HTTPAPI/2.0
iothub-messageid: 02cdb012-9749-48a9-bfb3-5812a4740675
iothub-to: /devices/18596c88-01e6-3f16-427b-10028d7305c5/messages/deviceBound
iothub-expiry:
iothub-correlationid:
iothub-ack: full
iothub-sequencenumber: 56
iothub-enqueuedtime: 2/2/2016 9:57:34 AM
iothub-deliverycount: 0
Date: Tue, 02 Feb 2016 10:21:43 GMT
Connection: close
2/2/2016 10:57:34 AM - Test message
Then when confirming I am getting HTTP 412 like
Request:
DELETE https://iot-hub-pospa.azure-devices.net/devices/18596c88-01e6-3f16-427b-10028d7305c5/messages/devicebound/02cdb012-9749-48a9-bfb3-5812a4740675?api-version=2015-08-15-preview HTTP/1.1
Accept: application/json
If-Match: "02cdb012-9749-48a9-bfb3-5812a4740675"
Authorization: SharedAccessSignature sr=iot-hub-pospa.azure-devices.net&sig={sig}&se=1485558838&skn=iothubowner
Host: iot-hub-pospa.azure-devices.net
Content-Length: 0
Connection: Close
Response:
HTTP/1.1 412 Precondition Failed
Content-Length: 330
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
iothub-errorcode: DeviceMessageLockLost
Date: Tue, 02 Feb 2016 10:21:49 GMT
Connection: close
 
{"Message":"ErrorCode:DeviceMessageLockLost;Message 02cdb012-9749-48a9-bfb3-5812a4740675 lock was lost for Device 18596c88-01e6-3f16-427b-10028d7305c5\r\nTracking Id:05994074a3664933a0910b5fc70e04e5-G:GatewayWorkerRole.6-B:1-P:cffe397b-f627-4435-bd54-48f5ba79c3ca-TimeStamp:02/02/2016 10:21:49\r\nErrorCode:DeviceMessageLockLost"}
 
 
Does anybody know what should I do to successfully confirm/delete message from IoT Hub, please? Thanks

static DeviceClient _deviceClient;
_deviceClient = DeviceClient.CreateFromConnectionString(<IoTHubURI>, TransportType.Http1);
public void SendMessage(IDictionary<string, object> dictionary)
{
Microsoft.Azure.Devices.Client.Message message = new Microsoft.Azure.Devices.Client.Message();
try
{
foreach (var r in dictionary)
{
message.Properties[r.Key] = r.Value.ToString();
}
_deviceClient.SendEventAsync(message);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}

Related

iothub-errorcode: InvalidProtocolVersion

Using the azure-iot-device sdk for node works in a standalone node program. When trying to use the same node code in a React web app, the connection to the IoT Hub fails "iothub-errorcode: InvalidProtocolVersion" with this error:
stream.js:61 WebSocket connection to 'wss://my-iothub.azure-devices.net/' failed: Error during WebSocket handshake: Unexpected response code: 400
App.js
var Protocol = require('azure-iot-device-mqtt').Mqtt;
var Client = require('azure-iot-device').Client;
var connectionString = "HostName=my-iothub.azure-devices.net;DeviceId=<redacted>;SharedAccessKey=<redacted>=";
var client = Client.fromConnectionString(connectionString, Protocol);
var connectCallback = function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
}
...
};
client.open(connectCallback);
Headers (From Chrome dev tools)
Request URL: wss://my-iothub.azure-devices.net/
Request Method: GET
Status Code: 400 Bad Request
Content-Length: 158
Content-Type: application/json; charset=utf-8
Date: Wed, 02 Oct 2019 21:18:10 GMT
iothub-errorcode: InvalidProtocolVersion
Server: Microsoft-HTTPAPI/2.0
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: Upgrade
Host: my-iothub.azure-devices.net
Origin: http://localhost:3000
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: <redacted>
Sec-WebSocket-Protocol: mqtt
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0)
Possibly related to: https://github.com/Azure/azure-sdk-for-js/issues/3473#issuecomment-499719031
I am assuming you are trying to utilise IOT hub from your react web app which is deployed in Microsoft Azure , if this is the case, please try the following:
what you need to check is the web app settings:
Set the consumer group as mentioned in this link.
Enable WebSocket.
Additional reference , please check the code repo and documentation around IOT HUB usage in web app, which is mentioned below:
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-live-data-visualization-in-web-apps
https://github.com/Azure/azure-iot-sdk-node/blob/master/device/ts-samples/sample_device.ts

Getting the API Key from ServiceStack request

Have a simple get Customer api that's returning list of customers fine.
Setting up for service to service authentication, if I make this [Authenticated] and try to implement using ApiKeyAuthProvider, the req.GetApiKey returns null and I get an error;
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST https://localhost:44347/api/customers application/json 0
Microsoft.AspNetCore.Hosting.Internal.WebHost:2019-07-01 16:50:34,004 [16] INFO Microsoft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 POST https://localhost:44347/api/customers application/json 0
The thread 0x42cc has exited with code 0 (0x0).
The thread 0x302c has exited with code 0 (0x0).
ServiceStack.ServiceStackHost:2019-07-01 17:01:14,601 [16] ERROR ServiceStack.ServiceStackHost - ServiceBase<TRequest>::Service Exception
System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at ServiceStack.Host.HttpRequestAuthentication.GetBasicAuth(IRequest httpReq) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Host\HttpRequestAuthentication.cs:line 45
at ServiceStack.Host.HttpRequestAuthentication.GetBasicAuthUserAndPassword(IRequest httpReq) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Host\HttpRequestAuthentication.cs:line 50
at ServiceStack.Auth.ApiKeyAuthProvider.PreAuthenticate(IRequest req, IResponse res) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Auth\ApiKeyAuthProvider.cs:line 232
at ServiceStack.AuthenticateAttribute.PreAuthenticate(IRequest req, IEnumerable`1 authProviders) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\AuthenticateAttribute.cs:line 96
at ServiceStack.AuthenticateAttribute.ExecuteAsync(IRequest req, IResponse res, Object requestDto) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\AuthenticateAttribute.cs:line 74
at ServiceStack.Host.ServiceRunner`1.ExecuteAsync(IRequest req, Object instance, TRequest requestDto) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Host\ServiceRunner.cs:line 127
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 640574.8754ms 400 application/json; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost:2019-07-01 17:01:14,607 [16] INFO Microsoft.AspNetCore.Hosting.Internal.WebHost - Request finished in 640574.8754ms 400 application/json; charset=utf-8
Clearly I have missed something obvious...any pointers appreciated.
// Register ORMLite connection
container.Register<IDbConnectionFactory>(dbFactory);
//Tell ServiceStack you want to persist User Auth Info in SQL Server
container.Register<IAuthRepository>(c => new OrmLiteAuthRepository(dbFactory));
// See https://docs.servicestack.net/api-key-authprovider
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new ApiKeyAuthProvider(AppSettings) {
SessionCacheDuration = TimeSpan.FromMinutes(10),
AllowInHttpParams = true, // Whether to allow API Keys in 'apikey' QueryString or FormData (e.g. `?apikey={APIKEY}`)
RequireSecureConnection = true,
},
}
) {
IncludeRegistrationService = true,
});
GlobalRequestFilters.Add((req, res, dto) =>
{
LastApiKey = req.GetApiKey();
});
Request
POST https://localhost:44347/api/customers HTTP/1.1
Host: localhost:44347
Connection: keep-alive
Content-Length: 2
Accept: application/json
Origin: https://localhost:44347
Authorization: yDOr26HsxyhpuRB3qbG07qfCmDhqutnA-yDOr26HsxyhpuRB3qbG07qfCmDhqutnA-yDOr26HsxyhpuRB3qbG07qfCmDhqutnA
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Content-Type: application/json
Referer: https://localhost:44347/swagger-ui/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8
{}
Response
HTTP/1.1 400 ArgumentOutOfRangeException
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Vary: Accept,Origin
Server: Microsoft-IIS/10.0
X-Powered-By: ServiceStack/5.50 NetCore/Windows
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: Content-Type
X-Startup-Errors: 1
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Content-Disposition
X-SourceFiles: =?UTF-8?B?QzpcUmVwb3NcTUJXZWJccnZhcGlcUnZXZWJcUnZBcGlcYXBpXGN1c3RvbWVycw==?=
X-Powered-By: ASP.NET
Date: Wed, 03 Jul 2019 08:07:40 GMT
13e
{"responseStatus":{"errorCode":"ArgumentOutOfRangeException","message":"Length cannot be less than zero.\r\nParameter name: length","errors":[{"errorCode":"ArgumentOutOfRangeException","fieldName":"length","message":"Length cannot be less than zero.\r\n"}]},"responseCreatedUtcDateTime":"2019-07-03T08:07:40.7955827Z"}
0
Your client is sending an invalid Authorization Bearer Token, it needs to have the Authroization Bearer Token format:
Authorization: Bearer {Token}
If you're sending an Authenticated API Key or JWT Request via Open API it needs to have the Bearer prefix as per the Open API docs:
OK I had manually created a User and APIKey in the underlying tables and had used a UserAuthId 'SomeAuthId' i.e. letter in them, and the ORM repository code is expecting these to be integers. Its cool that I can see the code in github and debug this myself - thanks for the comment as it got me thinking and looking into my Auth setup.

Getting code=OrganizationFromTenantGuidNotFound while updating group using Microsoft Graph

I am getting the below exception
"error": {
"code": "OrganizationFromTenantGuidNotFound",
"message": "The tenant for tenant guid '****' does not exist.",
"innerError": {
"request-id": "2acd6af1-99f8-4aab-b71d-cffc60263a05",
"date": "2019-04-20T11:33:04"
}
while updating the group using open extension as shown below: -
POST https://graph.microsoft.com/v1.0/groups/db5f4dbe-40e0-4352-84fb-9a20c131cfaf/extensions HTTP/1.1
Authorization: Bearer ****
Content-Type: text/plain; charset=utf-8
Host: graph.microsoft.com
Content-Length: 111
Expect: 100-continue
Connection: Keep-Alive
{ "#odata.type":"microsoft.graph.openTypeExtension","extensionName":"com.test.nickName","date":"OpenExtension"}
I am using user***#outlook.com id and having active azure subscription. I have given all delegated permission to microsoft graph.
Content type was not specified and it was going as text. Error handling could be improved. After changing content type to "application/json", it is working perfectly fine.
POST https://graph.microsoft.com/v1.0/groups/db5f4dbe-40e0-4352-84fb-9a20c131cfaf/extensions HTTP/1.1 Authorization: Bearer **** Content-Type: application/json; charset=utf-8 Host: graph.microsoft.com Content-Length: 111 Expect: 100-continue Connection: Keep-Alive
{ "#odata.type":"microsoft.graph.openTypeExtension","extensionName":"com.test.nickName","date":"OpenExtension"}

Windows azure blob set properties

I'm geting an error 'The remote server returned an error: (404) Not Found.
CloudBlockBlob blockBlob = container.GetBlockBlobReference("test.csv");
blockBlob.Properties.ContentType = "text/csv; charset=utf-8";
blockBlob.SetProperties();
The error is being thrown at SetProperties.
I have seen a few codes where they do not call SetProperties(). Does the contenttype get saved to the blob in such cases?
I did some search and found some people suggesting to check on fiddler.
The following is happening on fiddler..
/xxxevents?restype=container Result 404
/xxxevents?restype=container Result 201 Created ( Container.CreateIfNotExists called)
Now it throws an error while creating the blob.. Request and response headers provided..
404 HTTPS xxx.blob.core.windows.net /xxxevents/test.csv?comp=properties 215 application/xml waworkerhost:5500
PUT https://xxx.blob.core.windows.net/xxxevents/test.csv?comp=properties HTTP/1.1
User-Agent: WA-Storage/4.3.0 (.NET CLR 4.0.30319.18444; Win32NT 6.1.7601.65536)
x-ms-version: 2014-02-14
x-ms-blob-content-type: text/csv; charset=utf-8
x-ms-client-request-id: 2424933c-1bd7-49fd-998e-11d5499da03b
x-ms-date: Sun, 28 Sep 2014 07:16:04 GMT
Authorization: SharedKey xxx:tQ6DeUSVSq0TIaRjnVQoOgqNJIlHU5k1uay4loMeU04=
Host: xxx.blob.core.windows.net
Content-Length: 0
HTTP/1.1 404 The specified blob does not exist.
Content-Length: 215
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 7845cafa-0001-0033-7d19-af2c68000000
x-ms-version: 2014-02-14
Date: Sun, 28 Sep 2014 07:15:53 GMT
Would sincerely appreciate any help
Thanks
This is expected behavior. SetBlobProperties() method can only be called on blobs which are there in your blob storage. What you would need to do is upload blob first.
Assuming you're trying to upload test.csv file from say C:\temp folder, here's what you would need to do:
CloudBlockBlob blockBlob = container.GetBlockBlobReference("test.csv");
blockBlob.Properties.ContentType = "text/csv; charset=utf-8";
blockBlob.UploadFromFile(#"C:\temp\test.csv", FileMode.Open);

JSF-Login-Page in HTTP-Response despite valid JSESSIONID

I think this a HTTP-related problem.
I want to use my (JAX-RS) RESTeasy Service on a (JEE6) JBoss AS 7 Server from an Android Device. The RESTeasy Service is working fine. I am using on the Client-Side the Restlet-Client. This works too - without Security.
I want to use my JAAS-Formbased Security for the Pattern /rest/* in web.xml. So I have to send a HTTP-POST-Request with the Form-Data (j_username and j_password) to /foo/j_security_check.
I get the JSESSIONID from the first Response by the Server:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=uKUqlkUWdhX2l-FihiWyeSJr.undefined; Path=/foo
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 CET
X-Powered-By: JSF/2.0
Content-Type: text/html;charset=utf-8
Content-Length: 1028
Date: Wed, 15 Aug 2012 11:42:59 GMT
For this anonymous session I am authenticating ...
Header:
POST /foo/j_security_check HTTP/1.1
Date: Wed, 15 Aug 2012 11:42:58 GMT
Accept: text/html
Host: 172.24.47.5:8080
User-Agent: Restlet-Framework/2.0.14
Cookie: JSESSIONID=uKUqlkUWdhX2l-FihiWyeSJr.undefined
Content-Length: 62
Content-Language: *
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content:
j_username=Bob&j_password=a
... and it works: JBoss-Security-TRACE:
2012-08-15 13:22:26,829 TRACE
[org.jboss.security.auth.spi.DatabaseServerLoginModule]
(http-0.0.0.0-0.0.0.0-8080-4) User 'Bob' authenticated, loginOk=true
Now the Problem: In the following request I want to GET the REST-URL (using the Cookie JSESSIONID):
GET /foo/rest/sync/products HTTP/1.1
Date: Wed, 15 Aug 2012 11:42:59 GMT
Accept: application/json
Host: 172.24.47.5:8080
User-Agent: Restlet-Framework/2.0.14
Cookie: JSESSIONID=uKUqlkUWdhX2l-FihiWyeSJr.undefined
Content-Length: 0
But instead of returning the Response with JSON Content, the server is returning the JSF-Login-Page, because it want's me to authenticate again(?):
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 CET
X-Powered-By: JSF/2.0
Content-Type: text/html;charset=utf-8
Content-Length: 936
Date: Wed, 15 Aug 2012 11:42:59 GMT
<?xml version="1.0" encoding="utf-8"?> ... ... ... </html>
If I login with the Browser and then open the REST-URL it works fine. This is the GET-Request by the Browser:
GET http://localhost:8080/foo/rest/sync/products HTTP/1.1
Host: localhost:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.5 (KHTML, like Gecko)
Chrome/19.0.1084.56 Safari/536.5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: JSESSIONID=royq26yLd7REOz2otiZdTl6j.undefined
Anyone has an idea? I think the problem lays in the last request (GET /foo/rest/sync/products), because in the Browser it works fine.
Thanks

Resources