Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IE sends empty POST body randomly while using NTLM authentication (using angular to Spring)

We are seeing issues with seemingly random calls that are missing the POST in IE 11. Upon further inspection the requests from the browser are including a NTLM negotiation token. We see this token on GETs too from time to time, but they are unaffected by the body problem as they don't have one. Chrome and FF do not have this problem.

Further investigation shows that if our session times out and the browser is re-authed, then we will consistently see this problem after that at around 1 - 2 minute intervals. It is my understanding that if IE "expects" a 401, then it will not include the POST body as is expects the NTLM handshake to take place again.

We have an angular app (currently mixed Angular 1 and 2, but occurred in 1 just before this). The angular app makes restful webservice calls to our Spring boot application. We are using waffle for NTLM auth

// Shiro-Waffle / Security
'com.github.dblock.waffle:waffle-parent:1.7.3',
'com.github.dblock.waffle:waffle-shiro:1.7.3',
'org.apache.shiro:shiro-core:1.2.3',
'org.apache.shiro:shiro-web:1.2.3',

https://blogs.msdn.microsoft.com/ieinternals/2010/11/21/challenge-response-authentication-and-zero-length-posts/

I have one crappy workaround that I will post below as an answer, but I do not like it at all.

like image 812
Chewy Avatar asked Dec 01 '16 18:12

Chewy


1 Answers

I have created a shiro filter that I put as the last filter in the chain (Groovy)

package com.security.shiro

import com.security.AuthenticateTrait
import com.ws.RemoteUserAccessor
import com.ws.RequestAccessor

import javax.servlet.ServletRequest
import javax.servlet.ServletResponse

/**
 * Created by esarrazin on 11/30/2016.
 */
class IEBugFilter3 extends NegotiateAuthenticationFilter implements RemoteUserAccessor, AuthenticateTrait, RequestAccessor {

/**
 * Returns <code>false</code> If the giant piece of sh1t IE chooses to think that it will need to re-authenticate
 * and not send the body to us.  Here we will deny access (as IE expects - big turd) and have waffle re-negotiate
 * this useless sh1t-bag.  Then and only then will IE choose to give us the body of the POST.  This problem is intermittent
 * and there is no telling when IE will use its infinite wisdom to do this, so please don't think if you comment this
 * out it is still working without.
 *
 * Not a silver bullet, but here is a link to some reading about this:
 * https://blogs.msdn.microsoft.com/ieinternals/2010/11/21/challenge-response-authentication-and-zero-length-posts/
 *
 * @return Returns true if isAccessAllowed
 */
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        !isRequestExpectingToReAuth(request, response)
}

private boolean isRequestExpectingToReAuth(ServletRequest request, ServletResponse response) {
    if (request?.request?.request?.coyoteRequest?.methodMB == 'POST' && toHttp(request).getHeader('content-length') == '0') {
        System.out.println("Found the dreaded zero length body and attempting to recover from it. $request.remoteHost")
        return true
    }

    return false
}

}

Our NegotiateAuthenticationFilter extends waffle.shiro.negotiate.NegotiateAuthenticationFilter and is pretty straight forward.

This sees the empty body POST request coming across (forgive the request?.request garbage - not prod ready) and denies access, thus giving IE what it expects. Since we are denying access, a 401 goes across and the handshake begins. Then when the 200 is presented IE releases the body and we are AOK. But this is crap- albeit a solution.

like image 157
Chewy Avatar answered Oct 24 '22 04:10

Chewy