src/Microsoft.Azure.NotificationHubs/Auth/SharedAccessSignatureTokenProvider.cs (72 lines of code) (raw):

//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for // license information. //------------------------------------------------------------ using System; using System.Text; using Microsoft.Azure.NotificationHubs.Common; namespace Microsoft.Azure.NotificationHubs.Auth { /// <summary> /// Represents a Token Provider for Shared Access Signatures /// </summary> public class SharedAccessSignatureTokenProvider : TokenProvider { private const int MaxKeyNameLength = 256; private const int MaxKeyLength = 256; internal readonly byte[] _encodedSharedAccessKey; internal readonly string _keyName; internal readonly TimeSpan _tokenTimeToLive; private static readonly TimeSpan DefaultTokenTimeout = TimeSpan.FromMinutes(20); private static readonly TimeSpan DefaultTokenRefreshTimeMargin = TimeSpan.FromMinutes(2); internal SharedAccessSignatureTokenProvider(string connectionString): base(DefaultTokenTimeout - DefaultTokenRefreshTimeMargin) { var builder = new NotificationHubConnectionStringBuilder(connectionString); this._keyName = builder.SharedAccessKeyName; this._encodedSharedAccessKey = Encoding.UTF8.GetBytes(builder.SharedAccessKey); this._tokenTimeToLive = DefaultTokenTimeout; } internal SharedAccessSignatureTokenProvider(string keyName, string sharedAccessKey) : this(keyName, sharedAccessKey, DefaultTokenTimeout) { } internal SharedAccessSignatureTokenProvider(string keyName, string sharedAccessKey, TimeSpan tokenTimeToLive) : base(tokenTimeToLive - DefaultTokenRefreshTimeMargin) { if (string.IsNullOrEmpty(keyName)) { throw new ArgumentNullException("keyName"); } if (keyName.Length > MaxKeyNameLength) { throw new ArgumentOutOfRangeException( "keyName", SRCore.ArgumentStringTooBig("keyName", MaxKeyNameLength)); } if (string.IsNullOrEmpty(sharedAccessKey)) { throw new ArgumentNullException("sharedAccessKey"); } if (sharedAccessKey.Length > MaxKeyLength) { throw new ArgumentOutOfRangeException( "sharedAccessKey", SRCore.ArgumentStringTooBig("sharedAccessKey", MaxKeyLength)); } this._encodedSharedAccessKey = Encoding.UTF8.GetBytes(sharedAccessKey); this._keyName = keyName; this._tokenTimeToLive = tokenTimeToLive; } /// <summary> /// Construct a TokenProvider based on a sharedAccessSignature. /// </summary> /// <param name="connectionString">The connection string to the resource</param> /// <returns>A TokenProvider initialized with the shared access signature</returns> public static TokenProvider CreateSharedAccessSignatureTokenProvider(string connectionString) { return new SharedAccessSignatureTokenProvider(connectionString); } /// <summary> /// Construct a TokenProvider based on the provided Key Name and Shared Access Key. /// </summary> /// <param name="keyName">The key name of the corresponding SharedAccessKeyAuthorizationRule.</param> /// <param name="sharedAccessKey">The key associated with the SharedAccessKeyAuthorizationRule</param> /// <returns>A TokenProvider initialized with the provided RuleId and Password</returns> public static TokenProvider CreateSharedAccessSignatureTokenProvider(string keyName, string sharedAccessKey) { return new SharedAccessSignatureTokenProvider(keyName, sharedAccessKey, DefaultTokenTimeout); } /// <summary> /// Generates the token based upon the applies to. /// </summary> /// <param name="appliesTo">The scope of the token to generate.</param> /// <returns>The generated token</returns> protected override string GenerateToken(string appliesTo) { return BuildSignature(appliesTo); } private string BuildSignature(string targetUri) { return SharedAccessSignatureBuilder.BuildSignature(this._keyName, this._encodedSharedAccessKey, targetUri, this._tokenTimeToLive); } } }