private static void RegisterAuthenticationServicesWithCertificate(
     IServiceCollection services,
     IConfiguration configuration,
     AuthenticationOptions authenticationOptions,
     AzureADOptions azureADOptions)
 {
     services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
     .AddMicrosoftIdentityWebApi(
         options =>
     {
         options.Authority = $"{azureADOptions.Instance}{azureADOptions.TenantId}/v2.0";
         options.SaveToken = true;
         options.TokenValidationParameters.ValidAudiences    = AuthenticationServiceCollectionExtensions.GetValidAudiences(authenticationOptions);
         options.TokenValidationParameters.AudienceValidator = AuthenticationServiceCollectionExtensions.AudienceValidator;
         options.TokenValidationParameters.ValidIssuers      = AuthenticationServiceCollectionExtensions.GetValidIssuers(authenticationOptions);
     },
         microsoftIdentityOptions =>
     {
         configuration.Bind("AzureAd", microsoftIdentityOptions);
         microsoftIdentityOptions.ClientCertificates = new CertificateDescription[]
         {
             CertificateDescription.FromKeyVault(configuration.GetValue <string>("KeyVault:Url"), configuration.GetValue <string>("GraphAppCertName")),
         };
     })
     .EnableTokenAcquisitionToCallDownstreamApi(
         confidentialClientApplicationOptions =>
     {
         configuration.Bind("AzureAd", confidentialClientApplicationOptions);
     })
     .AddInMemoryTokenCaches();
 }
예제 #2
0
        public void TestFromKeyVault(string keyVaultUrl, string certificateName)
        {
            CertificateDescription certificateDescription = CertificateDescription.FromKeyVault(keyVaultUrl, certificateName);

            Assert.Equal(CertificateSource.KeyVault, certificateDescription.SourceType);
            Assert.Equal(keyVaultUrl, certificateDescription.Container);
            Assert.Equal(certificateName, certificateDescription.ReferenceOrValue);
            Assert.Equal(certificateName, certificateDescription.KeyVaultCertificateName);
            Assert.Equal(keyVaultUrl, certificateDescription.KeyVaultUrl);
        }
예제 #3
0
        public void TestFromKeyVault(string keyVaultUrl, string certificateName)
        {
            CertificateDescription certificateDescription = CertificateDescription.FromKeyVault(keyVaultUrl, certificateName);

            Assert.Equal(CertificateSource.KeyVault, certificateDescription.SourceType);
            Assert.Equal(keyVaultUrl, certificateDescription.Container);
            Assert.Equal(certificateName, certificateDescription.ReferenceOrValue);
            Assert.Equal(certificateName, certificateDescription.KeyVaultCertificateName);
            Assert.Equal(keyVaultUrl, certificateDescription.KeyVaultUrl);
            Assert.Equal(X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.EphemeralKeySet, certificateDescription.X509KeyStorageFlags);
            certificateDescription.X509KeyStorageFlags = X509KeyStorageFlags.UserKeySet;
            Assert.Equal(X509KeyStorageFlags.UserKeySet, certificateDescription.X509KeyStorageFlags);
        }
        public void TestDefaultCertificateLoader(CertificateSource certificateSource, string container, string referenceOrValue)
        {
            CertificateDescription certificateDescription;

            switch (certificateSource)
            {
            case CertificateSource.KeyVault:
                certificateDescription = CertificateDescription.FromKeyVault(container, referenceOrValue);
                break;

            case CertificateSource.Base64Encoded:
                certificateDescription = CertificateDescription.FromBase64Encoded(referenceOrValue);
                break;

            case CertificateSource.Path:
                certificateDescription = CertificateDescription.FromPath(container, referenceOrValue);
                break;

            case CertificateSource.StoreWithThumbprint:
                certificateDescription = new CertificateDescription()
                {
                    SourceType = CertificateSource.StoreWithThumbprint
                };
                certificateDescription.CertificateThumbprint = referenceOrValue;
                certificateDescription.CertificateStorePath  = container;
                break;

            case CertificateSource.StoreWithDistinguishedName:
                certificateDescription = new CertificateDescription()
                {
                    SourceType = CertificateSource.StoreWithDistinguishedName
                };
                certificateDescription.CertificateDistinguishedName = referenceOrValue;
                certificateDescription.CertificateStorePath         = container;
                break;

            default:
                certificateDescription = null;
                break;
            }

            ICertificateLoader loader = new DefaultCertificateLoader();

            loader.LoadIfNeeded(certificateDescription);

            Assert.NotNull(certificateDescription.Certificate);
        }
        static async Task Main(string[] args)
        {
            string clientId = "6af093f3-b445-4b7a-beae-046864468ad6";
            string tenant   = "msidentitysamplestesting.onmicrosoft.com";

            string[] scopes = new[] { "api://8206b76f-586e-4098-b1e5-598c1aa3e2a1/.default" };

            // Simulates the configuration, could be a IConfiguration or anything
            Dictionary <string, string> Configuration = new Dictionary <string, string>();

            // Certificate Loading
            string keyVaultContainer = "https://WebAppsApisTests.vault.azure.net";
            string keyVaultReference = "Self-Signed-5-5-22";
            CertificateDescription certDescription   = CertificateDescription.FromKeyVault(keyVaultContainer, keyVaultReference);
            ICertificateLoader     certificateLoader = new DefaultCertificateLoader();

            certificateLoader.LoadIfNeeded(certDescription);

            // Create the confidential client application
            IConfidentialClientApplication app;

            app = ConfidentialClientApplicationBuilder.Create(clientId)
                  // Alternatively to the certificate you can use .WithClientSecret(clientSecret)
                  .WithCertificate(certDescription.Certificate)
                  .WithTenantId(tenant)
                  .Build();

            //  In memory token caches (App and User caches)
            // app.AddInMemoryTokenCache();

            // Or

            // Distributed token caches (App and User caches)
            // Add one of the below: SQL, Redis, CosmosDb
            app.AddDistributedTokenCache(services =>
            {
                services.AddDistributedMemoryCache();
                services.AddLogging(configure => configure.AddConsole())
                .Configure <LoggerFilterOptions>(options => options.MinLevel = Microsoft.Extensions.Logging.LogLevel.Debug);

                /* Remove comments to use SQL cache implementation
                 * services.AddDistributedSqlServerCache(options =>
                 * {
                 *  // SQL Server token cache
                 *  // Requires to reference Microsoft.Extensions.Caching.SqlServer
                 *  options.ConnectionString = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=TestCache;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False";
                 *  options.SchemaName = "dbo";
                 *  options.TableName = "TestCache";
                 *
                 *  // You don't want the SQL token cache to be purged before the access token has expired. Usually
                 *  // access tokens expire after 1 hour (but this can be changed by token lifetime policies), whereas
                 *  // the default sliding expiration for the distributed SQL database is 20 mins.
                 *  // Use a value which is above 60 mins (or the lifetime of a token in case of longer lived tokens)
                 *  options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
                 * });
                 */

                /* Remove comments to use Redis cache implementation
                 * // Add Redis
                 * services.AddStackExchangeRedisCache(options =>
                 * {
                 *  options.Configuration = "localhost";
                 *  options.InstanceName = "Redis";
                 * });
                 */

                /* Remove comments to use CosmosDB cache implementation
                 * // Add CosmosDB
                 * services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
                 * {
                 *  cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
                 *  cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
                 *  cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
                 *  cacheOptions.CreateIfNotExists = true;
                 * });
                 */
            });

            // Acquire a token (twice)
            var result = await app.AcquireTokenForClient(scopes)
                         .ExecuteAsync();

            Console.WriteLine(result.AuthenticationResultMetadata.TokenSource);

            result = await app.AcquireTokenForClient(scopes)
                     .ExecuteAsync();

            Console.WriteLine(result.AuthenticationResultMetadata.TokenSource);
        }