private IConfidentialClientApplication GetOrCreateApplication() { if (_application == null) { lock (_applicationSyncObj) { if (_application == null) { var options = new ConfidentialClientApplicationOptions() { ClientId = AppServicesAuthenticationInformation.ClientId, ClientSecret = AppServicesAuthenticationInformation.ClientSecret, Instance = AppServicesAuthenticationInformation.Issuer, }; _application = ConfidentialClientApplicationBuilder.CreateWithApplicationOptions(options) .WithHttpClientFactory(_httpClientFactory) .Build(); _tokenCacheProvider.Initialize(_application.AppTokenCache); _tokenCacheProvider.Initialize(_application.UserTokenCache); } } } return(_application); }
/// <summary> /// Use a token cache and choose the serialization part by adding it to /// the services collection and configuring its options. /// </summary> /// <returns>The confidential client application.</returns> /// <param name="confidentialClientApp">Confidential client application.</param> /// <param name="initializeCaches">Action that you'll use to add a cache serialization /// to the service collection passed as an argument.</param> /// <returns>The application for chaining.</returns> /// <example> /// /// The following code adds a distributed in-memory token cache. /// /// <code> /// app.AddTokenCaches(services => /// { /// // In memory distributed token cache /// // In net472, requires to reference Microsoft.Extensions.Caching.Memory /// services.AddDistributedTokenCache(); /// services.AddDistributedMemoryCache(); /// }); /// </code> /// /// The following code adds a token cache based on REDIS and initializes /// its configuration. /// /// <code> /// app.AddTokenCaches(services => /// { /// services.AddDistributedTokenCache(); /// // Redis token cache /// // Requires to reference Microsoft.Extensions.Caching.StackExchangeRedis /// services.AddStackExchangeRedisCache(options => /// { /// options.Configuration = "localhost"; /// options.InstanceName = "Redis"; /// }); /// }); /// </code> /// If using distributed token caches, use AddDistributedTokenCache. /// </example> /// <remarks>Don't use this method in ASP.NET Core. Just add use the ConfigureServices method /// instead.</remarks> internal static IConfidentialClientApplication AddTokenCaches( this IConfidentialClientApplication confidentialClientApp, Action <IServiceCollection> initializeCaches) { _ = confidentialClientApp ?? throw new ArgumentNullException(nameof(confidentialClientApp)); _ = initializeCaches ?? throw new ArgumentNullException(nameof(initializeCaches)); // try to reuse existing XYZ cache if AddXYZCache was called before, to simulate ASP.NET Core var serviceProvider = s_serviceProviderFromAction.GetOrAdd(initializeCaches.Method, (m) => { lock (s_serviceProviderFromAction) { ServiceCollection services = new ServiceCollection(); initializeCaches(services); services.AddLogging(); return(services.BuildServiceProvider()); } }); IMsalTokenCacheProvider msalTokenCacheProvider = serviceProvider.GetRequiredService <IMsalTokenCacheProvider>(); msalTokenCacheProvider.Initialize(confidentialClientApp.UserTokenCache); msalTokenCacheProvider.Initialize(confidentialClientApp.AppTokenCache); return(confidentialClientApp); }
/// <summary> /// Creates an MSAL confidential client application. /// </summary> private IConfidentialClientApplication BuildConfidentialClientApplication() { var httpContext = CurrentHttpContext; var request = httpContext?.Request; string?currentUri = null; if (!string.IsNullOrEmpty(_applicationOptions.RedirectUri)) { currentUri = _applicationOptions.RedirectUri; } if (request != null && string.IsNullOrEmpty(currentUri)) { currentUri = BuildCurrentUriFromRequest(httpContext !, request); } PrepareAuthorityInstanceForMsal(); MicrosoftIdentityOptionsValidation.ValidateEitherClientCertificateOrClientSecret( _applicationOptions.ClientSecret, _microsoftIdentityOptions.ClientCertificates); try { var builder = ConfidentialClientApplicationBuilder .CreateWithApplicationOptions(_applicationOptions) .WithHttpClientFactory(_httpClientFactory) .WithLogging( Log, ConvertMicrosoftExtensionsLogLevelToMsal(_logger), enablePiiLogging: _applicationOptions.EnablePiiLogging) .WithExperimentalFeatures(); // The redirect URI is not needed for OBO if (!string.IsNullOrEmpty(currentUri)) { builder.WithRedirectUri(currentUri); } string authority; if (_microsoftIdentityOptions.IsB2C) { authority = $"{_applicationOptions.Instance}{ClaimConstants.Tfp}/{_microsoftIdentityOptions.Domain}/{_microsoftIdentityOptions.DefaultUserFlow}"; builder.WithB2CAuthority(authority); } else { authority = $"{_applicationOptions.Instance}{_applicationOptions.TenantId}/"; builder.WithAuthority(authority); } if (_microsoftIdentityOptions.ClientCertificates != null) { X509Certificate2?certificate = DefaultCertificateLoader.LoadFirstCertificate(_microsoftIdentityOptions.ClientCertificates); builder.WithCertificate(certificate); } IConfidentialClientApplication app = builder.Build(); _application = app; // Initialize token cache providers _tokenCacheProvider.Initialize(app.AppTokenCache); _tokenCacheProvider.Initialize(app.UserTokenCache); return(app); } catch (Exception ex) { _logger.LogInformation( ex, IDWebErrorMessage.ExceptionAcquiringTokenForConfidentialClient); throw; } }