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(); }
/// <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); }
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)); }
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); }
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; } }