private static void ValidateNtlmResponse(HttpContext context, string password,
                                                 NtlmAuthenticationMessage authMessage, byte[] challenge)
        {
            var hexExpectNtlmRes = authMessage.NtlmResponseData.BytesToHex();
            var hexNtlmRes       = NtlmResponses.GetNtlmResponse(password, challenge).BytesToHex();

            if (!hexExpectNtlmRes.Equals(hexNtlmRes, StringComparison.InvariantCultureIgnoreCase))
            {
                SendUnauthorized(context);
            }
            else
            {
                MarkAsLogon(context);
            }
        }
        private static void ValidateNtlmV2Response(HttpContext context, string userName, string password,
                                                   NtlmAuthenticationMessage authMessage, byte[] challenge)
        {
            var expectHmac    = authMessage.NtlmResponseData.NewCopy(0, 16);
            var expectBlob    = authMessage.NtlmResponseData.NewCopy(16);
            var hexExpectHmac = expectHmac.BytesToHex();

            var actualHmac = NtlmResponses.GetNtlmV2ResponseHash(
                authMessage.TargetName, userName, password, expectBlob, challenge);
            var hexActualHmac = actualHmac.BytesToHex();

            if (!hexExpectHmac.Equals(hexActualHmac, StringComparison.InvariantCultureIgnoreCase))
            {
                SendUnauthorized(context);
            }
            else
            {
                MarkAsLogon(context);
            }
        }
        public static void CheckNtlmAuth(this HttpContext context, string userName, string password, Action <string> log)
        {
            MakeIdentity(context);

            if (CheckLogon(context))
            {
                return;
            }

            var auth = context.Request.Headers["Authorization"];

            if (string.IsNullOrWhiteSpace(auth) || !auth.StartsWith("NTLM"))
            {
                SendUnauthorized(context);
            }
            else
            {
                var base64 = auth.Substring(5); //skip "NTLM "
                var token  = Convert.FromBase64String(base64);
                var header = token.ToStruct <MessageHeaderStruct>();

                switch (header.Type)
                {
                case MessageType.Negotiation:
                    var message1 = NtlmNegotiateMessage.Parse(token);
                    SendChallengeMessage(context, message1, log);
                    break;

                case MessageType.Authentication:
                    var message3 = new NtlmAuthenticationMessage(token);
                    ValidateAuthMessage(context, userName, password, message3, log);
                    break;

                default:
                    SendUnauthorized(context);
                    break;
                }
            }
        }
        private static void ValidateAuthMessage(HttpContext context, string userName, string password,
                                                NtlmAuthenticationMessage authMessage, Action <string> log)
        {
            log($"Message 3 Flags: {authMessage.Flags}");
            log($"Message 3 UserName: {authMessage.UserName}");
            log($"Message 3 HostName: {authMessage.HostName}");
            log($"Message 3 TargetName: {authMessage.TargetName}");

            if (authMessage.UserName.Equals(userName, StringComparison.InvariantCultureIgnoreCase))
            {
                if (authMessage.Message.NtlmResponseLength == 24)
                {
                    ValidateNtlmResponse(context, password, authMessage, Challenge);
                }
                else
                {
                    ValidateNtlmV2Response(context, userName, password, authMessage, Challenge);
                }
            }
            else
            {
                SendUnauthorized(context);
            }
        }