// Initialize status code
int statusCode = HttpServletResponse.SC_UNAUTHORIZED;
//Authentication Processes
AuthenticationProcessImpl authenticationProcessCls = null;
KerberosAuthenticationProcess krbAuthN =
new KerberosAuthenticationProcess();
//Initialize cookies vars
Cookie gsaRefererCookie = null;
Cookie gsaAuthCookie = null;
//Session Cookie arrays
Vector<Cookie> krbCookies = new Vector<Cookie>();
Vector<Cookie> nonKrbCookies = new Vector<Cookie>();
//user agent
String userAgent = null;
//user credentials
Credentials creds = null;
//User Session and Session ID vars definition
UserSession userSession = null;
String sessionID = null;
String encodedSessionID = null;
//Create the credentials store
try {
this.valveConf =
ValveConfigurationInstance.getValveConfig(gsaValveConfigPath);
} catch (ValveConfigurationException e) {
logger.error("Valve Config instantiation error: " + e);
}
logger.debug("Creating the credentials store");
creds = new Credentials();
String username = null;
//Setting Valve parameters
logger.debug("Setting Valve params");
setValveParams(request);
//Protection
if ((!isKerberos) || (!isNegotiate)) {
logger.error("Configuration error: if you want to use Kerberos silent AuthN, isKerberos and isNegotiate config vars have to be set to true");
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Configuration error - Kerberos is not set properly");
return;
}
Cookie cookies[] = null;
// Retrieve cookies
cookies = request.getCookies();
// Protection: look for auth and referer cookies
if (cookies != null) {
// Look for the referer cookie
for (int i = 0; i < cookies.length; i++) {
// Look for the referer cookie
if ((cookies[i].getName()).equals(refererCookieName)) {
// Cache cookie
gsaRefererCookie = cookies[i];
logger.debug("Referer cookie already exists: " +
gsaRefererCookie.getValue());
} else {
// Look for the auth cookie
if ((cookies[i].getName()).equals(authCookieName)) {
// Cache cookie
gsaAuthCookie = cookies[i];
logger.debug("Auth cookie already exists: " +
gsaAuthCookie.getValue());
}
}
if ((gsaRefererCookie != null) && (gsaAuthCookie != null)) {
// Exit
break;
}
}
}
// Protection
if (!isSAML) {
if (gsaRefererCookie == null) {
// Raise error
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"The GSA authentication servlet couldn't read the referer cookie");
// Log error
logger.error("The GSA authentication servlet couldn't read the referer cookie, pls. check the cookie domain value");
// Return
return;
}
} else {
//SAML
//Get SAML Params
relayState = request.getParameter("RelayState");
samlRequest = request.getParameter("SAMLRequest");
//String relayStateCookie = valveConf.getSAMLConfig().getRelayStateCookie();
boolean noParams = false;
boolean cookieExist = true;
//Protection
if ((relayState == null) || (relayState.equals(""))) {
noParams = true;
} else {
if ((samlRequest == null) || (samlRequest.equals(""))) {
noParams = true;
}
}
createRefererCookie(gsaRefererCookie);
//if ((noParams)&&(!cookieExist)) {
if (noParams) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid request");
return;
}
}
logger.debug("Let's validate if gsaAuthCookie is present");
if (gsaAuthCookie != null) {
if (!isSAML) {
//redirect
String redirect = gsaRefererCookie.getValue();
logger.debug("redirect is " + redirect);
//redirect only if the URL is different than the login one
if (!redirect.equals(loginUrl)) {
//user properly authenticated
logger.debug("The user was properly authenticated. Lets redirect to..." +
redirect);
// Redirect
response.sendRedirect(redirect);
} else {
logger.debug("It's the login URL. No redirect");
}
} else {
logger.debug("As this is SAML. Let's obviate the previous authentication cookie");
gsaAuthCookie = null;
}
}
userSession = new UserSession();
Sessions sessions = Sessions.getInstance();
sessions.setMaxSessionAgeMinutes(maxSessionAge);
sessions.setSessionTimeoutMinutes(sessionTimeout);
if (gsaAuthCookie == null) {
logger.debug("gsaAuthCookie does not exist");
isNegotiate = true;
// Read User-Agent header
userAgent = request.getHeader("User-Agent");
logger.debug("userAgent is... " + userAgent);
//check if user is gsa-crawler
if (userAgent.startsWith(GSA_CRAWLER_USER)) {
logger.debug("User is " + GSA_CRAWLER_USER);
//check if user is gsa-crawler and have to authenticate it thru a form
if (KrbUsrPwdCrawler) {
logger.debug("gsa-crawler has to access thru username and password");
//check if crawler already provided credentials
if (request.getParameter("UserIDKrb") == null) {
//the login page have to be filled in by the admin user before reaching here. Return error
logger.error("The login page [" + KrbUsrPwdCrawlerUrl +
"] has to be invoked and its credentials fields filled in before reaching here");
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"It means the GSA Valve Kerberos configuration is not done properly or you just forgot to fill in the Kerberos credentials in the login page");
return;
} else {
//user already submits credentials
logger.debug("Crawler has already sent credentials");
//set isNegotiate equal false (it authenticates the user thru username and pwd credentials)
isNegotiate = false;
//set Crawler credentials
setCrawlerCredentials(request, creds, KrbAdditionalAuthN);
//authenticate user
statusCode =
krbAuthentication(request, response,
krbAuthN, krbCookies,
gsaRefererCookie.getValue(),
creds, isNegotiate);
// Protection: check status code
if (statusCode != HttpServletResponse.SC_OK) {
// Raise error
response.sendError(statusCode,
"Authentication process failed!");
// Debug
if (logger.isDebugEnabled())
logger.debug("Krb Authentication process failed with code: " +
statusCode);
if (statusCode ==
HttpServletResponse.SC_UNAUTHORIZED) {
logger.debug("Note: this 401 could not be an error as sending 401 could be part of the Negotiation process");
}
// Return
return;
}
//check if the additional authN method is available. If so, start authN with these creds as well
//N: modification for always lanching the root authN process. Comment out the following line
//if (KrbAdditionalAuthN) {
statusCode =
nonKrbAuthentication(request, response,
authenticationProcessCls, nonKrbCookies,
gsaRefererCookie.getValue(),
creds);
//check if the status code is indeterminate
if (statusCode == -1) {
//the process could not determinate the authorization
//as there is no pattern that matches with any repository
statusCode = HttpServletResponse.SC_UNAUTHORIZED;
}
// Protection: check status code
if (statusCode != HttpServletResponse.SC_OK) {
// Raise error
response.sendError(statusCode,
"Authentication process failed!");
// Debug
if (logger.isDebugEnabled())
logger.debug("Non Krb Authentication process failed with code: " +
statusCode);
// Return
return;
}
//}
}
} else { // end KrbUsrPwdCrawler is set.
//If KrbUsrPwdCrawler is not set to true, then do nothing (assume content is feeded)
//just send back the error as a configuration one (we shouldn't configure Froms-based crawling)
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Configuration error. Review your configuration as you can not define this rule if it's not set properly (see doc on how to set it up using Kerberos config attributes)");
return;
}
} else { //User is not Crawler
logger.debug("User is NOT crawler");
//check if we have double AuthN or not
if (!KrbAdditionalAuthN) {
logger.debug("Krb silent authN only");
//set isNegotiate equal true (it authenticates the user thru kerberos ticket)
isNegotiate = true;
String refererCookieValue = null;
if (gsaRefererCookie != null) {
refererCookieValue = new String (gsaRefererCookie.getValue());
}
//authenticate user
statusCode =
krbAuthentication(request, response,
krbAuthN, krbCookies,
refererCookieValue,
creds, isNegotiate);
// Protection: check status code
if (statusCode != HttpServletResponse.SC_OK) {
// Raise error
response.sendError(statusCode,
"Authentication process failed!");
// Debug
if (logger.isDebugEnabled())
logger.debug("Krb Authentication process failed with code: " +
statusCode);
if (statusCode ==
HttpServletResponse.SC_UNAUTHORIZED) {
logger.debug("Note: this 401 could not be an error as sending 401 could be part of the Negotiation process");
}
// Return
return;
} else {
boolean doesKrbSubjectExist = lookForKrbCreds(creds);
if (!doesKrbSubjectExist) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Credentials not valid. Try to close your browser and try it again");
// Log error
logger.error("Kerberos Subject is not present when authenticating");
// Return
return;
}
//N: call rootAuthN once we have the Kerberos creds
//N: Begin update
if (!KrbAdditionalAuthN) {
statusCode =
nonKrbAuthentication(request, response,
authenticationProcessCls,
nonKrbCookies,
refererCookieValue,
creds);
//check if the status code is indeterminate
if (statusCode == -1) {
//the process could not determinate the authorization
//as there is no pattern that matches with any repository
statusCode =
HttpServletResponse.SC_UNAUTHORIZED;
}
// Protection: check status code
if (statusCode != HttpServletResponse.SC_OK) {
// Raise error
response.sendError(statusCode,
"Authentication process failed!");
// Debug
if (logger.isDebugEnabled())
logger.debug("Non Krb Authentication process failed with code: " +
statusCode);
// Return
return;
}
}
//N:End update
}
} else { //Double AuthN required. So that apart from the Krb silent authN, we authN the user as well thru username and pwd
logger.debug("Krb and Forms based AuthN mechanisms");
//check if Krb credentials are already set
Cookie gsaKrbCookie = getCookie(request, KRB_COOKIE_NAME);
//if (gsaKrbCookie != null) { //Kerberos cookie set
if (!isKrbProcess(gsaKrbCookie)) { //Kerberos cookie set
logger.debug("Krb cookie is set. Krb AuthN already in place");
Subject krbSubj =
getKrbSubject(gsaKrbCookie.getValue());
//Protection
if (krbSubj ==
null) { // couldn't localize the subject.
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Credentials not valid. Try to close your browser and try it again");
// Log error
logger.error("Kerberos Subject is not present when authenticating");
// Return
return;
} else {
logger.debug("The Krb subject exists. This is the Forms based AuthN part");
//check if parameters are present
if (request.getParameter("UserIDKrb") == null) {
logger.debug("Login page has not been already invoked");
String redirectUrl = contructKrbLoginURL();
logger.debug("Redirecting to...." +
redirectUrl);
//redirect to the login page
response.sendRedirect(response.encodeRedirectURL(redirectUrl));
// Return
return;
} else {
//user already submits credentials
logger.debug("User has already sent credentials");
createCredsDoubleAuthN(request, creds, krbSubj);
logger.debug("User Credentials created. Let's authenticate the user without Krb");
statusCode =
nonKrbAuthentication(request, response,
authenticationProcessCls,
nonKrbCookies,
gsaRefererCookie.getValue(),
creds);
//check if the status code is indeterminate
if (statusCode == -1) {
//the process could not determinate the authorization
//as there is no pattern that matches with any repository
statusCode =
HttpServletResponse.SC_UNAUTHORIZED;
}
// Protection: check status code
if (statusCode != HttpServletResponse.SC_OK) {
// Raise error
response.sendError(statusCode,
"Authentication process failed!");
// Debug
if (logger.isDebugEnabled())
logger.debug("Non Krb Authentication process failed with code: " +
statusCode);
// Return
return;
}
boolean resultDelete =
deleteKrbSubject(gsaKrbCookie.getValue());
if (!resultDelete) {
logger.error("Not KrbSubj found when deleting it");
}
}
}
} else { //Krb cookie does not exist
logger.debug("Krb cookie does not exist. Let's silently authenticate the user thru Krb firstly");
logger.debug("Krb silent authN only");
//set isNegotiate equal true (it authenticates the user thru kerberos ticket)
isNegotiate = true;
//authenticate user
statusCode =
krbAuthentication(request, response,
krbAuthN, krbCookies,
gsaRefererCookie.getValue(),
creds, isNegotiate);
// Protection: check status code
if (statusCode != HttpServletResponse.SC_OK) {
// Raise error
response.sendError(statusCode,
"Authentication process failed!");
// Debug
if (logger.isDebugEnabled())
logger.debug("Krb Authentication process failed with code: " +
statusCode);
if (statusCode ==
HttpServletResponse.SC_UNAUTHORIZED) {
logger.debug("Note: this 401 could not be an error as sending 401 could be part of the Negotiation process");
}
// Return
return;
} else {
Cookie krbCookie = krbCookies.elementAt(0);
String krbAuthCookieValue = krbCookie.getValue();
logger.debug("Krb cookie value: " +
krbAuthCookieValue);
if (krbAuthCookieValue == null) {
logger.error("Krb cookie not present");
// Raise error
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Kerberos cookie not present");
// Return
return;
} else {
addKrbCookie(response, krbCookie);
addKrbSubject(krbAuthCookieValue,
krbAuthN.getUserSubject());
logger.debug("The User Krb identity is already present. Let's authenticate the user thru username/password");
//redirect to Login page
String redirectUrl = contructKrbLoginURL();
response.sendRedirect(response.encodeRedirectURL(redirectUrl));
logger.debug("Redirect to.... " + redirectUrl);