Beispiel #1
0
        public static void PutCsbToken(Connection connection, ServiceBusConfiguration config, string audience)
        {
            var tokenProvider = new ManagedIdentityTokenProvider();
            var token         = tokenProvider.GetTokenAsync($"sb://{config.Host}/");

            var session = new Session(connection);

            var cbsClientAddress = "cbs-client-reply-to";
            var cbsSender        = new SenderLink(session, config.Subscription, "$cbs");
            var cbsReceiver      = new ReceiverLink(session, cbsClientAddress, "$cbs");

            // construct the put-token message
            var request = new Message(token.TokenValue)
            {
                Properties = new Properties
                {
                    MessageId = Guid.NewGuid().ToString(),
                    ReplyTo   = cbsClientAddress
                },
                ApplicationProperties = new ApplicationProperties
                {
                    ["operation"]  = "put-token",
                    ["type"]       = token.TokenType,
                    ["expiration"] = token.ExpiresAtUtc,
                    ["name"]       = audience
                }
            };

            cbsSender.SendAsync(request).Wait();
            Trace.WriteLine(TraceLevel.Information, " request: {0}", request.Properties);
            Trace.WriteLine(TraceLevel.Information, " request: {0}", request.ApplicationProperties);

            // receive the response
            var response = cbsReceiver.ReceiveAsync().Result;

            if (response?.Properties == null || response.ApplicationProperties == null)
            {
                throw new Exception("invalid response received");
            }

            // validate message properties and status code.
            Trace.WriteLine(TraceLevel.Information, " response: {0}", response.Properties);
            Trace.WriteLine(TraceLevel.Information, " response: {0}", response.ApplicationProperties);
            int statusCode = (int)response.ApplicationProperties["status-code"];

            if (statusCode != (int)HttpStatusCode.Accepted && statusCode != (int)HttpStatusCode.OK)
            {
                throw new Exception("put-token message was not accepted. Error code: " + statusCode);
            }

            // the sender/receiver may be kept open for refreshing tokens
            cbsSender.Close();
            cbsReceiver.Close();
            session.Close();
        }
Beispiel #2
0
        /// <inheritdoc />
        protected override async Task <BoolResult> StartupCoreAsync(OperationContext context)
        {
            await base.StartupCoreAsync(context).ThrowIfFailure();

            // Retry behavior in the Azure Event Hubs Client Library is controlled by the RetryPolicy property on the EventHubClient class.
            // The default policy retries with exponential backoff when Azure Event Hub returns a transient EventHubsException or an OperationCanceledException.
            if (ManagedIdentityUriHelper.TryParseForManagedIdentity(_configuration.EventHubConnectionString, out Uri eventHubNamespaceUri, out string eventHubName, out string managedIdentityId))
            {
                // https://docs.microsoft.com/en-us/dotnet/api/overview/azure/service-to-service-authentication#connection-string-support
                var tokenProvider = new ManagedIdentityTokenProvider(new AzureServiceTokenProvider($"RunAs=App;AppId={managedIdentityId}"));
                _eventHubClient = EventHubClient.CreateWithTokenProvider(
                    eventHubNamespaceUri,
                    eventHubName,
                    tokenProvider);
            }
Beispiel #3
0
        public async Task ThrowsIfMSINotEnabled()
        {
            _environment.SetEnvironmentVariable(EnvironmentSettingNames.MsiEndpoint, string.Empty);
            _environment.SetEnvironmentVariable(EnvironmentSettingNames.MsiSecret, string.Empty);

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                        ItExpr.Is <HttpRequestMessage>(s => MatchesVerb(s, HttpMethod.Get) && UrlMatchesSystemAssignedIdentity(s, UriWithNoSasTokenHost)),
                                                                        ItExpr.IsAny <CancellationToken>()).ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new StringContent(JsonConvert.SerializeObject(GetTokenServiceMsiResponse()))
            });

            _httpClientFactory = TestHelpers.CreateHttpClientFactory(handlerMock.Object);

            var tokenProvider = new ManagedIdentityTokenProvider(_environment, _httpClientFactory, new TestMetricsLogger(),
                                                                 NullLogger <ManagedIdentityTokenProvider> .Instance);

            await Assert.ThrowsAsync <InvalidOperationException>(async() => await tokenProvider.GetManagedIdentityToken(UriWithNoSasToken));
        }
Beispiel #4
0
        public async Task UsesUserAssignedIdentityToFetchToken()
        {
            _environment.SetEnvironmentVariable(EnvironmentSettingNames.MsiEndpoint, MsiEndpoint);
            _environment.SetEnvironmentVariable(EnvironmentSettingNames.MsiSecret, MSISecret);
            _environment.SetEnvironmentVariable(EnvironmentSettingNames.RunFromPackageManagedResourceId, UserAssignedIdentity);

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                        ItExpr.Is <HttpRequestMessage>(s => MatchesVerb(s, HttpMethod.Get) && UrlMatchesUserAssignedIdentity(s, UriWithNoSasTokenHost, UserAssignedIdentity)),
                                                                        ItExpr.IsAny <CancellationToken>()).ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new StringContent(JsonConvert.SerializeObject(GetTokenServiceMsiResponse()))
            });

            _httpClientFactory = TestHelpers.CreateHttpClientFactory(handlerMock.Object);

            var tokenProvider = new ManagedIdentityTokenProvider(_environment, _httpClientFactory, new TestMetricsLogger(), NullLogger <ManagedIdentityTokenProvider> .Instance);
            var token         = await tokenProvider.GetManagedIdentityToken(UriWithNoSasToken);

            Assert.Equal(AccessToken, token);
        }
Beispiel #5
0
 public async Task ThrowsOnInvalidUrls(string url)
 {
     var tokenProvider = new ManagedIdentityTokenProvider(_environment, _httpClientFactory, new TestMetricsLogger(), NullLogger <ManagedIdentityTokenProvider> .Instance);
     await Assert.ThrowsAsync <ArgumentException>(async() => await tokenProvider.GetManagedIdentityToken(url));
 }
        /// <summary>
        /// Creates a new instance of the ServiceBusNotificationService class
        /// </summary>
        public ServiceBusNotificationService(IConfiguration configuration,
                                             IOptions <NotificationServiceOptions> options,
                                             ILogger <ServiceBusNotificationService> logger)
        {
            try
            {
                this.configuration = configuration;
                if (options?.Value == null)
                {
                    throw new ArgumentNullException(nameof(options), "No configuration is defined for the notification service in the appsettings.json.");
                }

                if (options.Value.ServiceBus == null)
                {
                    throw new ArgumentNullException(nameof(options), "No ServiceBus element is defined in the configuration for the notification service in the appsettings.json.");
                }

                if (string.IsNullOrWhiteSpace(options.Value.ServiceBus.ConnectionString))
                {
                    throw new ArgumentNullException(nameof(options), "No connection string is defined in the configuration of the Service Bus notification service in the appsettings.json.");
                }

                if (string.IsNullOrWhiteSpace(options.Value.ServiceBus.QueueName))
                {
                    throw new ArgumentNullException(nameof(options), "No queue name is defined in the configuration of the Service Bus notification service in the appsettings.json.");
                }

                this.options = options.Value;
                this.logger  = logger;

                if (this.options.ServiceBus.ConnectionString.ToLower().StartsWith("endpoint="))
                {
                    logger.LogInformation("Using Service Bus connectionString to connect to the Service Bus namespace...");
                    queueClient = new QueueClient(this.options.ServiceBus.ConnectionString,
                                                  this.options.ServiceBus.QueueName);
                }
                else if (this.options.ServiceBus.ConnectionString.ToLower().EndsWith(".servicebus.windows.net"))
                {
                    logger.LogInformation("Using System-Assigned Managed Instance to connect to the Service Bus namespace...");
                    var tokenProvider = new ManagedIdentityTokenProvider();
                    queueClient = new QueueClient(this.options.ServiceBus.ConnectionString,
                                                  this.options.ServiceBus.QueueName,
                                                  tokenProvider);
                }
                else
                {
                    logger.LogError("The Service Bus connectionString format is wrong", this.options.ServiceBus.ConnectionString);
                }
                logger.LogInformation("QueueClient successfully created.ConnectionString = [{connectionstring}] QueueName = [{queuename}]",
                                      this.options.ServiceBus.ConnectionString,
                                      this.options.ServiceBus.QueueName);
                var instrumentationKey = configuration["ApplicationInsights:InstrumentationKey"];
                if (string.IsNullOrWhiteSpace(instrumentationKey))
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "An error occurred while creating an instance of the ServiceBusNotificationService class");
                throw;
            }
        }