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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With