/// <summary>
        /// Generate a Kerberos Ticket Claim string.
        /// </summary>
        /// <param name="servicePrincipalName">Service principal name to use.</param>
        /// <param name="ticketContainer">Ticket container to use.</param>
        /// <returns>A Kerberos Ticket Claim string if valid service principal name was given. Empty string, otherwise.</returns>
        internal static string GetKerberosTicketClaim(string servicePrincipalName, KerberosTicketContainer ticketContainer)
        {
            if (string.IsNullOrEmpty(servicePrincipalName))
            {
                return(string.Empty);
            }

            if (ticketContainer == KerberosTicketContainer.IdToken)
            {
                return(string.Format(
                           CultureInfo.InvariantCulture,
                           IdTokenAsRepTemplate,
                           servicePrincipalName));
            }

            return(string.Format(
                       CultureInfo.InvariantCulture,
                       AccessTokenAsRepTemplate,
                       servicePrincipalName));
        }
示例#2
0
 /// <summary>
 /// Sets the parameters required to get a Kerberos Ticket from Azure AD service.
 /// </summary>
 /// <param name="servicePrincipalName">Service principal name to get Kerberos Service Ticket.</param>
 /// <param name="ticketContainer">Container to use for Kerberos Ticket.</param>
 /// <returns>The builder to chain the .With methods</returns>
 public PublicClientApplicationBuilder WithKerberosTicketClaim(string servicePrincipalName, KerberosTicketContainer ticketContainer)
 {
     Config.KerberosServicePrincipalName = servicePrincipalName;
     Config.TicketContainer = ticketContainer;
     return(this);
 }
        /// <summary>
        /// Parse the command line arguments and set internal parameters with supplied value.
        /// </summary>
        /// <param name="args">List of commandline arguments.</param>
        /// <returns>True if argument parsing completed. False, if there's an error detected.</returns>
        public bool ParseCommandLineArguments(string[] args)
        {
            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].Equals("-tenantId", StringComparison.OrdinalIgnoreCase) && (i + 1) < args.Length)
                {
                    _tenantId = args[++i];
                }
                else if (args[i].Equals("-clientId", StringComparison.OrdinalIgnoreCase) && (i + 1) < args.Length)
                {
                    _clientId = args[++i];
                }
                else if (args[i].Equals("-spn", StringComparison.OrdinalIgnoreCase) && (i + 1) < args.Length)
                {
                    _kerberosServicePrincipalName = args[++i];
                }
                else if (args[i].Equals("-container", StringComparison.OrdinalIgnoreCase) && (i + 1) < args.Length)
                {
                    ++i;
                    if (args[i].Equals("id", StringComparison.OrdinalIgnoreCase))
                    {
                        _ticketContainer = KerberosTicketContainer.IdToken;
                    }
                    else if (args[i].Equals("access", StringComparison.OrdinalIgnoreCase))
                    {
                        _ticketContainer = KerberosTicketContainer.AccessToken;
                    }
                    else
                    {
                        Console.WriteLine("Unknown ticket container type '" + args[i] + "'");
                        ShowUsages();
                        return(false);
                    }
                }
                else if (args[i].Equals("-redirectUri", StringComparison.OrdinalIgnoreCase) && (i + 1) < args.Length)
                {
                    _redirectUri = args[++i];
                }
                else if (args[i].Equals("-scopes", StringComparison.OrdinalIgnoreCase) && (i + 1) < args.Length)
                {
                    _publicAppScopes = args[++i].Split(' ');
                }
                else if (args[i].Equals("-cached", StringComparison.OrdinalIgnoreCase))
                {
                    _isReadFromCache = true;
                }
                else if (args[i].Equals("-luid", StringComparison.OrdinalIgnoreCase))
                {
                    ++i;
                    try
                    {
                        _logonId = long.Parse(args[i], NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("-luid should be a long number or HEX format string!");
                        Console.WriteLine(ex);
                        return(false);
                    }
                }
                else if (args[i].Equals("-upn", StringComparison.OrdinalIgnoreCase))
                {
                    i++;
                    _Username = args[i];
                }
                else if (args[i].Equals("-password", StringComparison.OrdinalIgnoreCase))
                {
                    i++;
                    _UserPassword = args[i];
                }
                else if (args[i].Equals("-devicecodeflow", StringComparison.OrdinalIgnoreCase))
                {
                    _isDeviceCodeFlow = true;
                }
                else
                {
                    ShowUsages();
                    return(false);
                }
            }

            return(true);
        }
        private async Task <AuthenticationResult> KerberosRunTestForUserAsync(
            LabResponse labResponse,
            KerberosTicketContainer ticketContainer)
        {
            HttpSnifferClientFactory factory = null;
            IPublicClientApplication pca     = PublicClientApplicationBuilder
                                               .Create(labResponse.App.AppId)
                                               .WithRedirectUri(SeleniumWebUI.FindFreeLocalhostRedirectUri())
                                               .WithAuthority(labResponse.Lab.Authority + "common")
                                               .WithTestLogging(out factory)
                                               .WithTenantId(labResponse.Lab.TenantId)
                                               .WithClientId(TestConstants.KerberosTestApplicationId)
                                               .WithKerberosTicketClaim(TestConstants.KerberosServicePrincipalName, ticketContainer)
                                               .Build();

            var userCacheAccess = pca.UserTokenCache.RecordAccess();

            Trace.WriteLine("Part 1 - Acquire a token interactively, no login hint");
            AuthenticationResult result = await pca
                                          .AcquireTokenInteractive(s_scopes)
                                          .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.SelectAccount, false, false))
                                          .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token)
                                          .ConfigureAwait(false);

            Assert.IsTrue(result.AuthenticationResultMetadata.DurationTotalInMs > 0);
            Assert.IsTrue(result.AuthenticationResultMetadata.DurationInHttpInMs > 0);

            KerberosSupplementalTicket ticket = TestCommon.GetValidatedKerberosTicketFromAuthenticationResult(
                result,
                ticketContainer,
                labResponse.User.Upn);

            Assert.IsNotNull(ticket);

            userCacheAccess.AssertAccessCounts(0, 1);
            IAccount account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(1, 1); // the assert calls GetAccounts
            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);

            Trace.WriteLine("Part 2 - Clear the cache");
            await pca.RemoveAsync(account).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(1, 2);
            Assert.IsFalse((await pca.GetAccountsAsync().ConfigureAwait(false)).Any());
            userCacheAccess.AssertAccessCounts(2, 2);
            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);

            if (factory?.RequestsAndResponses != null)
            {
                factory.RequestsAndResponses.Clear();
            }

            Trace.WriteLine("Part 3 - Acquire a token interactively again, with login hint");
            result = await pca
                     .AcquireTokenInteractive(s_scopes)
                     .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.ForceLogin, true, false))
                     .WithPrompt(Prompt.ForceLogin)
                     .WithLoginHint(labResponse.User.Upn)
                     .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token)
                     .ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(2, 3);
            AssertCcsRoutingInformationIsSent(factory, labResponse);
            ticket = TestCommon.GetValidatedKerberosTicketFromAuthenticationResult(
                result,
                ticketContainer,
                labResponse.User.Upn);
            Assert.IsNotNull(ticket);

            account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(3, 3);
            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);

            if (factory?.RequestsAndResponses != null)
            {
                factory.RequestsAndResponses.Clear();
            }

            Trace.WriteLine("Part 4 - Acquire a token silently");
            result = await pca
                     .AcquireTokenSilent(s_scopes, account)
                     .ExecuteAsync(CancellationToken.None)
                     .ConfigureAwait(false);

            ticket = TestCommon.GetValidatedKerberosTicketFromAuthenticationResult(
                result,
                ticketContainer,
                labResponse.User.Upn);
            Assert.IsNotNull(ticket);

            Trace.WriteLine("Part 5 - Acquire a token silently with force refresh");
            result = await pca
                     .AcquireTokenSilent(s_scopes, account)
                     .WithForceRefresh(true)
                     .ExecuteAsync(CancellationToken.None)
                     .ConfigureAwait(false);

            await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);
            AssertCcsRoutingInformationIsSent(factory, labResponse);

            ticket = TestCommon.GetValidatedKerberosTicketFromAuthenticationResult(
                result,
                ticketContainer,
                labResponse.User.Upn);
            Assert.IsNotNull(ticket);
            TestCommon.ValidateKerberosWindowsTicketCacheOperation(ticket);

            return(result);
        }
示例#5
0
        /// <summary>
        /// Get a Kerberos Ticket contained in the given <see cref="AuthenticationResult"/> object.
        /// </summary>
        /// <param name="authResult">An <see cref="AuthenticationResult"/> object to get Kerberos Ticket from.</param>
        /// <param name="container">The <see cref="KerberosTicketContainer"/> indicating the token where the Kerberos Ticket stored.</param>"
        /// <param name="userUpn">UPN of the client.</param>
        /// <returns>A <see cref="KerberosSupplementalTicket"/> if there's valid one.</returns>
        public static KerberosSupplementalTicket GetValidatedKerberosTicketFromAuthenticationResult(AuthenticationResult authResult,
                                                                                                    KerberosTicketContainer container,
                                                                                                    string userUpn)
        {
            if (container == KerberosTicketContainer.IdToken)
            {
                ValidateNoKerberosTicketFromToken(authResult.AccessToken);
                return(GetValidatedKerberosTicketFromToken(authResult.IdToken, userUpn));
            }

            ValidateNoKerberosTicketFromToken(authResult.IdToken);
            return(GetValidatedKerberosTicketFromToken(authResult.AccessToken, userUpn));
        }
        private async Task KerberosAcquireTokenWithDeviceCodeFlowAsync(LabResponse labResponse, string userType, KerberosTicketContainer ticketContainer)
        {
            Trace.WriteLine($"Calling KerberosAcquireTokenWithDeviceCodeFlowAsync with {0}", userType);
            var builder = PublicClientApplicationBuilder.Create(labResponse.App.AppId)
                          .WithTestLogging()
                          .WithTenantId(labResponse.Lab.TenantId)
                          .WithClientId(TestConstants.KerberosTestApplicationId)
                          .WithKerberosTicketClaim(TestConstants.KerberosServicePrincipalName, ticketContainer);

            switch (labResponse.User.AzureEnvironment)
            {
            case AzureEnvironment.azureusgovernment:
                builder.WithAuthority(labResponse.Lab.Authority + labResponse.Lab.TenantId);
                break;

            default:
                break;
            }

            var pca             = builder.Build();
            var userCacheAccess = pca.UserTokenCache.RecordAccess();

            var result = await pca.AcquireTokenWithDeviceCode(s_scopes, deviceCodeResult =>
            {
                SeleniumExtensions.PerformDeviceCodeLogin(deviceCodeResult, labResponse.User, TestContext, false);
                return(Task.FromResult(0));
            }).ExecuteAsync(CancellationToken.None).ConfigureAwait(false);

            Trace.WriteLine("Running asserts");

            userCacheAccess.AssertAccessCounts(0, 1);
            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);

            Assert.IsNotNull(result);
            Assert.IsTrue(!string.IsNullOrEmpty(result.AccessToken));

            KerberosSupplementalTicket ticket = TestCommon.GetValidatedKerberosTicketFromAuthenticationResult(
                result,
                ticketContainer,
                labResponse.User.Upn);

            Assert.IsNotNull(ticket);
            TestCommon.ValidateKerberosWindowsTicketCacheOperation(ticket);
        }