Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port: [#6701] Add ConnectorClientOptions to ConfigurationBotFrameworkAuthentication #542

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public static BotFrameworkAuthentication Create()
credentialFactory: new PasswordServiceClientCredentialFactory(),
authConfiguration: new AuthenticationConfiguration(),
httpClientFactory: null,
logger: null);
logger: null,
connectorClientOptions: null);
}

/// <summary>
Expand All @@ -50,6 +51,7 @@ public static BotFrameworkAuthentication Create()
/// <param name="authConfiguration">The <see cref="AuthenticationConfiguration" /> to use.</param>
/// <param name="httpClientFactory">The <see cref="IHttpClientFactory" /> to use.</param>
/// <param name="logger">The <see cref="ILogger" /> to use.</param>
/// <param name="connectorClientOptions">The <see cref="ConnectorClientOptions"/> to use when creating <see cref="ConnectorClient"/>.</param>
/// <returns>A new <see cref="BotFrameworkAuthentication" /> instance.</returns>
public static BotFrameworkAuthentication Create(
string channelService,
Expand All @@ -64,7 +66,8 @@ public static BotFrameworkAuthentication Create(
ServiceClientCredentialsFactory credentialFactory,
AuthenticationConfiguration authConfiguration,
IHttpClientFactory httpClientFactory,
ILogger logger)
ILogger logger,
ConnectorClientOptions connectorClientOptions = default)
{
if (
!string.IsNullOrEmpty(toChannelFromBotLoginUrl) ||
Expand All @@ -89,19 +92,20 @@ public static BotFrameworkAuthentication Create(
credentialFactory,
authConfiguration,
httpClientFactory,
logger);
logger,
connectorClientOptions);
}
else
{
// else apply the built in default behavior, which is either the public cloud or the gov cloud depending on whether we have a channelService value present

if (string.IsNullOrEmpty(channelService))
{
return new PublicCloudBotFrameworkAuthentication(credentialFactory, authConfiguration, httpClientFactory, logger);
return new PublicCloudBotFrameworkAuthentication(credentialFactory, authConfiguration, httpClientFactory, logger, connectorClientOptions);
}
else if (channelService == GovernmentAuthenticationConstants.ChannelService)
{
return new GovernmentCloudBotFrameworkAuthentication(credentialFactory, authConfiguration, httpClientFactory, logger);
return new GovernmentCloudBotFrameworkAuthentication(credentialFactory, authConfiguration, httpClientFactory, logger, connectorClientOptions);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ internal abstract class BuiltinBotFrameworkAuthentication : BotFrameworkAuthenti
private readonly AuthenticationConfiguration _authConfiguration;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger _logger;
private readonly ConnectorClientOptions _connectorClientOptions;

protected BuiltinBotFrameworkAuthentication(string toChannelFromBotOAuthScope, string loginEndpoint, string callerId, string channelService, string oauthEndpoint, ServiceClientCredentialsFactory credentialsFactory, AuthenticationConfiguration authConfiguration, IHttpClientFactory httpClientFactory, ILogger logger)
protected BuiltinBotFrameworkAuthentication(string toChannelFromBotOAuthScope, string loginEndpoint, string callerId, string channelService, string oauthEndpoint, ServiceClientCredentialsFactory credentialsFactory, AuthenticationConfiguration authConfiguration, IHttpClientFactory httpClientFactory, ILogger logger, ConnectorClientOptions connectorClientOptions = default)
{
_toChannelFromBotOAuthScope = toChannelFromBotOAuthScope;
_loginEndpoint = loginEndpoint;
Expand All @@ -46,6 +47,7 @@ protected BuiltinBotFrameworkAuthentication(string toChannelFromBotOAuthScope, s
_authConfiguration = authConfiguration;
_httpClientFactory = httpClientFactory;
_logger = logger ?? NullLogger.Instance;
_connectorClientOptions = connectorClientOptions;
}

public static string GetAppId(ClaimsIdentity claimsIdentity)
Expand Down Expand Up @@ -98,7 +100,7 @@ public override async Task<AuthenticateRequestResult> AuthenticateRequestAsync(A

var callerId = await GenerateCallerIdAsync(_credentialsFactory, claimsIdentity, _callerId, cancellationToken).ConfigureAwait(false);

var connectorFactory = new ConnectorFactoryImpl(GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _loginEndpoint, true, _credentialsFactory, _httpClientFactory, _logger);
var connectorFactory = new ConnectorFactoryImpl(GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _loginEndpoint, true, _credentialsFactory, _httpClientFactory, _logger, _connectorClientOptions);

return new AuthenticateRequestResult { ClaimsIdentity = claimsIdentity, Audience = outboundAudience, CallerId = callerId, ConnectorFactory = connectorFactory };
}
Expand All @@ -121,7 +123,7 @@ public override async Task<AuthenticateRequestResult> AuthenticateStreamingReque

public override ConnectorFactory CreateConnectorFactory(ClaimsIdentity claimsIdentity)
{
return new ConnectorFactoryImpl(GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _loginEndpoint, true, _credentialsFactory, _httpClientFactory, _logger);
return new ConnectorFactoryImpl(GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _loginEndpoint, true, _credentialsFactory, _httpClientFactory, _logger, _connectorClientOptions);
}

public override async Task<UserTokenClient> CreateUserTokenClientAsync(ClaimsIdentity claimsIdentity, CancellationToken cancellationToken)
Expand All @@ -130,7 +132,7 @@ public override async Task<UserTokenClient> CreateUserTokenClientAsync(ClaimsIde

var credentials = await _credentialsFactory.CreateCredentialsAsync(appId, _toChannelFromBotOAuthScope, _loginEndpoint, true, cancellationToken).ConfigureAwait(false);

return new UserTokenClientImpl(appId, credentials, _oauthEndpoint, _httpClientFactory?.CreateClient(), _logger);
return new UserTokenClientImpl(appId, credentials, _oauthEndpoint, _httpClientFactory?.CreateClient(), _logger, _connectorClientOptions);
}

public override BotFrameworkClient CreateBotFrameworkClient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ internal class ConnectorFactoryImpl : ConnectorFactory
private readonly ServiceClientCredentialsFactory _credentialFactory;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger _logger;
private readonly ConnectorClientOptions _connectorClientOptions;

public ConnectorFactoryImpl(string appId, string toChannelFromBotOAuthScope, string loginEndpoint, bool validateAuthority, ServiceClientCredentialsFactory credentialFactory, IHttpClientFactory httpClientFactory, ILogger logger)
public ConnectorFactoryImpl(string appId, string toChannelFromBotOAuthScope, string loginEndpoint, bool validateAuthority, ServiceClientCredentialsFactory credentialFactory, IHttpClientFactory httpClientFactory, ILogger logger, ConnectorClientOptions connectorClientOptions = default)
{
_appId = appId;
_toChannelFromBotOAuthScope = toChannelFromBotOAuthScope;
Expand All @@ -28,6 +29,7 @@ public ConnectorFactoryImpl(string appId, string toChannelFromBotOAuthScope, str
_credentialFactory = credentialFactory;
_httpClientFactory = httpClientFactory;
_logger = logger;
_connectorClientOptions = connectorClientOptions;
}

public override async Task<IConnectorClient> CreateAsync(string serviceUrl, string audience, CancellationToken cancellationToken)
Expand All @@ -39,6 +41,8 @@ public override async Task<IConnectorClient> CreateAsync(string serviceUrl, stri
#pragma warning disable CA2000 // Dispose objects before losing scope
var httpClient = _httpClientFactory?.CreateClient() ?? new HttpClient();
ConnectorClient.AddDefaultRequestHeaders(httpClient);
ConnectorClient.AddUserAgent(httpClient, _connectorClientOptions?.UserAgent);

return new ConnectorClient(new Uri(serviceUrl), credentials, httpClient, true);
#pragma warning restore CA2000 // Dispose objects before losing scope
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.Bot.Connector.Authentication
{
internal class GovernmentCloudBotFrameworkAuthentication : BuiltinBotFrameworkAuthentication
{
public GovernmentCloudBotFrameworkAuthentication(ServiceClientCredentialsFactory credentialFactory, AuthenticationConfiguration authConfiguration, IHttpClientFactory httpClientFactory, ILogger logger = null)
public GovernmentCloudBotFrameworkAuthentication(ServiceClientCredentialsFactory credentialFactory, AuthenticationConfiguration authConfiguration, IHttpClientFactory httpClientFactory, ILogger logger = null, ConnectorClientOptions connectorClientOptions = default)
: base(
GovernmentAuthenticationConstants.ToChannelFromBotOAuthScope,
GovernmentAuthenticationConstants.ToChannelFromBotLoginUrl,
Expand All @@ -19,7 +19,8 @@ public GovernmentCloudBotFrameworkAuthentication(ServiceClientCredentialsFactory
credentialFactory,
authConfiguration,
httpClientFactory,
logger)
logger,
connectorClientOptions)
{
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ internal class ParameterizedBotFrameworkAuthentication : BotFrameworkAuthenticat
private readonly AuthenticationConfiguration _authConfiguration;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger _logger;
private readonly ConnectorClientOptions _connectorClientOptions;

public ParameterizedBotFrameworkAuthentication(
bool validateAuthority,
Expand All @@ -45,7 +46,8 @@ public ParameterizedBotFrameworkAuthentication(
ServiceClientCredentialsFactory credentialsFactory,
AuthenticationConfiguration authConfiguration,
IHttpClientFactory httpClientFactory,
ILogger logger)
ILogger logger,
ConnectorClientOptions connectorClientOptions = default)
{
_validateAuthority = validateAuthority;
_toChannelFromBotLoginUrl = toChannelFromBotLoginUrl;
Expand All @@ -59,6 +61,7 @@ public ParameterizedBotFrameworkAuthentication(
_authConfiguration = authConfiguration;
_httpClientFactory = httpClientFactory;
_logger = logger ?? NullLogger.Instance;
_connectorClientOptions = connectorClientOptions;
}

public override string GetOriginatingAudience()
Expand All @@ -79,7 +82,7 @@ public override async Task<AuthenticateRequestResult> AuthenticateRequestAsync(A

var callerId = await GenerateCallerIdAsync(_credentialsFactory, claimsIdentity, _callerId, cancellationToken).ConfigureAwait(false);

var connectorFactory = new ConnectorFactoryImpl(BuiltinBotFrameworkAuthentication.GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _toChannelFromBotLoginUrl, _validateAuthority, _credentialsFactory, _httpClientFactory, _logger);
var connectorFactory = new ConnectorFactoryImpl(BuiltinBotFrameworkAuthentication.GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _toChannelFromBotLoginUrl, _validateAuthority, _credentialsFactory, _httpClientFactory, _logger, _connectorClientOptions);

return new AuthenticateRequestResult { ClaimsIdentity = claimsIdentity, Audience = outboundAudience, CallerId = callerId, ConnectorFactory = connectorFactory };
}
Expand All @@ -102,7 +105,7 @@ public override async Task<AuthenticateRequestResult> AuthenticateStreamingReque

public override ConnectorFactory CreateConnectorFactory(ClaimsIdentity claimsIdentity)
{
return new ConnectorFactoryImpl(BuiltinBotFrameworkAuthentication.GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _toChannelFromBotLoginUrl, _validateAuthority, _credentialsFactory, _httpClientFactory, _logger);
return new ConnectorFactoryImpl(BuiltinBotFrameworkAuthentication.GetAppId(claimsIdentity), _toChannelFromBotOAuthScope, _toChannelFromBotLoginUrl, _validateAuthority, _credentialsFactory, _httpClientFactory, _logger, _connectorClientOptions);
}

public override async Task<UserTokenClient> CreateUserTokenClientAsync(ClaimsIdentity claimsIdentity, CancellationToken cancellationToken)
Expand All @@ -111,7 +114,7 @@ public override async Task<UserTokenClient> CreateUserTokenClientAsync(ClaimsIde

var credentials = await _credentialsFactory.CreateCredentialsAsync(appId, _toChannelFromBotOAuthScope, _toChannelFromBotLoginUrl, _validateAuthority, cancellationToken).ConfigureAwait(false);

return new UserTokenClientImpl(appId, credentials, _oAuthUrl, _httpClientFactory?.CreateClient(), _logger);
return new UserTokenClientImpl(appId, credentials, _oAuthUrl, _httpClientFactory?.CreateClient(), _logger, _connectorClientOptions);
}

public override BotFrameworkClient CreateBotFrameworkClient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.Bot.Connector.Authentication
{
internal class PublicCloudBotFrameworkAuthentication : BuiltinBotFrameworkAuthentication
{
public PublicCloudBotFrameworkAuthentication(ServiceClientCredentialsFactory credentialFactory, AuthenticationConfiguration authConfiguration, IHttpClientFactory httpClientFactory, ILogger logger)
public PublicCloudBotFrameworkAuthentication(ServiceClientCredentialsFactory credentialFactory, AuthenticationConfiguration authConfiguration, IHttpClientFactory httpClientFactory, ILogger logger, ConnectorClientOptions connectorClientOptions = default)
: base(
AuthenticationConstants.ToChannelFromBotOAuthScope,
AuthenticationConstants.ToChannelFromBotLoginUrlTemplate,
Expand All @@ -19,7 +19,8 @@ public PublicCloudBotFrameworkAuthentication(ServiceClientCredentialsFactory cre
credentialFactory,
authConfiguration,
httpClientFactory,
logger)
logger,
connectorClientOptions)
{
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ public UserTokenClientImpl(
ServiceClientCredentials credentials,
string oauthEndpoint,
HttpClient httpClient,
ILogger logger)
ILogger logger,
ConnectorClientOptions connectorClientOptions = default)
{
_appId = appId;
_httpClient = httpClient ?? new HttpClient();
ConnectorClient.AddDefaultRequestHeaders(_httpClient);
ConnectorClient.AddUserAgent(_httpClient, connectorClientOptions?.UserAgent);
_client = new OAuthClient(credentials, _httpClient, true) { BaseUri = new Uri(oauthEndpoint) };
_logger = logger ?? NullLogger.Instance;
}
Expand Down
23 changes: 23 additions & 0 deletions libraries/Microsoft.Bot.Connector/ConnectorClientEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,29 @@ public static string GetClientVersion<T>(T client)
return assembly.GetName().Version.ToString();
}

/// <summary>
/// Configures an HTTP client to include default headers for the Bot Framework.
/// </summary>
/// <param name="httpClient">The HTTP client to configure.</param>
/// <param name="userAgent">user agent.</param>
public static void AddUserAgent(HttpClient httpClient, string userAgent)
{
if (httpClient == null)
{
return;
}

if (string.IsNullOrEmpty(userAgent))
{
return;
}

lock (httpClient)
{
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent);
}
}

/// <summary>
/// Configures an HTTP client to include default headers for the Bot Framework.
/// </summary>
Expand Down
19 changes: 19 additions & 0 deletions libraries/Microsoft.Bot.Connector/ConnectorClientOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Connector
{
/// <summary>
/// A class representing the options for <see cref="Microsoft.Bot.Connector.ConnectorClient"/>.
/// </summary>
public class ConnectorClientOptions
{
/// <summary>
/// Gets or sets the user agent when sending the request.
/// </summary>
/// <value>
/// The user agent.
/// </value>
public string UserAgent { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Skills;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Configuration;
Expand All @@ -28,7 +29,8 @@ public class ConfigurationBotFrameworkAuthentication : BotFrameworkAuthenticatio
/// <param name="authConfiguration">An <see cref="AuthenticationConfiguration"/> instance.</param>
/// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/> to use.</param>
/// <param name="logger">The ILogger instance to use.</param>
public ConfigurationBotFrameworkAuthentication(IConfiguration configuration, ServiceClientCredentialsFactory credentialsFactory = null, AuthenticationConfiguration authConfiguration = null, IHttpClientFactory httpClientFactory = null, ILogger logger = null)
/// <param name="connectorClientOptions">The <see cref="ConnectorClientOptions"/> to use when creating <see cref="ConnectorClient"/>.</param>
public ConfigurationBotFrameworkAuthentication(IConfiguration configuration, ServiceClientCredentialsFactory credentialsFactory = null, AuthenticationConfiguration authConfiguration = null, IHttpClientFactory httpClientFactory = null, ILogger logger = null, ConnectorClientOptions connectorClientOptions = default)
{
var channelService = configuration.GetSection("ChannelService")?.Value;
var validateAuthority = configuration.GetSection("ValidateAuthority")?.Value;
Expand All @@ -53,7 +55,8 @@ public ConfigurationBotFrameworkAuthentication(IConfiguration configuration, Ser
credentialsFactory ?? new ConfigurationServiceClientCredentialFactory(configuration),
authConfiguration ?? new AuthenticationConfiguration(),
httpClientFactory,
logger);
logger,
connectorClientOptions);
}

/// <inheritdoc />
Expand Down
Loading
Loading