if (reauthenticateFromSSO(ssoId, request)) {
return true;
}
}
MessageBytes authorization =
request.getCoyoteRequest().getMimeHeaders()
.getValue("authorization");
if (authorization == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("authenticator.noAuthHeader"));
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
authorization.toBytes();
ByteChunk authorizationBC = authorization.getByteChunk();
if (!authorizationBC.startsWithIgnoreCase("negotiate ", 0)) {
if (log.isDebugEnabled()) {
log.debug(sm.getString(
"spnegoAuthenticator.authHeaderNotNego"));
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
authorizationBC.setOffset(authorizationBC.getOffset() + 10);
byte[] decoded = Base64.decodeBase64(authorizationBC.getBuffer(),
authorizationBC.getOffset(),
authorizationBC.getLength());
if (decoded.length == 0) {
if (log.isDebugEnabled()) {
log.debug(sm.getString(
"spnegoAuthenticator.authHeaderNoToken"));
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
LoginContext lc = null;
GSSContext gssContext = null;
byte[] outToken = null;
try {
try {
lc = new LoginContext(getLoginConfigName());
lc.login();
} catch (LoginException e) {
log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"),
e);
response.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return false;
}
// Assume the GSSContext is stateless
// TODO: Confirm this assumption
final GSSManager manager = GSSManager.getInstance();
final PrivilegedExceptionAction<GSSCredential> action =
new PrivilegedExceptionAction<GSSCredential>() {
@Override
public GSSCredential run() throws GSSException {
return manager.createCredential(null,
GSSCredential.DEFAULT_LIFETIME,
new Oid("1.3.6.1.5.5.2"),
GSSCredential.ACCEPT_ONLY);
}
};
gssContext = manager.createContext(Subject.doAs(lc.getSubject(), action));
outToken = Subject.doAs(lc.getSubject(), new AcceptAction(gssContext, decoded));
if (outToken == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString(
"spnegoAuthenticator.ticketValidateFail"));
}
// Start again
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
principal = context.getRealm().authenticate(gssContext,
isStoreDelegatedCredential());
} catch (GSSException e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"), e);
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
} catch (PrivilegedActionException e) {
log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
} finally {
if (gssContext != null) {
try {
gssContext.dispose();
} catch (GSSException e) {
// Ignore
}
}
if (lc != null) {
try {
lc.logout();
} catch (LoginException e) {
// Ignore
}
}
}
// Send response token on success and failure
response.setHeader("WWW-Authenticate", "Negotiate "
+ Base64.encodeBase64String(outToken));
if (principal != null) {
register(request, response, principal, Constants.SPNEGO_METHOD,
principal.getName(), null);
Pattern p = noKeepAliveUserAgents;
if (p != null) {
MessageBytes ua =
request.getCoyoteRequest().getMimeHeaders().getValue(
"user-agent");
if (ua != null && p.matcher(ua.toString()).matches()) {
response.setHeader("Connection", "close");
}
}
return true;
}