Trying to learn AWS IoT, I created a few "Things" + a Policy and I am even able to use IoT CLI to list-things or list-policies. I am even able to update the shadow through CLI with update-thing command through CLI. But once I try to access a Shadow through REST GET / POST request (through a .Net program or directly like https://XXXXXXXXXXXXX.iot.us-west-2.amazonaws.com/things/mything/shadow), I receive a
"Missing Authentication Token"
. So I started to use a certificate. Here is part of my code:
string Certificate = "xxxxxxxxx-certificate.crt"; // downloaded from my thing
X509Certificate cert = new X509Certificate(Certificate);
WebRequestHandler handler = new WebRequestHandler();
handler.ClientCertificates.Add(cert);
HttpClient client = new HttpClient(handler);
// url = @"https://xxxxxxxxxxxxx.iot.us-west-2.amazonaws.com/things/<mything>/shadow";
HttpResponseMessage webResponse = client.GetAsync(url, HttpCompletionOption.ResponseContentRead).Result;
The result is:
StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
x-amzn-RequestId: 25f3c1dc-9ddd-4787-a4cf-cb79dc96748b
connection: Keep-Alive
x-amzn-ErrorType: ForbiddenException:
Date: Tue, 15 Dec 2015 08:53:56 GMT
Content-Length: 91
Content-Type: application/json
}
Any assistance?
If you want to publish and/or subscribe to topics, you can take two different approach.
For the "missing authentication token" exception you get is due to unavailability of authentication tokens and amazon specific headers in your request. To make your HTTPS request work, You either use a rest client to add amazon specific headers or write a program.
You should try doing the following steps to make your https requests to work.
For detailed steps, refer http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
TASK 1: CREATE A CANONICAL REQUEST
TASK 2: CREATE THE STRING TO SIGN Using SHA256 algorithm, hash the canonical request (using any programming language/tools) and create a string to sign like below
string_to_sign = YourHashingAlgorithm + '\n' + CurrentDateInUTC+ '\n' + credential_scope + '\n' + yourHashedCanonicalRequest
API's to AWS services are uniquely identified by service paths. For IOT it is "iotdata/aws4_request". So your credential_scope in the above 'string_to_sign' should be like
credential_scope = datestamp + '/' + us-west-2+ '/' + iotdata+ '/' + 'aws4_request'
TASK 3: CALCULATE THE SIGNATURE
Calculate the hash using the same algorithm used in previous steps.
Refer the above said link for more details.
TASK 4: ADD SIGNING INFORMATION TO THE REQUEST
Here you need to set some of the headers like 'x-amz-date','Authorization', 'SignedHeaders' and 'Signature'. This Signature header will carry the final value of the Step 3.
Note: None of these headers are optional. Every HTTPS request should have all this information for authentication and authorization. Else AWS API will reject it.
You should get a 200 OK response to assure that your request is actually processed.
Coming to your .Net approach, you can try using AWS's .NET SDK and try inspecting the final request. I never tried using x.509 certificates directly in code. I think you are missing headers in your requests.
In cURL it would be something like below
curl "https://iot.amazonaws.com" \ --request GET \ --form "Action=UpdateThing" \ --form "UserName=iam_user" \ --form "CertificateBody=@~/.aws/credentials/sample/cert.pem" \ --form "Version=2010-05-08" \ --form "AUTHPARAMS"
Hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With