private async Task <ContainerProperties> ReadCollectionAsync( string collectionLink, IDocumentClientRetryPolicy retryPolicyInstance, ITrace trace, IClientSideRequestStatistics clientSideRequestStatistics, CancellationToken cancellationToken) { using (ITrace childTrace = trace.StartChild("Read Collection", TraceComponent.Transport, TraceLevel.Info)) { cancellationToken.ThrowIfCancellationRequested(); RequestNameValueCollection headers = new RequestNameValueCollection(); using (DocumentServiceRequest request = DocumentServiceRequest.Create( OperationType.Read, ResourceType.Collection, collectionLink, AuthorizationTokenType.PrimaryMasterKey, headers)) { headers.XDate = Rfc1123DateTimeCache.UtcNow(); request.RequestContext.ClientRequestStatistics = clientSideRequestStatistics ?? new ClientSideRequestStatisticsTraceDatum(DateTime.UtcNow, trace.Summary); if (clientSideRequestStatistics == null) { childTrace.AddDatum( "Client Side Request Stats", request.RequestContext.ClientRequestStatistics); } string authorizationToken = await this.tokenProvider.GetUserAuthorizationTokenAsync( request.ResourceAddress, PathsHelper.GetResourcePath(request.ResourceType), HttpConstants.HttpMethods.Get, request.Headers, AuthorizationTokenType.PrimaryMasterKey, childTrace); headers.Authorization = authorizationToken; using (new ActivityScope(Guid.NewGuid())) { retryPolicyInstance?.OnBeforeSendRequest(request); try { using (DocumentServiceResponse response = await this.storeModel.ProcessMessageAsync(request)) { return(CosmosResource.FromStream <ContainerProperties>(response)); } } catch (DocumentClientException ex) { childTrace.AddDatum("Exception Message", ex.Message); throw; } } } } }
private static void ValidateInputRequestTime( string dateToCompare, int masterTokenExpiryInSeconds, int allowedClockSkewInSeconds) { if (string.IsNullOrEmpty(dateToCompare)) { throw new UnauthorizedException(RMResources.MissingDateForAuthorization); } if (!DateTime.TryParse(dateToCompare, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal | DateTimeStyles.AllowWhiteSpaces, out DateTime utcStartTime)) { throw new UnauthorizedException(RMResources.InvalidDateHeader); } // Check if time range is beyond DateTime.MaxValue bool outOfRange = utcStartTime >= DateTime.MaxValue.AddSeconds(-masterTokenExpiryInSeconds); if (outOfRange) { string message = string.Format(CultureInfo.InvariantCulture, RMResources.InvalidTokenTimeRange, utcStartTime.ToString("r", CultureInfo.InvariantCulture), DateTime.MaxValue.ToString("r", CultureInfo.InvariantCulture), Rfc1123DateTimeCache.UtcNow()); DefaultTrace.TraceError(message); throw new ForbiddenException(message); } DateTime utcEndTime = utcStartTime + TimeSpan.FromSeconds(masterTokenExpiryInSeconds); AuthorizationHelper.CheckTimeRangeIsCurrent(allowedClockSkewInSeconds, utcStartTime, utcEndTime); }
public static void CheckTimeRangeIsCurrent( int allowedClockSkewInSeconds, DateTime startDateTime, DateTime expiryDateTime) { // Check if time ranges provided are beyond DateTime.MinValue or DateTime.MaxValue bool outOfRange = startDateTime <= DateTime.MinValue.AddSeconds(allowedClockSkewInSeconds) || expiryDateTime >= DateTime.MaxValue.AddSeconds(-allowedClockSkewInSeconds); // Adjust for a time lag between various instances upto 5 minutes i.e. allow [start-5, end+5] if (outOfRange || startDateTime.AddSeconds(-allowedClockSkewInSeconds) > DateTime.UtcNow || expiryDateTime.AddSeconds(allowedClockSkewInSeconds) < DateTime.UtcNow) { string message = string.Format(CultureInfo.InvariantCulture, RMResources.InvalidTokenTimeRange, startDateTime.ToString("r", CultureInfo.InvariantCulture), expiryDateTime.ToString("r", CultureInfo.InvariantCulture), Rfc1123DateTimeCache.UtcNow()); DefaultTrace.TraceError(message); throw new ForbiddenException(message); } }
public override ValueTask <(string token, string payload)> GetUserAuthorizationAsync( string resourceAddress, string resourceType, string requestVerb, INameValueCollection headers, AuthorizationTokenType tokenType) { // this is masterkey authZ headers[HttpConstants.HttpHeaders.XDate] = Rfc1123DateTimeCache.UtcNow(); string authorizationToken = AuthorizationHelper.GenerateKeyAuthorizationSignature( requestVerb, resourceAddress, resourceType, headers, this.authKeyHashFunction, out AuthorizationHelper.ArrayOwner arrayOwner); using (arrayOwner) { string payload = null; if (arrayOwner.Buffer.Count > 0) { payload = Encoding.UTF8.GetString(arrayOwner.Buffer.Array, arrayOwner.Buffer.Offset, (int)arrayOwner.Buffer.Count); } return(new ValueTask <(string token, string payload)>((authorizationToken, payload))); } }
private async Task <DocumentServiceResponse> GetMasterAddressesViaGatewayAsync( DocumentServiceRequest request, ResourceType resourceType, string resourceAddress, string entryUrl, bool forceRefresh, bool useMasterCollectionResolver) { INameValueCollection addressQuery = new RequestNameValueCollection { { HttpConstants.QueryStrings.Url, HttpUtility.UrlEncode(entryUrl) } }; INameValueCollection headers = new RequestNameValueCollection(); if (forceRefresh) { headers.Set(HttpConstants.HttpHeaders.ForceRefresh, bool.TrueString); } if (useMasterCollectionResolver) { headers.Set(HttpConstants.HttpHeaders.UseMasterCollectionResolver, bool.TrueString); } if (request.ForceCollectionRoutingMapRefresh) { headers.Set(HttpConstants.HttpHeaders.ForceCollectionRoutingMapRefresh, bool.TrueString); } addressQuery.Add(HttpConstants.QueryStrings.Filter, this.protocolFilter); string resourceTypeToSign = PathsHelper.GetResourcePath(resourceType); headers.Set(HttpConstants.HttpHeaders.XDate, Rfc1123DateTimeCache.UtcNow()); using (ITrace trace = Trace.GetRootTrace(nameof(GetMasterAddressesViaGatewayAsync), TraceComponent.Authorization, TraceLevel.Info)) { string token = await this.tokenProvider.GetUserAuthorizationTokenAsync( resourceAddress, resourceTypeToSign, HttpConstants.HttpMethods.Get, headers, AuthorizationTokenType.PrimaryMasterKey, trace); headers.Set(HttpConstants.HttpHeaders.Authorization, token); Uri targetEndpoint = UrlUtility.SetQuery(this.addressEndpoint, UrlUtility.CreateQuery(addressQuery)); string identifier = GatewayAddressCache.LogAddressResolutionStart(request, targetEndpoint); using (HttpResponseMessage httpResponseMessage = await this.httpClient.GetAsync( uri: targetEndpoint, additionalHeaders: headers, resourceType: resourceType, timeoutPolicy: HttpTimeoutPolicyControlPlaneRetriableHotPath.Instance, clientSideRequestStatistics: request.RequestContext?.ClientRequestStatistics, cancellationToken: default))
public MasterKeyAuthorizationBenchmark() { this.authKeyHashFunction = new StringHMACSHA256Hash(MockDocumentClient.GenerateRandomKey()); Headers headers = new Headers(); headers[HttpConstants.HttpHeaders.XDate] = Rfc1123DateTimeCache.UtcNow(); this.testHeaders = headers.CosmosMessageHeaders.INameValueCollection; }
public async Task AddSystemAuthorizationHeaderAsync( DocumentServiceRequest request, string federationId, string verb, string resourceId) { request.Headers[HttpConstants.HttpHeaders.XDate] = Rfc1123DateTimeCache.UtcNow(); request.Headers[HttpConstants.HttpHeaders.Authorization] = (await this.GetUserAuthorizationAsync( resourceId ?? request.ResourceAddress, PathsHelper.GetResourcePath(request.ResourceType), verb, request.Headers, request.RequestAuthorizationTokenType)).token; }
public override ValueTask AddAuthorizationHeaderAsync( INameValueCollection headersCollection, Uri requestAddress, string verb, AuthorizationTokenType tokenType) { string dateTime = Rfc1123DateTimeCache.UtcNow(); headersCollection[HttpConstants.HttpHeaders.XDate] = dateTime; string token = AuthorizationHelper.GenerateKeyAuthorizationSignature( verb, requestAddress, headersCollection, this.authKeyHashFunction); headersCollection.Add(HttpConstants.HttpHeaders.Authorization, token); return(default);
public void TestGenerateAuthorizationTokenWithHashCoreDoesNotEncodeUrl() { Mock <INameValueCollection> mockHeaders = new Mock <INameValueCollection>(); mockHeaders.SetupGet(h => h["x-ms-date"]).Returns(Rfc1123DateTimeCache.UtcNow()); Mock <IComputeHash> hashHelperMock = new Mock <IComputeHash>(); hashHelperMock.Setup( ch => ch.ComputeHash(It.IsAny <ArraySegment <byte> >())) .Returns(new byte[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }); string token = AuthorizationHelper.GenerateAuthorizationTokenWithHashCore( verb: "testVerb", resourceId: "dbs/V4lVAA==/colls/V4lVAMl0wuQ=/", resourceType: "colls", headers: mockHeaders.Object, stringHMACSHA256Helper: hashHelperMock.Object, out _); // Encoding.UTF8 string representation of the key byte array. (if it were URL encoded, it would end with "3d%3d" instead of "=="). Assert.AreEqual("AgQGCAoMDhASFA==", token); }
ValueTask <string> ICosmosAuthorizationTokenProvider.GetUserAuthorizationTokenAsync( string resourceAddress, string resourceType, string requestVerb, INameValueCollection headers, AuthorizationTokenType tokenType, ITrace trace) // unused, use token based upon what is passed in constructor { // this is masterkey authZ headers[HttpConstants.HttpHeaders.XDate] = Rfc1123DateTimeCache.UtcNow(); string authorization = AuthorizationHelper.GenerateKeyAuthorizationSignature( verb: requestVerb, resourceId: resourceAddress, resourceType: resourceType, headers: headers, stringHMACSHA256Helper: this.authKeyHashFunction, payload: out AuthorizationHelper.ArrayOwner payload); using (payload) { return(new ValueTask <string>(authorization)); } }
public override ValueTask <string> GetUserAuthorizationTokenAsync( string resourceAddress, string resourceType, string requestVerb, INameValueCollection headers, AuthorizationTokenType tokenType, ITrace trace) { // this is masterkey authZ headers[HttpConstants.HttpHeaders.XDate] = Rfc1123DateTimeCache.UtcNow(); string authorizationToken = AuthorizationHelper.GenerateKeyAuthorizationSignature( requestVerb, resourceAddress, resourceType, headers, this.authKeyHashFunction, out AuthorizationHelper.ArrayOwner arrayOwner); using (arrayOwner) { return(new ValueTask <string>(authorizationToken)); } }
public void Rfc1123DateTimeCacheUtcNow() { _ = Rfc1123DateTimeCache.UtcNow(); }
public static int SerializeMessagePayload( Span <byte> stream, string verb, string resourceId, string resourceType, INameValueCollection headers, bool bUseUtcNowForMissingXDate = false) { string xDate = AuthorizationHelper.GetHeaderValue(headers, HttpConstants.HttpHeaders.XDate); string date = AuthorizationHelper.GetHeaderValue(headers, HttpConstants.HttpHeaders.HttpDate); // At-least one of date header should present // https://docs.microsoft.com/en-us/rest/api/documentdb/access-control-on-documentdb-resources if (string.IsNullOrEmpty(xDate) && string.IsNullOrWhiteSpace(date)) { if (!bUseUtcNowForMissingXDate) { throw new UnauthorizedException(RMResources.InvalidDateHeader); } headers[HttpConstants.HttpHeaders.XDate] = Rfc1123DateTimeCache.UtcNow(); xDate = AuthorizationHelper.GetHeaderValue(headers, HttpConstants.HttpHeaders.XDate); } // for name based, it is case sensitive, we won't use the lower case if (!PathsHelper.IsNameBased(resourceId)) { resourceId = resourceId.ToLowerInvariant(); } int totalLength = 0; int length = stream.Write(verb.ToLowerInvariant()); totalLength += length; stream = stream.Slice(length); length = stream.Write("\n"); totalLength += length; stream = stream.Slice(length); length = stream.Write(resourceType.ToLowerInvariant()); totalLength += length; stream = stream.Slice(length); length = stream.Write("\n"); totalLength += length; stream = stream.Slice(length); length = stream.Write(resourceId); totalLength += length; stream = stream.Slice(length); length = stream.Write("\n"); totalLength += length; stream = stream.Slice(length); length = stream.Write(xDate.ToLowerInvariant()); totalLength += length; stream = stream.Slice(length); length = stream.Write("\n"); totalLength += length; stream = stream.Slice(length); length = stream.Write(xDate.Equals(string.Empty, StringComparison.OrdinalIgnoreCase) ? date.ToLowerInvariant() : string.Empty); totalLength += length; stream = stream.Slice(length); length = stream.Write("\n"); totalLength += length; return(totalLength); }
private static string GetUtcDateTime() { return(Rfc1123DateTimeCache.UtcNow()); }