SPNEGO Error 401 html message cannot be customized


The SPNEGO logic leads CAS to send a 401 status with a WWW-Authenticate: Negotiate header to the client. Unfortunately, if the browser is Firefox and this browser is misconfigured (eg. network.negotiate-auth.trusted-uris preference does not refer to CAS server URL) the client remains stuck on tomcat's default error message.
This message should be customizable, but actually, modifying web.xml is not sufficient.

I've tested one modification in class org.jasig.cas.support.spnego.web.flow.SpnegoNegociateCredentialsAction where sending 401 status code is done on line 82 by :


replaced by :

try {
} catch (IOException e) {

I got a half success :

  • If error page uses session : it fails with "cas unavailable"

  • If error page does not use session, the first call shows "cas unavailable", and next calls show the right error page.

I suspect nasty things between response.sendError() and context.getExternalContext().recordResponseComplete() calls.


debian squeeze, Java 1.6.0_34, Tomcat 7.0.29, Active Directory 2008R2 as authentication source (ldap + kerberos)


Antoni Alatalo
November 15, 2012, 5:36 AM

i've tested modified code. It works only, if browser has Spnego configuration. If not, view with unauthorized message is shown.

My solution works in any case (spnego is activated on server side and browser has or does not have spnego configuration):

New spnego-webflow.xml is created with:

login-webflow.xml is rewrited:

added to cas-servlet.xml:

There is no need any more for negotiate view in my case. All works like a sharm. Springs subflow does all work fine and returns request from negotiate action to spnego action.

Please check if solution works also for you.

Antoni Alatalo

Antoni Alatalo
December 7, 2012, 8:34 AM

previouse solution don't work in IE.

Please see new detailed documentation and suggestion here.

First of all requirements:
1. There must be Spnego and LDAP authentications
2. LDAP (username + password) should be shown always if spnego fails
3. Client browser can have Spnego enabled and browser can be without Spnego enabled
4. Spnego authentication must be in line with spring webflow: while performing Spnego flow must return to the previouse execution point.
5. NTLM is disabled

What does not work in current solution:
1. Spnego always returns to the start of flow (don't remember previouse execution point)
2. Spnego doesn't show login form if it's enabled in server side and not enabled in Browser (IE)
see http://lists.samba.org/archive/jcifs/2008-February/007661.html for reasons

Proposed solution:

Here is login-webflow.xml lines:


casNegotitateView is used to redirect user to proper action with flow id. If ntlm hader present, then redirect to login form, else redirect to external action to process Spnego authentication.

SpnegoController is used to send and receive Negotiate token


spnegoLoginView is used as a page where is form submitting on load if Negotiating doesn't work. If negotitating works, then form is not used.

spnegoAfterLoginView just rediects user back to the flow with flow id

In case when Negotiating is successfull, Spnego action is called. If spnego action fails, then it redirects to the spnegoReturnView view. This allows us form submitting in IE when Negotiating fails.

This is modification of SpnegoCredentialsAction class (see authorizationHeader extracting and last four lines):

Tehre are some other modifications to get SpnegoController to work:



This solution works for our needs. I'll do some refactorings on this proposed code, but the idea will stay.

Giorgio Ascani
May 17, 2013, 3:08 PM

Hi Antoni, thanks for your solution but I've got an error on spnegoLoginView when SpnegoController return spnegoLoginView without executionId parameter.


Then on page link:

execution is null and I've got the exception:

Can you help me to resolve the issue? Thanks.


John Gasper
September 23, 2013, 2:51 PM

Submitted pull request (https://github.com/Jasig/cas/pull/321) to make optional (invoked by parameter). This is not likely the ideal (and final) fix, but this fix allows CAS's SPNEGO users to use this module again.

This is a 3.5.x version.

John Gasper
September 23, 2013, 3:12 PM

Submitted https://github.com/Jasig/cas/pull/322 which is the 4.x version.


John Gasper


Philippe Marasse



Estimated End Date



Fix versions

Affects versions