Answered by:
The specified SAS token is expired

Question
-
Running Windows Core Insider Preview (10556.0.150925-0019.TH2_RELEASE) on a Raspberry Pi2.
Connect to IOT Hub with a DeviceClient using a Device ID created with Device Explorer app.
Initially run very smoothly, sending messages to the IOT Hub and receiving messages from the Device Explorer App.
Now I'm getting a "The specified SAS token is expired" exception when ReceiveAsync or SensAsync is called.
How do I fix this? How do I get a new SAS token from the IOT Hub or the Service Hub and how do I get my Device Client to use this new token?
deviceClient.ReceiveAsync
Tuesday, November 17, 2015 2:07 PM
Answers
-
With the help of others, I managed to figure out that the reason for the "expiration" was the device time - Windows Iot Core doesn't sync with time servers by default, and if the time is sufficiently off, the generated SAS token is considered expired by the service endpoint.
In short, use e.g. "w32tm /resync /force" after boot.
- Proposed as answer by Morten H. Frederiksen Tuesday, December 1, 2015 9:56 PM
- Marked as answer by IoTGirlMicrosoft employee Thursday, December 3, 2015 5:37 PM
Wednesday, November 25, 2015 6:58 PM -
Thanks for the response.
The problem is I do not know the token setup as well. It is used somewhere deep inside the Internet of Things (IoT) .NET SDK.
After 24 hours and a clean restart, my IoT app is connecting again without any intervention from me. I will have to understand the use of SAS tokens better before starting production code.
- Marked as answer by EmbeddedGuyDan Wednesday, November 18, 2015 6:40 AM
- Unmarked as answer by IoTGirlMicrosoft employee Wednesday, November 18, 2015 5:33 PM
- Marked as answer by IoTGirlMicrosoft employee Wednesday, November 18, 2015 5:34 PM
Wednesday, November 18, 2015 6:39 AM -
The SAS token sent to the CBS link is generated by the .Net client starting from device id and device key you provide.
After generating the first token on the first Send, the client start an internal timer called when the token renewal is needed. When the timer expired, the client generates and sends a new SAS token to the CBS link.
You can see this mechanism in the SDK source code ...
IotHubConnection class with the two related methods SendCbsTokenAsync and OnRefreshToken.
As you can see the renewal is about every 1 hour.
Paolo
Paolo Patierno
- Edited by Paolo PatiernoMVP Wednesday, November 18, 2015 9:34 AM
- Proposed as answer by Paolo PatiernoMVP Wednesday, November 18, 2015 9:42 AM
- Marked as answer by IoTGirlMicrosoft employee Wednesday, November 18, 2015 5:33 PM
Wednesday, November 18, 2015 9:18 AM
All replies
-
Hi Dan,
Not sure what your token setup is but there is a great blog on SAS available at https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-1/ . If you follow the info there does it point out how to refresh the SAS in your case?
Sincerely,
IoTGirl
Tuesday, November 17, 2015 6:11 PM -
Thanks for the response.
The problem is I do not know the token setup as well. It is used somewhere deep inside the Internet of Things (IoT) .NET SDK.
After 24 hours and a clean restart, my IoT app is connecting again without any intervention from me. I will have to understand the use of SAS tokens better before starting production code.
- Marked as answer by EmbeddedGuyDan Wednesday, November 18, 2015 6:40 AM
- Unmarked as answer by IoTGirlMicrosoft employee Wednesday, November 18, 2015 5:33 PM
- Marked as answer by IoTGirlMicrosoft employee Wednesday, November 18, 2015 5:34 PM
Wednesday, November 18, 2015 6:39 AM -
The SAS token sent to the CBS link is generated by the .Net client starting from device id and device key you provide.
After generating the first token on the first Send, the client start an internal timer called when the token renewal is needed. When the timer expired, the client generates and sends a new SAS token to the CBS link.
You can see this mechanism in the SDK source code ...
IotHubConnection class with the two related methods SendCbsTokenAsync and OnRefreshToken.
As you can see the renewal is about every 1 hour.
Paolo
Paolo Patierno
- Edited by Paolo PatiernoMVP Wednesday, November 18, 2015 9:34 AM
- Proposed as answer by Paolo PatiernoMVP Wednesday, November 18, 2015 9:42 AM
- Marked as answer by IoTGirlMicrosoft employee Wednesday, November 18, 2015 5:33 PM
Wednesday, November 18, 2015 9:18 AM -
On RPi with any tutorial code sending to (or receiving from) IoT Hub, with a fresh Device Explorer-generated connection string or using a connection string from a device that actually works (using the Node.js API), the .Net API always fails with:
'Microsoft.Azure.Devices.Client.Exceptions.UnauthorizedException: {"Message":"The specified SAS token is expired"}
The exact same code, unchanged, worked yesterday, with same connection string:
deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, TransportType.Http1);
Message eventMessage = new Message(Encoding.UTF8.GetBytes(ctd.ToString()));
await deviceClient.SendEventAsync(eventMessage);
I don't see anything in the API that allows me control over the SAS tokens used.
- Merged by IoTGirlMicrosoft employee Friday, November 20, 2015 5:51 PM Duplicate question
Thursday, November 19, 2015 9:09 PM -
This related question has been marked as answered, but the merge of my question into this thread doesn't help me.
As stated, I don't see how the three lines of example code can be extended or changed to make it work, even for the first send. Also, as stated, the similar Node.js SDK works fine.
Since AMQP currently isn't implemented on the RPi, the code uses HTTP, and from what I can see from the SDK, the UWP/HTTP code doesn't use the mentioned methods - the IotHubConnection class is pretty much empty when running on the RPi.
Friday, November 20, 2015 7:47 PM -
With the help of others, I managed to figure out that the reason for the "expiration" was the device time - Windows Iot Core doesn't sync with time servers by default, and if the time is sufficiently off, the generated SAS token is considered expired by the service endpoint.
In short, use e.g. "w32tm /resync /force" after boot.
- Proposed as answer by Morten H. Frederiksen Tuesday, December 1, 2015 9:56 PM
- Marked as answer by IoTGirlMicrosoft employee Thursday, December 3, 2015 5:37 PM
Wednesday, November 25, 2015 6:58 PM -
Hi the Code where the Exception occurs Looks like this:
var DeviceClient = DeviceClient.Create(iotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey(DeviceId, deviceKey), TransportType.Http1); while (true) { Message receivedMessage = await DeviceClient.ReceiveAsync(); if (receivedMessage == null) continue; }
The ReceiveAsync failes. The same Code where this Problem occurs runs without Problems usually and some times without any changes it failes like this.
Here is the Exception Info copied:
Microsoft.Azure.Devices.Client.Exceptions.UnauthorizedException wurde nicht von Benutzercode behandelt. HResult=-2146233088 IsTransient=false Message={"Message":"The specified SAS token is expired"} Source=Microsoft.Azure.Devices.Client TrackingId="" StackTrace: at Microsoft.Azure.Devices.Client.HttpClientHelper.<ExecuteAsync>d__17.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Devices.Client.HttpClientHelper.<GetAsync>d__7`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Devices.Client.HttpDeviceClient.<OnReceiveAsync>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Devices.Client.DeviceClientHelper.<ReceiveAsync>d__14.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at IsmDevice.Device.<ReceiveC2dAsync>d__53.MoveNext() InnerException:
The Project is a UWP App and I run it on a Minnowboard MAX with Win IoTCore. I start this Project usually many times a day in debug mode without any issues. But when this Problem occurs like this morning, I have noc Chance and it throws this exception everytime i start the Project. Notice that I do not send Messages with a Sender but the Receive throws this Exception.
Any hints?
- Merged by IoTGirlMicrosoft employee Tuesday, December 1, 2015 9:53 PM Same error: The specified SAS token is expired
Friday, November 27, 2015 9:27 AM -
Today the Error occured again and I tried out "w32tm /resync /force".
Indeed that seems to work for me. Thanks a lot.
edit: sometimes when I use w32tm /resync I get: "The computer did not resync because no time data was available"
But the principle is the same, I set the correct time with "set-date -date ..." and it works.
- Edited by chrisbow Wednesday, December 16, 2015 3:47 PM
Thursday, December 3, 2015 8:45 AM -
Same here, I had the timezone correct on my device, but the time itself was off by about 3 or 4 hours.
Simply updating the time on my device resolved my issues. NO other changes.
- Edited by Lee Berg Tuesday, December 8, 2015 4:51 AM formatting
Tuesday, December 8, 2015 4:50 AM -
You can also set the time on your device by connecting through a PowerShell session
The date and time on the Pi must be correct for the security tokens used to publish to Azure to be valid. To check the current time zone setting on the Pi, type:
tzutil /g
If the time zone reported is not correct, you can find a list of valid time zones using (you may need to increase the buffer size on your powershell window):
tzutil /l
To set the time zone, locate the id of the time zone you want from the step above, then use:
`tzutil /s "Your TimeZone Name"
For example, for "Pacific Standard Time"
`tzutil /s "Pacific Standard Time"
To check the date on the Raspberry Pi, type
Get-Date
If the date or time is incorrect, use the
Set-Date
utilitySet-Date "mm/dd/yy hh:mm:ss AM/PM"
For Example, if it was 12:15 pm on January 3rd, 2016:
Set-Date "01/03/16 12:15 PM"
Reboot the device for the change to take effect. You can use the shutdown command as follows:
shutdown /r /t 0
Wednesday, March 9, 2016 5:34 PM -
are there any work planned for making this experience a bit better? opening a Powershell session to set timezone, date & time, forcing a sync or writing a startup script is fine if you're dealing with one or two devices. having to do this with hundreds of devices deployed remotely is a pain...Thursday, March 10, 2016 1:21 AM
-
From what I can tell, the latest (insider preview version, at least) versions of IoT Core has time sync enabled by default. Let the device run for a few minutes with a working internet connection, and it should end up with the right time. Also, setting the device time zone is now possible using the web interface.Thursday, March 10, 2016 8:37 PM
-
hi,
I am Working on IOT technology, in one my Universal Windows Project but not an Console project in that I want to send messages from device to cloud and cloud to device , for that concept I was created an one IoT hub in Azure.
and I was wrote below lines of code but I did not the output it gives the exception as SAS token has Expired and Unauthorized exception.
static async void SendDeviceToCloudMessagesAsync()
{
string iotHubUri = "XXXXX";
string deviceName = "XXXxxx";
string deviceKey = "XXXXXx=";var deviceClient = DeviceClient.Create(iotHubUri,
AuthenticationMethodFactory.
CreateAuthenticationWithRegistrySymmetricKey(deviceName, deviceKey),
TransportType.Http1);var str = "Hello, Cloud!";
var message = new Message(Encoding.ASCII.GetBytes(str));await deviceClient.SendEventAsync(message);
Debug.WriteLine("Sending message: {0}", message);
}and also see the complete exception in below figure.
Please tell me how to resolve this exception, when I was call SendEventAsync() method and ReceiveAsync() method.
Regards,
Pradeep
- Merged by IoTGirlMicrosoft employee Wednesday, March 30, 2016 6:48 PM Same error
Wednesday, March 30, 2016 11:25 AM -
have you searched the forum before posting?
are the answers not relevant to your issue?
Wednesday, March 30, 2016 1:44 PM -
Hi,
I already seen above links in forums before I was posting question in to forums but I my issue was not resolved.
pls tell me how to resolve it?
Regards,
pradeep
Wednesday, March 30, 2016 6:05 PM -
with the help of others i was clear the issue, I has something to do with a problem the Raspberry Pi has getting the correct time off the network (the time on the Pi is not within the SAS Token's life span).
I was opened my raspberry device in web browser then it will displayed wrong time after seen the time once I was restarted my device , then now working my IoT project with out any issue like SAS token has Expired.
- Proposed as answer by bandaru sateesh Thursday, March 31, 2016 5:05 AM
- Unproposed as answer by IoTGirlMicrosoft employee Thursday, March 31, 2016 4:29 PM
Thursday, March 31, 2016 5:02 AM