Microsoft.Azure.Devices.Edge.Hub.CloudProxy.Test
DeviceScopeTokenAuthenticatorTest.cs
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Hub.CloudProxy.Test
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Edge.Hub.CloudProxy.Authenticators;
using Microsoft.Azure.Devices.Edge.Hub.Core;
using Microsoft.Azure.Devices.Edge.Hub.Core.Device;
using Microsoft.Azure.Devices.Edge.Hub.Core.Idensaty;
using Microsoft.Azure.Devices.Edge.Hub.Core.Idensaty.Service;
using Microsoft.Azure.Devices.Edge.Util;
using Microsoft.Azure.Devices.Edge.Util.Test.Common;
using Moq;
using Xunit;
[Unit]
public clast DeviceScopeTokenAuthenticatorTest
{
[Fact]
public async Task AuthenticateTest_Device()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var serviceIdensaty = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(serviceIdensaty));
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(deviceId));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_DeviceUpdateServiceIdensaty()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var serviceIdensaty1 = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(GetKey(), GetKey())), ServiceIdensatyStatus.Enabled);
var serviceIdensaty2 = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(serviceIdensaty1));
deviceScopeIdensatiesCache.Setup(d => d.RefreshServiceIdensaty(deviceId))
.Callback((id) => deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(deviceId)).ReturnsAsync(Option.Some(serviceIdensaty2)))
.Returns(Task.CompletedTask);
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(deviceId));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
deviceScopeIdensatiesCache.Verify(d => d.GetServiceIdensaty(deviceId), Times.Exactly(2));
deviceScopeIdensatiesCache.Verify(d => d.RefreshServiceIdensaty(deviceId), Times.Once);
}
[Fact]
public async Task ReauthenticateTest_DeviceUpdateServiceIdensaty()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var serviceIdensaty1 = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(GetKey(), GetKey())), ServiceIdensatyStatus.Enabled);
var serviceIdensaty2 = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(deviceId))
.ReturnsAsync(Option.Some(serviceIdensaty1));
deviceScopeIdensatiesCache.Setup(d => d.RefreshServiceIdensaty(deviceId))
.Callback((id) => deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(deviceId)).ReturnsAsync(Option.Some(serviceIdensaty2)))
.Returns(Task.CompletedTask);
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(deviceId));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.ReauthenticateAsync(tokenCredentials);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
deviceScopeIdensatiesCache.Verify(d => d.GetServiceIdensaty(deviceId), Times.Once);
deviceScopeIdensatiesCache.Verify(d => d.RefreshServiceIdensaty(deviceId), Times.Never);
}
[Fact]
public async Task AuthenticateTest_Module()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
string moduleId = "m1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var serviceIdensaty = new ServiceIdensaty(deviceId, moduleId, "e1", new List(), "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == $"{deviceId}/{moduleId}")))
.ReturnsAsync(Option.Some(serviceIdensaty));
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == $"{deviceId}/{moduleId}")))
.ReturnsAsync(Option.Some($"{deviceId}/{moduleId}"));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.ModuleId == moduleId && d.Id == $"{deviceId}/{moduleId}");
string token = GetDeviceToken(iothubHostName, deviceId, moduleId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_ModuleWithDeviceToken()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
string moduleId = "m1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var deviceServiceIdensaty = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Enabled);
var moduleServiceIdensaty = new ServiceIdensaty(deviceId, moduleId, "e1", new List(), "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(GetKey(), GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == $"{deviceId}/{moduleId}")))
.ReturnsAsync(Option.Some(moduleServiceIdensaty));
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == $"{deviceId}/{moduleId}")))
.ReturnsAsync(Option.Some($"{deviceId}/{moduleId}"));
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(deviceServiceIdensaty));
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(deviceId));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.ModuleId == moduleId && d.Id == $"{deviceId}/{moduleId}");
string token = GetDeviceToken(iothubHostName, deviceId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_ModuleWithDeviceKey()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
string moduleId = "m1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var deviceServiceIdensaty = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Enabled);
var moduleServiceIdensaty = new ServiceIdensaty(deviceId, moduleId, "e1", new List(), "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(GetKey(), GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == $"{deviceId}/{moduleId}")))
.ReturnsAsync(Option.Some(moduleServiceIdensaty));
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == $"{deviceId}/{moduleId}")))
.ReturnsAsync(Option.Some($"{deviceId}/{moduleId}"));
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(deviceServiceIdensaty));
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(deviceId));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.ModuleId == moduleId && d.Id == $"{deviceId}/{moduleId}");
string token = GetDeviceToken(iothubHostName, deviceId, moduleId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_Device_ServiceIdensatyNotEnabled()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var serviceIdensaty = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Disabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(serviceIdensaty));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_Device_WrongToken()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var serviceIdensaty = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(GetKey(), GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(serviceIdensaty));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_Device_TokenExpired()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var serviceIdensaty = new ServiceIdensaty(deviceId, "1234", new string[0], new ServiceAuthentication(new SymmetricKeyAuthentication(key, GetKey())), ServiceIdensatyStatus.Enabled);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.Some(serviceIdensaty));
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, key, TimeSpan.FromHours(-1));
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_Nested_Device()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string actorDeviceId = "actorEdge";
string leafDeviceId = "leaf";
var authChain = Option.Some(leafDeviceId + ";" + actorDeviceId);
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var actorAuth = new SymmetricKeyAuthentication(key, key);
var actorEdgeHubServiceIdensaty = new ServiceIdensaty(actorDeviceId, Constants.EdgeHubModuleId, null, new List(), "1234", Enumerable.Empty(), new ServiceAuthentication(actorAuth), ServiceIdensatyStatus.Enabled);
string actorEdgeHubId = actorEdgeHubServiceIdensaty.Id;
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == leafDeviceId)))
.ReturnsAsync(authChain);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == actorEdgeHubId)))
.ReturnsAsync(Option.Some(actorEdgeHubServiceIdensaty));
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true, true);
var actorEdgeHubIdensaty = Mock.Of(d => d.DeviceId == actorDeviceId && d.ModuleId == Constants.EdgeHubModuleId && d.Id == $"{actorDeviceId}/{Constants.EdgeHubModuleId}");
string token = GetDeviceToken(iothubHostName, actorDeviceId, Constants.EdgeHubModuleId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == actorEdgeHubIdensaty && t.Token == token && t.AuthChain == authChain);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task AuthenticateTest_Nested_Module()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string actorEdgeId = "parentEdge";
string nestedEdgeId = "childEdge";
string nestedModuleId = nestedEdgeId + "/" + Constants.EdgeHubModuleId;
var authChain = Option.Some(nestedModuleId + ";" + nestedEdgeId + ";" + actorEdgeId);
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
var nestedModuleIdensaty = Mock.Of(i => i.DeviceId == nestedEdgeId && i.ModuleId == Constants.EdgeHubModuleId && i.Id == nestedModuleId);
var actorAuth = new SymmetricKeyAuthentication(key, key);
var actorEdgeHubServiceIdensaty = new ServiceIdensaty(actorEdgeId, Constants.EdgeHubModuleId, null, new List(), "1234", Enumerable.Empty(), new ServiceAuthentication(actorAuth), ServiceIdensatyStatus.Enabled);
string actorEdgeHubId = actorEdgeHubServiceIdensaty.Id;
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == nestedModuleId)))
.ReturnsAsync(authChain);
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == actorEdgeHubId)))
.ReturnsAsync(Option.Some(actorEdgeHubServiceIdensaty));
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true, true);
var actorEdgeHubIdensaty = Mock.Of(d => d.DeviceId == actorEdgeId && d.ModuleId == Constants.EdgeHubModuleId && d.Id == $"{actorEdgeId}/{Constants.EdgeHubModuleId}");
string token = GetDeviceToken(iothubHostName, actorEdgeId, Constants.EdgeHubModuleId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == actorEdgeHubIdensaty && t.Token == token && t.AuthChain == authChain);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public void ValidateAudienceTest()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = Mock.Of();
string key = GetKey();
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, key);
SharedAccessSignature sharedAccessSignature = SharedAccessSignature.Parse(iothubHostName, token);
string audience = sharedAccessSignature.Audience;
// Act
bool isAuthenticated = authenticator.ValidateAudience(audience, idensaty);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public void ValidateAudienceWithEdgeHubHostNameTest()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = Mock.Of();
string key = GetKey();
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(edgehubHostName, deviceId, key);
SharedAccessSignature sharedAccessSignature = SharedAccessSignature.Parse(edgehubHostName, token);
string audience = sharedAccessSignature.Audience;
// Act
bool isAuthenticated = authenticator.ValidateAudience(audience, idensaty);
// astert
astert.True(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public void InvalidAudienceTest_DeviceId()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = Mock.Of();
string key = GetKey();
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(edgehubHostName, "d2", key);
SharedAccessSignature sharedAccessSignature = SharedAccessSignature.Parse(edgehubHostName, token);
string audience = sharedAccessSignature.Audience;
// Act
bool isAuthenticated = authenticator.ValidateAudience(audience, idensaty);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public void InvalidAudienceTest_Hostname()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = Mock.Of();
string key = GetKey();
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken("edgehub2", deviceId, key);
SharedAccessSignature sharedAccessSignature = SharedAccessSignature.Parse(edgehubHostName, token);
string audience = sharedAccessSignature.Audience;
// Act
bool isAuthenticated = authenticator.ValidateAudience(audience, idensaty);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public void InvalidAudienceTest_Device_Format()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = Mock.Of();
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string audience = $"{iothubHostName}/devices/{deviceId}/foo";
// Act
bool isAuthenticated = authenticator.ValidateAudience(audience, idensaty);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public void InvalidAudienceTest_Module_Format()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
string moduleId = "m1";
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = Mock.Of();
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.ModuleId == moduleId && d.Id == $"{deviceId}/{moduleId}");
string audience = $"{iothubHostName}/devices/{deviceId}/modules/{moduleId}/m1";
// Act
bool isAuthenticated = authenticator.ValidateAudience(audience, idensaty);
// astert
astert.False(isAuthenticated);
Mock.Get(underlyingAuthenticator).VerifyAll();
}
[Fact]
public async Task InvalidAuthChainTest_UnauthorizedActor()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string rootEdgeId = "rootEdge";
string actorEdgeId = "childEdge";
string leafDeviceId = "leaf";
var authChain = Option.Some(leafDeviceId + ";" + "NotActorEdge" + ";" + rootEdgeId);
var underlyingAuthenticator = Mock.Of();
var deviceScopeIdensatiesCache = new Mock();
string key = GetKey();
deviceScopeIdensatiesCache.Setup(d => d.GetAuthChain(It.Is(i => i == leafDeviceId)))
.ReturnsAsync(authChain);
var authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == actorEdgeId && d.ModuleId == Constants.EdgeHubModuleId && d.Id == $"{actorEdgeId}/{Constants.EdgeHubModuleId}");
string token = GetDeviceToken(iothubHostName, actorEdgeId, Constants.EdgeHubModuleId, key);
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
bool isAuthenticated = await authenticator.AuthenticateAsync(tokenCredentials);
// astert
astert.False(isAuthenticated);
}
[Fact]
public async Task ValidateUnderlyingAuthenticatorErrorTest()
{
// Arrange
string iothubHostName = "testiothub.azure-devices.net";
string edgehubHostName = "edgehub1";
string deviceId = "d1";
var underlyingAuthenticator = Mock.Of();
Mock.Get(underlyingAuthenticator).Setup(u => u.AuthenticateAsync(It.IsAny())).ThrowsAsync(new TimeoutException());
var deviceScopeIdensatiesCache = new Mock();
deviceScopeIdensatiesCache.Setup(d => d.GetServiceIdensaty(It.Is(i => i == deviceId)))
.ReturnsAsync(Option.None());
IAuthenticator authenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdensatiesCache.Object, iothubHostName, edgehubHostName, underlyingAuthenticator, true, true);
var idensaty = Mock.Of(d => d.DeviceId == deviceId && d.Id == deviceId);
string token = GetDeviceToken(iothubHostName, deviceId, GetKey());
var tokenCredentials = Mock.Of(t => t.Idensaty == idensaty && t.Token == token);
// Act
await astert.ThrowsAsync(() => authenticator.AuthenticateAsync(tokenCredentials));
// astert
Mock.Get(underlyingAuthenticator).VerifyAll();
Mock.Get(underlyingAuthenticator).Verify(u => u.AuthenticateAsync(It.IsAny()), Times.Once);
}
static string GetDeviceToken(string iothubHostName, string deviceId, string key, TimeSpan timeToLive)
{
DateTime startTime = DateTime.UtcNow;
string audience = WebUtility.UrlEncode($"{iothubHostName}/devices/{deviceId}");
string expiresOn = SasTokenHelper.BuildExpiresOn(startTime, timeToLive);
string data = string.Join("\n", new List { audience, expiresOn });
string signature = Sign(data, key);
return SasTokenHelper.BuildSasToken(audience, signature, expiresOn);
}
static string GetDeviceToken(string iothubHostName, string deviceId, string key)
=> GetDeviceToken(iothubHostName, deviceId, key, TimeSpan.FromHours(1));
static string GetDeviceToken(string iothubHostName, string deviceId, string moduleId, string key)
{
DateTime startTime = DateTime.UtcNow;
string audience = WebUtility.UrlEncode($"{iothubHostName}/devices/{deviceId}/modules/{moduleId}");
string expiresOn = SasTokenHelper.BuildExpiresOn(startTime, TimeSpan.FromHours(1));
string data = string.Join("\n", new List { audience, expiresOn });
string signature = Sign(data, key);
return SasTokenHelper.BuildSasToken(audience, signature, expiresOn);
}
static string Sign(string requestString, string key)
{
using (var algorithm = new HMACSHA256(Convert.FromBase64String(key)))
{
return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(requestString)));
}
}
static string GetKey() => Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
}
}