public async Task RegistryManager_Http_SasCredentialAuth_Renewed_Success()
        {
            // arrange
            string signature     = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(-1));
            var    sasCredential = new AzureSasCredential(signature);

            using var registryManager = RegistryManager.Create(
                      TestConfiguration.IoTHub.GetIotHubHostName(),
                      sasCredential);

            var device = new Device(Guid.NewGuid().ToString());

            // act
            try
            {
                await registryManager.AddDeviceAsync(device).ConfigureAwait(false);

                Assert.Fail("The SAS token is expired so the call should fail with an exception");
            }
            catch (UnauthorizedException)
            {
                // Expected to be unauthorized exception.
            }
            signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1));
            sasCredential.Update(signature);
            Device createdDevice = await registryManager.AddDeviceAsync(device).ConfigureAwait(false);

            // assert
            Assert.IsNotNull(createdDevice);

            // cleanup
            await registryManager.RemoveDeviceAsync(device.Id).ConfigureAwait(false);
        }
        public void SasCredentialUpdatesAreRespected()
        {
            var tokenExpiration  = TimeSpan.FromSeconds(GetSignatureRefreshBuffer().TotalSeconds / 2);
            var signature        = new SharedAccessSignature("hub-name", "keyName", "key", tokenExpiration);
            var sourceCredential = new AzureSasCredential(signature.Value);
            var credential       = new SharedAccessCredential(sourceCredential);

            Assert.That(GetSharedAccessSignature(credential).Value, Is.EqualTo(sourceCredential.Signature), "The signature should match the source credential.");

            var updatedSignature = new SharedAccessSignature("hub-name", "newKeyName", "newKey", tokenExpiration.Add(TimeSpan.FromMinutes(30)));

            sourceCredential.Update(updatedSignature.Value);

            var accessToken = credential.GetToken(new TokenRequestContext(), CancellationToken.None);

            Assert.That(accessToken.Token, Is.EqualTo(updatedSignature.Value));
            Assert.That(accessToken.ExpiresOn, Is.EqualTo(updatedSignature.SignatureExpiration).Within(TimeSpan.FromMinutes(5)));
        }
Beispiel #3
0
        public async Task TestCbsTokenGeneration_Succeeds()
        {
            // arrange
            DateTime epochTime            = new DateTime(1970, 1, 1);
            DateTime expiresAt            = DateTime.UtcNow.Add(TimeSpan.FromHours(1));
            TimeSpan secondsFromEpochTime = expiresAt.Subtract(epochTime);
            long     seconds = Convert.ToInt64(secondsFromEpochTime.TotalSeconds, CultureInfo.InvariantCulture);
            string   expiry  = Convert.ToString(seconds, CultureInfo.InvariantCulture);

            DateTime updatedExpiresAt            = DateTime.UtcNow.Add(TimeSpan.FromHours(2));
            TimeSpan updatedSecondsFromEpochTime = updatedExpiresAt.Subtract(epochTime);
            long     updatedSeconds = Convert.ToInt64(updatedSecondsFromEpochTime.TotalSeconds, CultureInfo.InvariantCulture);
            string   updatedExpiry  = Convert.ToString(updatedSeconds, CultureInfo.InvariantCulture);

            string token = string.Format(
                CultureInfo.InvariantCulture,
                "SharedAccessSignature sr={0}&sig={1}&se={2}",
                WebUtility.UrlEncode(_hostName),
                WebUtility.UrlEncode("signature"),
                expiry);

            string updatedToken = string.Format(
                CultureInfo.InvariantCulture,
                "SharedAccessSignature sr={0}&sig={1}&se={2}",
                WebUtility.UrlEncode(_hostName),
                WebUtility.UrlEncode("signature"),
                updatedExpiry);

            var azureSasCredential            = new AzureSasCredential(token);
            var iotHubSasCredentialProperties = new IotHubSasCredentialProperties(_hostName, azureSasCredential);

            // act

            CbsToken cbsToken = await iotHubSasCredentialProperties.GetTokenAsync(null, null, null).ConfigureAwait(false);

            azureSasCredential.Update(updatedToken);
            CbsToken updatedCbsToken = await iotHubSasCredentialProperties.GetTokenAsync(null, null, null).ConfigureAwait(false);

            // assert
            Math.Abs(expiresAt.Subtract(cbsToken.ExpiresAtUtc).TotalSeconds).Should().BeLessThan(1);
            Math.Abs(updatedExpiresAt.Subtract(updatedCbsToken.ExpiresAtUtc).TotalSeconds).Should().BeLessThan(1);
        }
        /// <summary>
        /// A sample to illustrate how to use SAS token for authentication to the IoT hub.
        /// <param name="args">Run with `--help` to see a list of required and optional parameters.</param>
        /// For more information on setting up AAD for IoT hub, see <see href="https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-dev-guide-azure-ad-rbac"/>
        /// </summary>
        public static async Task Main(string[] args)
        {
            // Parse application parameters
            Parameters parameters            = null;
            ParserResult <Parameters> result = Parser.Default.ParseArguments <Parameters>(args)
                                               .WithParsed(parsedParams =>
            {
                parameters = parsedParams;
            })
                                               .WithNotParsed(errors =>
            {
                Environment.Exit(1);
            });

            // Initialize SAS token credentials.
            Console.WriteLine("Creating sas credential.");

            TimeSpan timeToLive = TimeSpan.FromHours(1);
            DateTime expiresOn  = DateTime.UtcNow.Add(timeToLive);
            string   sasToken   = GenerateSasToken(parameters.ResourceUri, parameters.SharedAccessKey, expiresOn);
            // Note: Pass the generated sasToken and not just the shared access signature when creating the AzureSasCredential.
            AzureSasCredential sasCredential = new AzureSasCredential(sasToken);

            // This is how the credential can be updated in the AzureSasCredential object whenever necessary.
            // This sample just shows how to perform the update but it is not necessary to update the token
            // until the token is close to its expiry.
            DateTime newExpiresOn    = DateTime.UtcNow.Add(timeToLive);
            string   updatedSasToken = GenerateSasToken(parameters.ResourceUri, parameters.SharedAccessKey, newExpiresOn);

            sasCredential.Update(updatedSasToken);

            // There are constructors for all the other clients where you can pass SAS credentials - JobClient, RegistryManager, DigitalTwinClient
            var hostName = parameters.ResourceUri.Split('/')[0];

            using var serviceClient = ServiceClient.Create(hostName, sasCredential, parameters.TransportType);

            var sample = new AzureSasCredentialAuthenticationSample();
            await sample.RunSampleAsync(serviceClient, parameters.DeviceId);
        }
        public async Task Service_Amqp_SasCredentialAuth_Renewed_Success()
        {
            // arrange
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt);
            await deviceClient.OpenAsync().ConfigureAwait(false);

            string signature     = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(-1));
            var    sasCredential = new AzureSasCredential(signature);

            using var serviceClient = ServiceClient.Create(
                      TestConfiguration.IoTHub.GetIotHubHostName(),
                      sasCredential,
                      TransportType.Amqp);

            // act
            try
            {
                await serviceClient.OpenAsync().ConfigureAwait(false);

                Assert.Fail("The SAS token is expired so the call should fail with an exception");
            }
            catch (AmqpException ex) when(ex.Error.Description.Contains("401"))
            {
                // Expected to get an unauthorized exception.
            }

            signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1));
            sasCredential.Update(signature);
            await serviceClient.OpenAsync().ConfigureAwait(false);

            using var message = new Message(Encoding.ASCII.GetBytes("Hello, Cloud!"));
            await serviceClient.SendAsync(testDevice.Id, message);

            // cleanup
            await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
        }