microsoft/teams.net

Public

mirrored from https://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v2.0.7

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/src/Microsoft.Teams.Core/Hosting/BotConfig.cs

98lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using Microsoft.Extensions.Configuration;
5using Microsoft.Extensions.DependencyInjection;
6using Microsoft.Extensions.Logging;
7
8namespace Microsoft.Teams.Core.Hosting;
9
10/// <summary>
11/// Configuration model for bot authentication credentials, sourced from a
12/// Microsoft.Identity.Web compatible configuration section (e.g. "AzureAd").
13/// </summary>
14public sealed class BotConfig
15{
16 internal const string DefaultSectionName = "AzureAd";
17
18 /// <summary>
19 /// Gets or sets the Azure AD tenant ID.
20 /// </summary>
21 public string TenantId { get; set; } = string.Empty;
22
23 /// <summary>
24 /// Gets or sets the application (client) ID from Azure AD app registration.
25 /// </summary>
26 public string ClientId { get; set; } = string.Empty;
27
28 /// <summary>
29 /// Gets or sets the configuration section name used to resolve this BotConfig.
30 /// Also used as the MSAL named-options key and the JWT auth scheme name.
31 /// </summary>
32 public string SectionName { get; set; } = DefaultSectionName;
33
34 internal IConfigurationSection? MsalConfigurationSection { get; set; }
35
36 /// <summary>
37 /// Gets a value indicating whether this configuration uses User-Assigned Managed Identity (UMI) for authentication.
38 /// Returns true when no ClientCredentials are configured in the section.
39 /// </summary>
40 internal bool IsUserAssignedManagedIdentity =>
41 MsalConfigurationSection is not null &&
42 !MsalConfigurationSection.GetSection("ClientCredentials").GetChildren().Any();
43
44 /// <summary>
45 /// Resolves a BotConfig from a service collection by extracting configuration and logger.
46 /// </summary>
47 /// <param name="services">The service collection containing IConfiguration and ILoggerFactory registrations.</param>
48 /// <param name="sectionName">The configuration section name. Defaults to "AzureAd".</param>
49 /// <returns>A BotConfig populated from the section, or an empty BotConfig if no ClientId is configured.</returns>
50 public static BotConfig Resolve(IServiceCollection services, string sectionName = DefaultSectionName)
51 {
52 ArgumentNullException.ThrowIfNull(services);
53
54 // Extract IConfiguration from service collection — prefer the instance if available,
55 // otherwise resolve via the factory registered in the descriptor.
56 ServiceDescriptor? configDescriptor = services.FirstOrDefault(d => d.ServiceType == typeof(IConfiguration));
57 IConfiguration? configuration = configDescriptor?.ImplementationInstance as IConfiguration;
58 if (configuration is null && configDescriptor?.ImplementationFactory is not null)
59 {
60 using ServiceProvider tempProvider = services.BuildServiceProvider();
61 configuration = tempProvider.GetService<IConfiguration>();
62 }
63
64 if (configuration is null)
65 {
66 throw new InvalidOperationException(
67 "IConfiguration must be registered in the service collection before calling BotConfig.Resolve. " +
68 "Ensure AddConfiguration() or WebApplication.CreateBuilder() has been called.");
69 }
70
71 ILogger logger = AddBotApplicationExtensions.GetLoggerFromServices(services, typeof(BotConfig));
72
73 IConfigurationSection section = configuration.GetSection(sectionName);
74 BotConfig config = new()
75 {
76 TenantId = section["TenantId"] ?? string.Empty,
77 ClientId = section["ClientId"] ?? string.Empty,
78 MsalConfigurationSection = section,
79 SectionName = sectionName
80 };
81
82 if (!string.IsNullOrEmpty(config.ClientId))
83 {
84 _logUsingSectionConfig(logger, sectionName, null);
85 }
86 else
87 {
88 _logNoConfigFound(logger, null);
89 }
90 return config;
91 }
92
93 private static readonly Action<ILogger, string, Exception?> _logUsingSectionConfig =
94 LoggerMessage.Define<string>(LogLevel.Debug, new(3), "Resolved bot configuration from '{SectionName}' configuration section");
95 private static readonly Action<ILogger, Exception?> _logNoConfigFound =
96 LoggerMessage.Define(LogLevel.Warning, new(4), "No bot configuration found in configuration.");
97
98}
99