Exemple #1
0
        public async Task GetToken()
        {
            var tenantId = TestEnvironment.ServicePrincipalTenantId;
            var clientId = TestEnvironment.ServicePrincipalClientId;
            var secret   = TestEnvironment.ServicePrincipalClientSecret;

            var options = InstrumentClientOptions(new TokenCredentialOptions());

            var credential = new ClientSecretCredential(tenantId, clientId, secret, options);

            var tokenRequestContext = new TokenRequestContext(new[] { AzureAuthorityHosts.GetDefaultScope(AzureAuthorityHosts.AzurePublicCloud) });

            // ensure we can initially acquire a  token
            AccessToken token = await credential.GetTokenAsync(tokenRequestContext);

            Assert.IsNotNull(token.Token);

            // ensure subsequent calls before the token expires are served from the token cache
            AccessToken cachedToken = await credential.GetTokenAsync(tokenRequestContext);

            Assert.AreEqual(token.Token, cachedToken.Token);

            // ensure new credentials don't share tokens from the cache
            var credential2 = new ClientSecretCredential(tenantId, clientId, secret, options);

            AccessToken token2 = await credential2.GetTokenAsync(tokenRequestContext);

            if (Mode != RecordedTestMode.Playback && Mode != RecordedTestMode.None)
            {
                Assert.AreNotEqual(token.Token, token2.Token);
            }
        }
Exemple #2
0
        public async Task VerifyClientSecretRequestFailedAsync()
        {
            var response = new MockResponse(400);

            response.SetContent($"{{ \"error_code\": \"InvalidSecret\", \"message\": \"The specified client_secret is incorrect\" }}");

            var mockTransport = new MockTransport(response);

            var options = new TokenCredentialOptions()
            {
                Transport = mockTransport
            };

            var expectedTenantId = Guid.NewGuid().ToString();

            var expectedClientId = Guid.NewGuid().ToString();

            var expectedClientSecret = "secret";

            ClientSecretCredential client = InstrumentClient(new ClientSecretCredential(expectedTenantId, expectedClientId, expectedClientSecret, options));

            Assert.ThrowsAsync <AuthenticationFailedException>(async() => await client.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            await Task.CompletedTask;
        }
        //MSAL doesn't cache Service Principal into msal.cache
        public override Task <IAccessToken> Authenticate(AuthenticationParameters parameters, CancellationToken cancellationToken)
        {
            var spParameters = parameters as ServicePrincipalParameters;
            var onPremise    = spParameters.Environment.OnPremise;
            var tenantId     = onPremise ? AdfsTenant :
                               (string.Equals(parameters.TenantId, OrganizationsTenant, StringComparison.OrdinalIgnoreCase) ? null : parameters.TenantId);
            var resource  = spParameters.Environment.GetEndpoint(spParameters.ResourceId) ?? spParameters.ResourceId;
            var scopes    = AuthenticationHelpers.GetScope(onPremise, resource);
            var clientId  = spParameters.ApplicationId;
            var authority = spParameters.Environment.ActiveDirectoryAuthority;

            var requestContext = new TokenRequestContext(scopes);

            var options = new ClientCertificateCredentialOptions()
            {
                AuthorityHost = new Uri(authority)
            };

            if (!string.IsNullOrEmpty(spParameters.Thumbprint))
            {
                //Service Principal with Certificate
                ClientCertificateCredential certCredential;
                if (!ClientCertCredentialMap.TryGetValue(spParameters.ApplicationId, out certCredential))
                {
                    //first time login
                    var certificate = AzureSession.Instance.DataStore.GetCertificate(spParameters.Thumbprint);
                    certCredential = new ClientCertificateCredential(tenantId, spParameters.ApplicationId, certificate, options);
                    var tokenTask = certCredential.GetTokenAsync(requestContext, cancellationToken);
                    return(MsalAccessToken.GetAccessTokenAsync(tokenTask,
                                                               () => { ClientCertCredentialMap[spParameters.ApplicationId] = certCredential; },
                                                               spParameters.TenantId,
                                                               spParameters.ApplicationId));
                }
                else
                {
                    var tokenTask = certCredential.GetTokenAsync(requestContext, cancellationToken);
                    return(MsalAccessToken.GetAccessTokenAsync(tokenTask, spParameters.TenantId, spParameters.ApplicationId));
                }
            }
            else if (spParameters.Secret != null)
            {
                // service principal with secret
                var secretCredential = new ClientSecretCredential(tenantId, spParameters.ApplicationId, spParameters.Secret.ConvertToString(), options);
                var tokenTask        = secretCredential.GetTokenAsync(requestContext, cancellationToken);
                return(MsalAccessToken.GetAccessTokenAsync(
                           tokenTask,
                           spParameters.TenantId,
                           spParameters.ApplicationId));
            }
            else
            {
                throw new MsalException(MsalError.AuthenticationFailed, string.Format(AuthenticationFailedMessage, clientId));
            }
        }
        public async Task UsesTenantIdHint(
            [Values(null, TenantIdHint)] string tenantId,
            [Values(true)] bool allowMultiTenantAuthentication)
        {
            TestSetup();
            var context = new TokenRequestContext(new[] { Scope }, tenantId: tenantId);

            expectedTenantId = TenantIdResolver.Resolve(TenantId, context);
            ClientSecretCredential client = InstrumentClient(new ClientSecretCredential(expectedTenantId, ClientId, "secret", options, null, mockConfidentialMsalClient));

            var token = await client.GetTokenAsync(new TokenRequestContext(MockScopes.Default));

            Assert.AreEqual(token.Token, expectedToken, "Should be the expected token value");
        }
Exemple #5
0
        public void GetTokenIncorrectPassword()
        {
            var tenantId = TestEnvironment.ServicePrincipalTenantId;
            var clientId = TestEnvironment.ServicePrincipalClientId;
            var secret   = "badsecret";

            var options = InstrumentClientOptions(new TokenCredentialOptions());

            var credential = new ClientSecretCredential(tenantId, clientId, secret, options);

            var tokenRequestContext = new TokenRequestContext(new[] { AzureAuthorityHosts.GetDefaultScope(AzureAuthorityHosts.AzurePublicCloud) });

            // ensure we can initially acquire a  token
            Assert.ThrowsAsync <AuthenticationFailedException>(async() => await credential.GetTokenAsync(tokenRequestContext));
        }
        public async Task VerifyClientSecretCredentialRequestAsync()
        {
            var response = new MockResponse(200);

            var expectedToken = "mock-msi-access-token";

            response.SetContent($"{{ \"access_token\": \"{expectedToken}\", \"expires_in\": 3600 }}");

            var mockTransport = new MockTransport(response);

            var options = new TokenCredentialOptions()
            {
                Transport = mockTransport
            };

            var expectedTenantId = Guid.NewGuid().ToString();

            var expectedClientId = Guid.NewGuid().ToString();

            var expectedClientSecret = "secret";

            ClientSecretCredential client = InstrumentClient(new ClientSecretCredential(expectedTenantId, expectedClientId, expectedClientSecret, options));

            AccessToken actualToken = await client.GetTokenAsync(new TokenRequestContext(MockScopes.Default));

            Assert.AreEqual(expectedToken, actualToken.Token);

            MockRequest request = mockTransport.SingleRequest;

            Assert.IsTrue(request.Content.TryComputeLength(out long contentLen));

            var content = new byte[contentLen];

            await request.Content.WriteToAsync(new MemoryStream(content), default);

            Assert.IsTrue(TryParseFormEncodedBody(content, out Dictionary <string, string> parsedBody));

            Assert.IsTrue(parsedBody.TryGetValue("response_type", out string responseType) && responseType == "token");

            Assert.IsTrue(parsedBody.TryGetValue("grant_type", out string grantType) && grantType == "client_credentials");

            Assert.IsTrue(parsedBody.TryGetValue("client_id", out string actualClientId) && actualClientId == expectedClientId);

            Assert.IsTrue(parsedBody.TryGetValue("client_secret", out string actualClientSecret) && actualClientSecret == "secret");

            Assert.IsTrue(parsedBody.TryGetValue("scope", out string actualScope) && actualScope == MockScopes.Default.ToString());
        }
Exemple #7
0
        public async Task GetToken()
        {
            var tenantId = TestEnvironment.ServicePrincipalTenantId;
            var clientId = TestEnvironment.ServicePrincipalClientId;
            var secret   = TestEnvironment.ServicePrincipalClientSecret;

            var cache   = new MemoryTokenCache();
            var options = InstrumentClientOptions(new ClientSecretCredentialOptions()
            {
                TokenCachePersistenceOptions = cache
            });

            var credential = InstrumentClient(new ClientSecretCredential(tenantId, clientId, secret, options));

            var tokenRequestContext = new TokenRequestContext(new[] { AzureAuthorityHosts.GetDefaultScope(new Uri(TestEnvironment.AuthorityHostUrl)) });

            // ensure we can initially acquire a  token
            AccessToken token = await credential.GetTokenAsync(tokenRequestContext);

            Assert.IsNotNull(token.Token);
            Assert.That(cache.CacheReadCount, Is.Not.Zero);
            Assert.That(cache.CacheUpdatedCount, Is.Not.Zero);

            // ensure subsequent calls before the token expires are served from the token cache
            AccessToken cachedToken = await credential.GetTokenAsync(tokenRequestContext);

            Assert.AreEqual(token.Token, cachedToken.Token);

            var options2 = InstrumentClientOptions(new ClientSecretCredentialOptions());

            // ensure new credentials don't share tokens from the cache
            var credential2 = new ClientSecretCredential(tenantId, clientId, secret, options2);

            AccessToken token2 = await credential2.GetTokenAsync(tokenRequestContext);

            if (Mode != RecordedTestMode.Playback && Mode != RecordedTestMode.None)
            {
                Assert.AreNotEqual(token.Token, token2.Token);
            }
        }
        public async Task TestGetAzureAdTokenAndAuthenticate()
        {
            var credential = new ClientSecretCredential(TestTenantId, TestClientId, TestClientSecret);

            ConfigurationManager <OpenIdConnectConfiguration> configManager = new ConfigurationManager <OpenIdConnectConfiguration>(
                "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration",
                new OpenIdConnectConfigurationRetriever()
                );
            var keys = configManager.GetConfigurationAsync().Result.SigningKeys;

            var p = new TokenValidationParameters()
            {
                ValidateLifetime = true,
                ValidateAudience = false,

                IssuerValidator = (string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
                {
                    if (issuer.StartsWith(IssuerEndpoint))
                    {
                        return(IssuerEndpoint);
                    }
                    throw new SecurityTokenInvalidIssuerException();
                },

                ValidateIssuerSigningKey = true,
                IssuerSigningKeys        = keys,
            };

            var handler = new JwtSecurityTokenHandler();

            IdentityModelEventSource.ShowPII = true;

            var accessToken = await credential.GetTokenAsync(new TokenRequestContext(DefaultScopes));

            var claims = handler.ValidateToken(accessToken.Token, p, out var validToken);

            Assert.NotNull(validToken);
        }
        public async Task VerifyClientSecretCredentialExceptionAsync()
        {
            string expectedInnerExMessage = Guid.NewGuid().ToString();

            var mockAadClient = new MockAadIdentityClient(() => { throw new MockClientException(expectedInnerExMessage); });

            ClientSecretCredential credential = InstrumentClient(new ClientSecretCredential(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), CredentialPipeline.GetInstance(null), mockAadClient));

            var ex = Assert.ThrowsAsync <AuthenticationFailedException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            Assert.IsNotNull(ex.InnerException);

            Assert.IsInstanceOf(typeof(MockClientException), ex.InnerException);

            Assert.AreEqual(expectedInnerExMessage, ex.InnerException.Message);

            await Task.CompletedTask;
        }