-
Notifications
You must be signed in to change notification settings - Fork 493
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(service-client: Refactor and add implementation for token credential…
… input) (#1781)
- Loading branch information
Showing
6 changed files
with
175 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.Azure.Amqp; | ||
using Microsoft.Azure.Devices.Common; | ||
|
||
namespace Microsoft.Azure.Devices | ||
{ | ||
/// <summary> | ||
/// The properties required for authentication to IoT hub that are independent of the authentication type. | ||
/// </summary> | ||
internal abstract class IotHubCredential | ||
: IAuthorizationHeaderProvider, ICbsTokenProvider | ||
{ | ||
private const string HostNameSeparator = "."; | ||
private const string HttpsEndpointPrefix = "https"; | ||
|
||
// Azure.Core (used in IotHubTokenCredential) is not available in NET451. | ||
// So we need this constructor for the build to pass. | ||
protected IotHubCredential() | ||
{ | ||
} | ||
|
||
protected IotHubCredential(string hostName) | ||
{ | ||
HostName = hostName; | ||
IotHubName = GetIotHubName(hostName); | ||
AmqpEndpoint = new UriBuilder(CommonConstants.AmqpsScheme, HostName, AmqpConstants.DefaultSecurePort).Uri; | ||
HttpsEndpoint = new UriBuilder(HttpsEndpointPrefix, HostName).Uri; | ||
} | ||
|
||
public string IotHubName { get; protected set; } | ||
|
||
public string HostName { get; protected set; } | ||
|
||
public Uri HttpsEndpoint { get; protected set; } | ||
|
||
public Uri AmqpEndpoint { get; protected set; } | ||
|
||
public abstract string GetAuthorizationHeader(); | ||
|
||
public abstract Task<CbsToken> GetTokenAsync(Uri namespaceAddress, string appliesTo, string[] requiredClaims); | ||
|
||
public Uri BuildLinkAddress(string path) | ||
{ | ||
var builder = new UriBuilder(AmqpEndpoint) | ||
{ | ||
Path = path, | ||
}; | ||
|
||
return builder.Uri; | ||
} | ||
|
||
private static string GetIotHubName(string hostName) | ||
{ | ||
if (string.IsNullOrWhiteSpace(hostName)) | ||
{ | ||
throw new ArgumentNullException($"{nameof(hostName)} is null or empty."); | ||
} | ||
|
||
int index = hostName.IndexOf(HostNameSeparator, StringComparison.OrdinalIgnoreCase); | ||
string iotHubName = index >= 0 ? hostName.Substring(0, index) : hostName; | ||
return iotHubName; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.Azure.Amqp; | ||
using System.Threading; | ||
|
||
#if !NET451 | ||
|
||
using Azure.Core; | ||
|
||
#endif | ||
|
||
namespace Microsoft.Azure.Devices | ||
{ | ||
/// <summary> | ||
/// The properties required for authentication to IoT hub using a token credential. | ||
/// </summary> | ||
internal class IotHubTokenCredential : IotHubCredential | ||
{ | ||
#if NET451 | ||
|
||
public IotHubTokenCredential() | ||
{ | ||
throw new InvalidOperationException("nameof(TokenCredential) is not supported in NET451"); | ||
} | ||
#else | ||
private const string _tokenType = "jwt"; | ||
private readonly TokenCredential _credential; | ||
|
||
public IotHubTokenCredential(string hostName, TokenCredential credential) : base(hostName) | ||
{ | ||
_credential = credential; | ||
} | ||
|
||
#endif | ||
|
||
public override string GetAuthorizationHeader() | ||
{ | ||
#if NET451 | ||
throw new InvalidOperationException($"{nameof(GetAuthorizationHeader)} is not supported on NET451"); | ||
|
||
#else | ||
AccessToken token = _credential.GetToken(new TokenRequestContext(), new CancellationToken()); | ||
return $"Bearer {token.Token}"; | ||
|
||
#endif | ||
} | ||
|
||
#pragma warning disable CS1998 // Disabled as we need to throw exception for NET 451. | ||
|
||
public async override Task<CbsToken> GetTokenAsync(Uri namespaceAddress, string appliesTo, string[] requiredClaims) | ||
{ | ||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously | ||
#if NET451 | ||
throw new InvalidOperationException($"{nameof(GetTokenAsync)} is not supported on NET451"); | ||
|
||
#else | ||
AccessToken token = await _credential.GetTokenAsync(new TokenRequestContext(), new CancellationToken()).ConfigureAwait(false); | ||
return new CbsToken( | ||
token.Token, | ||
_tokenType, | ||
token.ExpiresOn.UtcDateTime); | ||
#endif | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.