/// <summary>
        /// Checks there's a Kerberos Ticket in current user's Windows Ticket Cache matched with the service principal name.
        /// If there's a valid ticket, then show the Ticket Information on the console.
        /// </summary>
        /// <returns></returns>
        public bool ShowCachedTicket()
        {
            try
            {
                byte[] ticket
                    = KerberosSupplementalTicketManager.GetKerberosTicketFromWindowsTicketCache(_kerberosServicePrincipalName, _logonId);
                if (ticket != null && ticket.Length > 32)
                {
                    var encode = Convert.ToBase64String(ticket);

                    AADKerberosLogger.PrintLines(2);
                    AADKerberosLogger.Save($"---Find cached Ticket: {ticket.Length} bytes");
                    AADKerberosLogger.PrintBinaryData(ticket);

                    TicketDecoder decoder = new TicketDecoder();
                    decoder.ShowApReqTicket(encode);
                    return(true);
                }

                Console.WriteLine($"There's no ticket associated with '{_kerberosServicePrincipalName}'");
            }
            catch (Win32Exception ex)
            {
                Console.WriteLine($"ERROR while finding Kerberos Ticket for '{_kerberosServicePrincipalName}': {ex.Message}");
            }
            return(false);
        }
        public void GetKrbCred()
        {
            KerberosSupplementalTicket ticket = KerberosSupplementalTicketManager.FromIdToken(_testIdTokenWithKerberosTicketClaim);

            byte[] krbCred = KerberosSupplementalTicketManager.GetKrbCred(ticket);

            Assert.IsNotNull(krbCred);
        }
Exemple #3
0
        private async Task AddBodyParamsAndHeadersAsync(
            IDictionary <string, string> additionalBodyParameters,
            string scopes,
            CancellationToken cancellationToken)
        {
            _oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientId, _requestParams.AppConfig.ClientId);

            if (_serviceBundle.Config.ClientCredential != null)
            {
                await _serviceBundle.Config.ClientCredential.AddConfidentialClientParametersAsync(
                    _oAuth2Client,
                    _requestParams.RequestContext.Logger,
                    _serviceBundle.PlatformProxy.CryptographyManager,
                    _requestParams.AppConfig.ClientId,
                    _requestParams.Authority.GetTokenEndpoint(),
                    _requestParams.SendX5C,
                    cancellationToken).ConfigureAwait(false);
            }

            _oAuth2Client.AddBodyParameter(OAuth2Parameter.Scope, scopes);

            // Add Kerberos Ticket claims if there's valid service principal name in Configuration.
            // Kerberos Ticket claim is only allowed at token request due to security issue.
            // It should not be included for authorize request.
            KerberosSupplementalTicketManager.AddKerberosTicketClaim(_oAuth2Client, _requestParams);

            foreach (var kvp in additionalBodyParameters)
            {
                _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value);
            }

            foreach (var kvp in _requestParams.AuthenticationScheme.GetTokenRequestParams())
            {
                _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value);
            }

            _oAuth2Client.AddHeader(
                TelemetryConstants.XClientCurrentTelemetry,
                _serviceBundle.HttpTelemetryManager.GetCurrentRequestHeader(
                    _requestParams.RequestContext.ApiEvent));

            if (!_requestInProgress)
            {
                _requestInProgress = true;

                _oAuth2Client.AddHeader(
                    TelemetryConstants.XClientLastTelemetry,
                    _serviceBundle.HttpTelemetryManager.GetLastRequestHeader());
            }

            //Signaling that the client can perform PKey Auth on supported platforms
            if (DeviceAuthHelper.CanOSPerformPKeyAuth())
            {
                _oAuth2Client.AddHeader(PKeyAuthConstants.DeviceAuthHeaderName, PKeyAuthConstants.DeviceAuthHeaderValue);
            }

            AddExtraHttpHeaders();
        }
        public void FromIdToken_WithKerberosTicket()
        {
            KerberosSupplementalTicket ticket = KerberosSupplementalTicketManager.FromIdToken(_testIdTokenWithKerberosTicketClaim);

            Assert.IsNotNull(ticket);
            Assert.IsTrue(string.IsNullOrEmpty(ticket.ErrorMessage));
            Assert.IsFalse(string.IsNullOrEmpty(ticket.KerberosMessageBuffer));
            Assert.AreEqual(_testServicePrincipalName, ticket.ServicePrincipalName, "Service principal name is not matched.");
            Assert.AreEqual(_testClientName, ticket.ClientName, "Client name is not matched.");
        }
Exemple #5
0
        /// <summary>
        /// Get a Kerberos Ticket contained in the given token.
        /// </summary>
        /// <param name="token">Token to be validated.</param>
        /// <param name="userUpn">UPN of the client.</param>
        /// <returns>A <see cref="KerberosSupplementalTicket"/> if there's valid one.</returns>
        public static KerberosSupplementalTicket GetValidatedKerberosTicketFromToken(string token, string userUpn)
        {
            KerberosSupplementalTicket ticket = KerberosSupplementalTicketManager.FromIdToken(token);

            Assert.IsNotNull(ticket, "Kerberos Ticket is not found.");
            Assert.IsTrue(string.IsNullOrEmpty(ticket.ErrorMessage), "Kerberos Ticket creation failed with: " + ticket.ErrorMessage);
            Assert.IsFalse(string.IsNullOrEmpty(ticket.KerberosMessageBuffer), "Kerberos Ticket data is not found.");
            Assert.IsTrue(ticket.KerberosMessageBuffer.Length > TestConstants.KerberosMinMessageBufferLength, "Received Kerberos Ticket data is too short.");
            Assert.AreEqual(KerberosKeyTypes.Aes256CtsHmacSha196, ticket.KeyType, "Kerberos key type is not matched.");
            Assert.AreEqual(TestConstants.KerberosServicePrincipalName, ticket.ServicePrincipalName, true, CultureInfo.InvariantCulture, "Service principal name is not matched.");
            Assert.AreEqual(userUpn, ticket.ClientName, true, CultureInfo.InvariantCulture, "Client name is not matched.");

            return(ticket);
        }
        /// <summary>
        /// Checks there's a valid Kerberos Ticket information within the received authentication token.
        /// If there's a valid one, show the ticket information and cache it into current user's
        /// Windows Ticket Cache so that it can be shared with other Kerberos-aware applications.
        /// </summary>
        /// <param name="result">The <see cref="AuthenticationResult"/> from token request.</param>
        private void ProcessKerberosTicket(AuthenticationResult result)
        {
            KerberosSupplementalTicket ticket;

            if (_ticketContainer == KerberosTicketContainer.IdToken)
            {
                // 1. Get the Kerberos Ticket contained in the Id Token.
                ticket = KerberosSupplementalTicketManager.FromIdToken(result.IdToken);
                if (ticket == null)
                {
                    AADKerberosLogger.Save("ERROR: There's no Kerberos Ticket information within the IdToken.");
                    return;
                }

                AADKerberosLogger.PrintLines(2);

                try
                {
                    // 2. Save the Kerberos Ticket into current user's Windows Ticket Cache.
                    KerberosSupplementalTicketManager.SaveToWindowsTicketCache(ticket, _logonId);
                    AADKerberosLogger.Save("---Kerberos Ticket cached into user's Ticket Cache\n");
                }
                catch (Win32Exception ex)
                {
                    AADKerberosLogger.Save("---Kerberos Ticket caching failed: " + ex.Message);
                }

                AADKerberosLogger.PrintLines(2);
                AADKerberosLogger.Save("KerberosSupplementalTicket {");
                AADKerberosLogger.Save("                Client Key: " + ticket.ClientKey);
                AADKerberosLogger.Save("                  Key Type: " + ticket.KeyType);
                AADKerberosLogger.Save("            Errorr Message: " + ticket.ErrorMessage);
                AADKerberosLogger.Save("                     Realm: " + ticket.Realm);
                AADKerberosLogger.Save("    Service Principal Name: " + ticket.ServicePrincipalName);
                AADKerberosLogger.Save("               Client Name: " + ticket.ClientName);
                AADKerberosLogger.Save("     KerberosMessageBuffer: " + ticket.KerberosMessageBuffer);
                AADKerberosLogger.Save("}\n");

                // shows detailed ticket information.
                TicketDecoder decoder = new TicketDecoder();
                decoder.ShowKrbCredTicket(ticket.KerberosMessageBuffer);
            }
            else
            {
                AADKerberosLogger.PrintLines(2);
                AADKerberosLogger.Save("Kerberos Ticket handling is not supported for access token.");
            }
        }
        public void GetKerberosTicketClaim_AccessToken()
        {
            string kerberosClaim
                = KerberosSupplementalTicketManager.GetKerberosTicketClaim(_testServicePrincipalName, KerberosTicketContainer.AccessToken);

            Assert.IsFalse(string.IsNullOrEmpty(kerberosClaim));

            JsonObject claim = JsonObject.Parse(kerberosClaim);

            Assert.IsNotNull(claim);

            Assert.IsTrue(claim.ContainsKey("access_token"));
            JsonObject accessToken = claim.GetNamedObject("access_token");

            Assert.IsNotNull(accessToken);

            CheckKerberosClaim(accessToken);
        }
Exemple #8
0
        /// <summary>
        /// Validates Windows Ticket Cache interface for the given <see cref="KerberosSupplementalTicket"/> Kerberos Ticket.
        /// </summary>
        /// <param name="ticket">A <see cref="KerberosSupplementalTicket"/> object to be checked.</param>
        public static void ValidateKerberosWindowsTicketCacheOperation(KerberosSupplementalTicket ticket)
        {
            if (DesktopOsHelper.IsWindows())
            {
                // First, save the given Kerberos Ticket (with KRB-CRED format) into the Windows Ticket Cache.
                // Windows Ticket Cache decrypts the given Kerberos Ticket with KRB-CRED format, re-encrypt with it's
                // credential and save it as AP-REQ format.
                KerberosSupplementalTicketManager.SaveToWindowsTicketCache(ticket);

                // Read-back saved Ticket data.
                byte[] ticketBytes
                    = KerberosSupplementalTicketManager.GetKerberosTicketFromWindowsTicketCache(ticket.ServicePrincipalName);
                Assert.IsNotNull(ticketBytes);

                // To validate public field of AP-REQ format Kerberos Ticket, convert binary ticket data as a printable string format.
                StringBuilder sb = new StringBuilder();
                foreach (byte ch in ticketBytes)
                {
                    if (ch >= 32 && ch < 127)
                    {
                        sb.Append((char)ch);
                    }
                    else
                    {
                        sb.Append('*');
                    }
                }
                string ticketAsString = sb.ToString();

                // Check the Azure AD Kerberos Realm string exists.
                Assert.IsTrue(ticketAsString.IndexOf(TestConstants.AzureADKerberosRealmName) >= 0);

                // Check the ticket has matched Kerberos Service Principal Name.
                Assert.IsTrue(ticketAsString.IndexOf(TestConstants.KerberosServicePrincipalNameEscaped, StringComparison.OrdinalIgnoreCase) >= 0);
            }
        }
        public void FromIdToken_WithoutKerberosTicket()
        {
            KerberosSupplementalTicket ticket = KerberosSupplementalTicketManager.FromIdToken(_testIdToken);

            Assert.IsNull(ticket);
        }
Exemple #10
0
        /// <summary>
        /// Validates there were no valid Kerberos Ticket contained in the given token.
        /// </summary>
        /// <param name="token">Token to be validated.</param>
        public static void ValidateNoKerberosTicketFromToken(string token)
        {
            KerberosSupplementalTicket ticket = KerberosSupplementalTicketManager.FromIdToken(token);

            Assert.IsNull(ticket, "Kerberos Ticket exists.");
        }