سؤال

What we have?

  1. Client : win8, ie11, logged in into system using domain credentials.

  2. Server : 3 tomcat7 nodes run beyond apache 2.2.22. application uses waffle library to authenticate windows users who are logged in into domain in sso manner.

  3. Application uses spring security and the main thing regarding this topic is that filter that handles login via form comes before filter that handles authentication headers.

  4. NegotiateSecurityFilterProvider supports only Negotiate protocol, not NTLM

What we do?

  1. Go into application via direct link : https://app.domain.com/app_name/subordinates.do. It is ok, we are bearing valid kerberos header (it is good and big one kerberos token which fiddler describes as 'Authorization Header (Negotiate) appears to contain a kerberos ticket' ^^) and waffle on application side passes us inside with kerberos reply.

  2. Logout.

  3. Login via form on login page: we make post request with user_name and password, again we bearing same kerberos token. Application uses user_name and password to login us with help of waffle WindowsAuthenticationProvider. Here we get authenticate before we rich NegotiateSecurityFilter, so there is no any kerberos header within reply from server. Anyway everything is ok.

Now we are log into MS account via OS. And magic happens.

When trying to login via direct link we get 'The handle specified is invalid' error on login page as SPRING_SECURITY_LAST_EXCEPTION constant. my guess here is that we send some kind of invalid authorization header

And when trying to login via form we get 'The parameter is incorrect'. here i think we send ntlm type 1 POST request with empty body but we still have invalid header so application does not recognize it and does not sent 401 reply and thereafter waffle sends null name to AD and here error comes (just guess)

BUT when I turn fiddler on to see what is really happened then everything begins to work fine as before login into MS account.
Ok, to figure out what header are sent to the server I used some code inside cmd file:

UDPATED add code and output

    var cookieContainer = new CookieContainer();
    var authRequest = (HttpWebRequest) WebRequest.Create("https://app.domain.com/app_name/home.do");
    var credentials = CredentialCache.DefaultNetworkCredentials;
    authRequest.Credentials = credentials;
    authRequest.CookieContainer = cookieContainer;
    authRequest.AllowAutoRedirect = false;
    var authResponse = (HttpWebResponse)authRequest.GetResponse();
    Console.WriteLine("Request headers:");
    foreach (string header in authRequest.Headers.AllKeys) {
        Console.WriteLine("\t{0}: {1}", header, authRequest.Headers.Get(header));
    }
    Console.WriteLine("\nResponse: {0} {1}", (int)authResponse.StatusCode, authResponse.StatusDescription);
    Console.WriteLine("Response headers:");
    foreach (string header in authResponse.Headers)
    Console.WriteLine("\t{0}: {1}", header, authResponse.GetResponseHeader(header));
    foreach (var cookie in cookieContainer.GetCookies(new Uri("https://app.domain.com/app_name/")))
    Console.WriteLine("Received cookie: {0}", cookie);
    Console.WriteLine("\nPress ENTER to exit");
    Console.ReadLine();

Here what I get:

    Request headers:
        Authorization: Negotiate oTMwMaADCgEBoioEKE5UTE1TU1AAAQAAAJeCCOIAAAAAAAAAAAAAAAAAAAAABgOAJQAAAA8=
        Host: {host}
        Cookie: JSESSIONID={sessionId}
    Response: 302 Found
    Response headers:
        Vary: Accept-Encoding
        Content-Length: 0
        Content-Type: text/ plain; charset=UTF-8
        Date: Tue, 04 Feb 2014 11:44:15 GMT
        Location: https://app.domain.com/app_name/login.do?error_code=1
        Server: Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/0.9.8t mod_jk/1.2.37
    Received cookie: JSESSIONID={sessionId}

It is definitely much smaller header than kerberos one what fiddler sees when authentication works.

So questions are:
1. Why does loging into MS account affect what headers are sent to server?
2. Why it begins to work when fiddler on?
3. What type of this header : Negotiate oTMwMaADCgEBoioEKE5UTE1TU1AAAQAAAJeCCOIAAAAAAAAAAAAAAAAAAAAABgOAJQAAAA8= and how should it be handled by server?

UPDATE 17 March 2014: wireshark capture shows KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN error after tgs request, server mentioned - machine name with apache. After investigation with support team we found out that special user which is used to run tomcat servers on different nodes didn't have spn for domain name of machine with apache (it had spn for resource domain name but not for current machine). After spn was added problem disappeared.

هل كانت مفيدة؟

المحلول

After decoding oTMwMaADCgEBoioEKE5UTE1TU1AAAQAAAJeCCOIAAAAAAAAAAAAAAAAAAAAABgOAJQAAAA8= we can see that it contains NTLMSSP (a new version).

Check browsers configuration: In Internet Explorer: webpage should be in "Local intranet" zone (in a zone in which user is logged automatically) and that IWA, Integrated Windows Authentication is enabled.

If that's not the case, please take a look in Wireshark for dns and kerberos packets.

Check DNS: IE uses dns to resolve webserver address into principal name. CNAME address is resolved into A address. If not found, IE will not ask for Kerberos service ticket at all (and will fallback to NTLM).

Check SPNs: When Active Directory can't find requested principal (or there or two, or more). Then IE falls back into NTLM.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top