protected override IEnumerator <AsyncStep> GetAsyncSteps() { Task <CbsToken> getTokenTask = null; yield return(this.CallTask( (thisPtr, t) => getTokenTask = thisPtr.tokenProvider.GetTokenAsync(thisPtr.namespaceAddress, thisPtr.resource, thisPtr.requiredClaims), ExceptionPolicy.Transfer)); this.token = getTokenTask.Result; string tokenType = this.token.TokenType; if (tokenType == null) { this.Complete(new InvalidOperationException(AmqpResources.AmqpUnsupportedTokenType)); yield break; } RequestResponseAmqpLink requestResponseLink; if (this.cbsLink.linkFactory.TryGetOpenedObject(out requestResponseLink)) { this.requestResponseLinkTask = Task.FromResult(requestResponseLink); } else { yield return(this.CallTask( (thisPtr, t) => thisPtr.requestResponseLinkTask = thisPtr.cbsLink.linkFactory.GetOrCreateAsync(t), ExceptionPolicy.Transfer)); } AmqpValue value = new AmqpValue(); value.Value = this.token.TokenValue; AmqpMessage putTokenRequest = AmqpMessage.Create(value); putTokenRequest.ApplicationProperties = new ApplicationProperties(); putTokenRequest.ApplicationProperties.Map[CbsConstants.Operation] = CbsConstants.PutToken.OperationValue; putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Type] = tokenType; putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Audience] = this.audience; putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Expiration] = this.token.ExpiresAtUtc; AmqpMessage putTokenResponse = null; Fx.AssertIsNotNull(this.requestResponseLinkTask.Result, "requestResponseLink cannot be null without exception"); yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.requestResponseLinkTask.Result.BeginRequest(putTokenRequest, t, c, s), (thisPtr, r) => putTokenResponse = thisPtr.requestResponseLinkTask.Result.EndRequest(r), ExceptionPolicy.Transfer)); int statusCode = (int)putTokenResponse.ApplicationProperties.Map[CbsConstants.PutToken.StatusCode]; string statusDescription = (string)putTokenResponse.ApplicationProperties.Map[CbsConstants.PutToken.StatusDescription]; if (statusCode == (int)AmqpResponseStatusCode.Accepted || statusCode == (int)AmqpResponseStatusCode.OK) { this.ExpiresAtUtc = this.token.ExpiresAtUtc; } else { this.Complete(ConvertToException(statusCode, statusDescription)); } }
/// <summary> /// Sends a security token for a resource for later access. /// </summary> /// <param name="tokenProvider">The provider for issuing security tokens.</param> /// <param name="namespaceAddress">The namespace (or tenant) name.</param> /// <param name="audience">The audience. In most cases it is the same as resource.</param> /// <param name="resource">The resource to access.</param> /// <param name="requiredClaims">The required claims to access the resource.</param> /// <param name="timeout">The operation timeout.</param> /// <returns></returns> public async Task <DateTime> SendTokenAsync(ICbsTokenProvider tokenProvider, Uri namespaceAddress, string audience, string resource, string[] requiredClaims, TimeSpan timeout) { if (this.connection.IsClosing()) { throw new OperationCanceledException("Connection is closing or closed."); } CbsToken token = await tokenProvider.GetTokenAsync(namespaceAddress, resource, requiredClaims).ConfigureAwait(false); string tokenType = token.TokenType; if (tokenType == null) { throw new NotSupportedException(AmqpResources.AmqpUnsupportedTokenType); } RequestResponseAmqpLink requestResponseLink; if (!this.linkFactory.TryGetOpenedObject(out requestResponseLink)) { requestResponseLink = await this.linkFactory.GetOrCreateAsync(timeout).ConfigureAwait(false); } AmqpValue value = new AmqpValue(); value.Value = token.TokenValue; AmqpMessage putTokenRequest = AmqpMessage.Create(value); putTokenRequest.ApplicationProperties.Map[CbsConstants.Operation] = CbsConstants.PutToken.OperationValue; putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Type] = tokenType; putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Audience] = audience; putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Expiration] = token.ExpiresAtUtc; AmqpMessage putTokenResponse = await requestResponseLink.RequestAsync(putTokenRequest, timeout).ConfigureAwait(false); int statusCode = (int)putTokenResponse.ApplicationProperties.Map[CbsConstants.PutToken.StatusCode]; string statusDescription = (string)putTokenResponse.ApplicationProperties.Map[CbsConstants.PutToken.StatusDescription]; if (statusCode == (int)AmqpResponseStatusCode.Accepted || statusCode == (int)AmqpResponseStatusCode.OK) { return(token.ExpiresAtUtc); } Exception exception; AmqpResponseStatusCode amqpResponseStatusCode = (AmqpResponseStatusCode)statusCode; switch (amqpResponseStatusCode) { case AmqpResponseStatusCode.BadRequest: exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; case AmqpResponseStatusCode.NotFound: exception = new AmqpException(AmqpErrorCode.NotFound, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; case AmqpResponseStatusCode.Forbidden: exception = new AmqpException(AmqpErrorCode.TransferLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; case AmqpResponseStatusCode.Unauthorized: exception = new AmqpException(AmqpErrorCode.UnauthorizedAccess, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; default: exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; } throw exception; }