use of org.alfresco.repo.web.auth.UnknownCredentials in project alfresco-remote-api by Alfresco.
the class BaseNTLMAuthenticationFilter method processType3.
/**
* Process a type 3 NTLM message
*
* @param type3Msg Type3NTLMMessage
* @param req HttpServletRequest
* @param res HttpServletResponse
*
* @exception IOException
* @exception ServletException
*/
protected boolean processType3(Type3NTLMMessage type3Msg, ServletContext context, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
Log logger = getLogger();
if (logger.isDebugEnabled())
logger.debug("Received type3 " + type3Msg);
// Get the existing NTLM details
NTLMLogonDetails ntlmDetails = null;
SessionUser user = null;
user = getSessionUser(context, req, res, true);
HttpSession session = req.getSession();
ntlmDetails = (NTLMLogonDetails) session.getAttribute(NTLM_AUTH_DETAILS);
// Get the NTLM logon details
String userName = type3Msg.getUserName();
String workstation = type3Msg.getWorkstation();
String domain = type3Msg.getDomain();
// ALF-10997 fix, normalize the userName
// the system runAs is acceptable because we are resolving a username i.e. it's a system-wide operation that does not need permission checks
final String userName_f = userName;
String normalized = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<String>() {
public String execute() throws Throwable {
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<String>() {
public String doWork() throws Exception {
String normalized = personService.getUserIdentifier(userName_f);
return normalized;
}
}, AuthenticationUtil.SYSTEM_USER_NAME);
}
}, true);
if (normalized != null) {
userName = normalized;
}
boolean authenticated = false;
// Check if we are using cached details for the authentication
if (user != null && ntlmDetails != null && ntlmDetails.hasNTLMHashedPassword()) {
// Check if the received NTLM hashed password matches the cached password
byte[] ntlmPwd = type3Msg.getNTLMHash();
byte[] cachedPwd = ntlmDetails.getNTLMHashedPassword();
if (ntlmPwd != null) {
authenticated = Arrays.equals(cachedPwd, ntlmPwd);
}
if (logger.isDebugEnabled())
logger.debug("Using cached NTLM hash, authenticated = " + authenticated);
onValidate(context, req, res, new NTLMCredentials(userName, ntlmPwd));
// Allow the user to access the requested page
return true;
} else {
WebCredentials credentials;
// Check if we are using local MD4 password hashes or passthru authentication
if (nltmAuthenticator.getNTLMMode() == NTLMMode.MD4_PROVIDER) {
// Check if guest logons are allowed and this is a guest logon
if (m_allowGuest && userName.equalsIgnoreCase(authenticationComponent.getGuestUserName())) {
credentials = new GuestCredentials();
// Indicate that the user has been authenticated
authenticated = true;
if (getLogger().isDebugEnabled())
getLogger().debug("Guest logon");
} else {
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = getMD4Hash(userName);
if (md4hash != null) {
authenticated = validateLocalHashedPassword(type3Msg, ntlmDetails, authenticated, md4hash);
credentials = new NTLMCredentials(ntlmDetails.getUserName(), ntlmDetails.getNTLMHashedPassword());
} else {
// Check if unknown users should be logged on as guest
if (m_mapUnknownUserToGuest) {
// Reset the user name to be the guest user
userName = authenticationComponent.getGuestUserName();
authenticated = true;
credentials = new GuestCredentials();
if (logger.isDebugEnabled())
logger.debug("User " + userName + " logged on as guest, no Alfresco account");
} else {
if (logger.isDebugEnabled())
logger.debug("User " + userName + " does not have Alfresco account");
// Bypass NTLM authentication and display the logon screen,
// as user account does not exist in Alfresco
credentials = new UnknownCredentials();
authenticated = false;
}
}
}
} else {
credentials = new NTLMCredentials(type3Msg.getUserName(), type3Msg.getNTLMHash());
// Determine if the client sent us NTLMv1 or NTLMv2
if (type3Msg.hasFlag(NTLM.Flag128Bit) && type3Msg.hasFlag(NTLM.FlagNTLM2Key) || (type3Msg.getNTLMHash() != null && type3Msg.getNTLMHash().length > 24)) {
// Cannot accept NTLMv2 if we are using passthru auth
if (logger.isErrorEnabled())
logger.error("Client " + workstation + " using NTLMv2 logon, not valid with passthru authentication");
} else {
if (ntlmDetails == null) {
if (logger.isWarnEnabled())
logger.warn("Authentication failed: NTLM details can not be retrieved from session. Client must support cookies.");
restartLoginChallenge(context, req, res);
return false;
}
// Passthru mode, send the hashed password details to the passthru authentication server
NTLMPassthruToken authToken = (NTLMPassthruToken) ntlmDetails.getAuthenticationToken();
authToken.setUserAndPassword(type3Msg.getUserName(), type3Msg.getNTLMHash(), PasswordEncryptor.NTLM1);
try {
// Run the second stage of the passthru authentication
nltmAuthenticator.authenticate(authToken);
authenticated = true;
// Check if the user has been logged on as guest
if (authToken.isGuestLogon()) {
userName = authenticationComponent.getGuestUserName();
}
// Set the authentication context
authenticationComponent.setCurrentUser(userName);
} catch (BadCredentialsException ex) {
if (logger.isDebugEnabled())
logger.debug("Authentication failed, " + ex.getMessage());
} catch (AuthenticationException ex) {
if (logger.isDebugEnabled())
logger.debug("Authentication failed, " + ex.getMessage());
} finally {
// Clear the authentication token from the NTLM details
ntlmDetails.setAuthenticationToken(null);
}
}
}
// Check if the user has been authenticated, if so then setup the user environment
if (authenticated == true) {
boolean userInit = false;
if (user == null) {
try {
user = createUserEnvironment(session, userName);
userInit = true;
} catch (AuthenticationException ex) {
if (logger.isDebugEnabled())
logger.debug("Failed to validate user " + userName, ex);
onValidateFailed(context, req, res, session, credentials);
return false;
}
}
onValidate(context, req, res, credentials);
// Update the NTLM logon details in the session
String srvName = getServerName();
if (ntlmDetails == null) {
// No cached NTLM details
ntlmDetails = new NTLMLogonDetails(userName, workstation, domain, false, srvName);
ntlmDetails.setNTLMHashedPassword(type3Msg.getNTLMHash());
session.setAttribute(NTLM_AUTH_DETAILS, ntlmDetails);
if (logger.isDebugEnabled())
logger.debug("No cached NTLM details, created");
} else {
// Update the cached NTLM details
ntlmDetails.setDetails(userName, workstation, domain, false, srvName);
ntlmDetails.setNTLMHashedPassword(type3Msg.getNTLMHash());
if (logger.isDebugEnabled())
logger.debug("Updated cached NTLM details");
}
if (logger.isDebugEnabled())
logger.debug("User logged on via NTLM, " + ntlmDetails);
if (onLoginComplete(context, req, res, userInit)) {
// Allow the user to access the requested page
return true;
}
} else {
restartLoginChallenge(context, req, res);
}
}
return false;
}
Aggregations