use of org.alfresco.repo.security.authentication.AuthenticationException 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;
}
use of org.alfresco.repo.security.authentication.AuthenticationException in project alfresco-remote-api by Alfresco.
the class HTTPRequestAuthenticationFilter method doFilter.
/**
* Run the authentication filter
*
* @param req
* ServletRequest
* @param resp
* ServletResponse
* @param chain
* FilterChain
* @exception ServletException
* @exception IOException
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
// Assume it's an HTTP request
final HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
// Get the user details object from the session
SessionUser user = (SessionUser) httpReq.getSession().getAttribute(AUTHENTICATION_USER);
if (user == null) {
// Check for the auth header
String authHdr = httpReq.getHeader(httpServletRequestAuthHeaderName);
if (logger.isDebugEnabled()) {
if (authHdr == null) {
logger.debug("Header not found: " + httpServletRequestAuthHeaderName);
} else {
logger.debug("Header is <" + authHdr + ">");
}
}
if ((authHdr != null) && (authHdr.length() > 0)) {
// Get the user
final String userName;
if (m_authPattern != null) {
Matcher matcher = m_authPattern.matcher(authHdr);
if (matcher.matches()) {
userName = matcher.group();
if ((userName == null) || (userName.length() < 1)) {
if (logger.isDebugEnabled()) {
logger.debug("Extracted null or empty user name from pattern " + m_authPatternString + " against " + authHdr);
}
reject(httpReq, httpResp);
return;
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("no pattern match for " + m_authPatternString + " against " + authHdr);
}
reject(httpReq, httpResp);
return;
}
} else {
userName = authHdr;
}
if (logger.isDebugEnabled()) {
logger.debug("User = " + userName);
}
// Get the authorization header
user = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<SessionUser>() {
public SessionUser execute() throws Throwable {
try {
// Authenticate the user
m_authComponent.clearCurrentSecurityContext();
m_authComponent.setCurrentUser(userName);
return createUserEnvironment(httpReq.getSession(), userName, authenticationService.getCurrentTicket(), true);
} catch (AuthenticationException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed", ex);
}
return null;
// Perhaps auto-creation/import is disabled
}
}
});
} else {
// Check if the request includes an authentication ticket
String ticket = req.getParameter(ARG_TICKET);
if (ticket != null && ticket.length() > 0) {
if (logger.isDebugEnabled())
logger.debug("Logon via ticket from " + req.getRemoteHost() + " (" + req.getRemoteAddr() + ":" + req.getRemotePort() + ")" + " ticket=" + ticket);
try {
// Validate the ticket
authenticationService.validate(ticket);
// Need to create the User instance if not already available
user = createUserEnvironment(httpReq.getSession(), authenticationService.getCurrentUserName(), ticket, true);
} catch (AuthenticationException authErr) {
// Clear the user object to signal authentication failure
if (logger.isDebugEnabled()) {
logger.debug("Failed", authErr);
}
user = null;
}
}
}
if (user == null) {
// No user/ticket, force the client to prompt for logon details
reject(httpReq, httpResp);
return;
}
}
// Chain other filters
chain.doFilter(req, resp);
}
use of org.alfresco.repo.security.authentication.AuthenticationException in project alfresco-remote-api by Alfresco.
the class SSOFallbackBasicAuthenticationDriver method authenticateRequest.
@Override
public boolean authenticateRequest(ServletContext context, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String authHdr = request.getHeader("Authorization");
HttpSession session = request.getSession(false);
SessionUser user = session == null ? null : (SessionUser) session.getAttribute(userAttributeName);
if (user == null) {
if (authHdr != null && authHdr.length() > 5 && authHdr.substring(0, 5).equalsIgnoreCase("Basic")) {
String basicAuth = new String(Base64.decodeBase64(authHdr.substring(5).getBytes()));
String username = null;
String password = null;
int pos = basicAuth.indexOf(":");
if (pos != -1) {
username = basicAuth.substring(0, pos);
password = basicAuth.substring(pos + 1);
} else {
username = basicAuth;
password = "";
}
try {
if (logger.isDebugEnabled())
logger.debug("Authenticating user '" + username + "'");
Authorization auth = new Authorization(username, password);
if (auth.isTicket()) {
authenticationService.validate(auth.getTicket());
} else {
authenticationService.authenticate(username, password.toCharArray());
}
final RetryingTransactionCallback<SessionUser> callback = new RetryingTransactionCallback<SessionUser>() {
@Override
public SessionUser execute() throws Throwable {
NodeRef personNodeRef = personService.getPerson(authenticationService.getCurrentUserName());
String username = (String) nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME);
NodeRef homeSpaceRef = (NodeRef) nodeService.getProperty(personNodeRef, ContentModel.PROP_HOMEFOLDER);
return new WebDAVUser(username, authenticationService.getCurrentTicket(), homeSpaceRef);
}
};
user = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<SessionUser>() {
public SessionUser doWork() throws Exception {
return transactionService.getRetryingTransactionHelper().doInTransaction(callback, true);
}
}, AuthenticationUtil.SYSTEM_USER_NAME);
if (logger.isDebugEnabled())
logger.debug("Authenticated user '" + username + "'");
request.getSession().setAttribute(userAttributeName, user);
return true;
} catch (AuthenticationException ex) {
// Do nothing, user object will be null
}
}
} else {
try {
authenticationService.validate(user.getTicket());
return true;
} catch (AuthenticationException ex) {
session.invalidate();
}
}
return false;
}
use of org.alfresco.repo.security.authentication.AuthenticationException in project acs-community-packaging by Alfresco.
the class LoginBean method login.
// ------------------------------------------------------------------------------
// Action event methods
/**
* Login action handler
*
* @return outcome view name
*/
public String login() {
String outcome = null;
FacesContext fc = FacesContext.getCurrentInstance();
if (this.username != null && this.username.length() != 0 && this.password != null && this.password.length() != 0) {
try {
// Perform a full session invalidation to ensure no cached data is left around
// - important if the login page has been accessed directly rather than via the Login/out action links
logout();
// Authenticate via the authentication service, then save the details of user in an object
// in the session - this is used by the servlet filter etc. on each page to check for login
this.getAuthenticationService().authenticate(this.username, this.password.toCharArray());
// Set the user name as stored by the back end
this.username = this.getAuthenticationService().getCurrentUserName();
// setup User object and Home space ID
User user = new User(this.username, this.getAuthenticationService().getCurrentTicket(), getPersonService().getPerson(this.username));
NodeRef homeSpaceRef = (NodeRef) this.getNodeService().getProperty(getPersonService().getPerson(this.username), ContentModel.PROP_HOMEFOLDER);
// check that the home space node exists - else user cannot login
if (homeSpaceRef == null || this.getNodeService().exists(homeSpaceRef) == false) {
throw new InvalidNodeRefException(homeSpaceRef);
}
user.setHomeSpaceId(homeSpaceRef.getId());
// put the User object in the Session - the authentication servlet will then allow
// the app to continue without redirecting to the login page
Application.setCurrentUser(fc, user);
// Save the current username to cookie
AuthenticationHelper.setUsernameCookie((HttpServletRequest) fc.getExternalContext().getRequest(), (HttpServletResponse) fc.getExternalContext().getResponse(), this.username);
// Programatically retrieve the LoginOutcomeBean from JSF
LoginOutcomeBean loginOutcomeBean = (LoginOutcomeBean) fc.getApplication().createValueBinding("#{LoginOutcomeBean}").getValue(fc);
// if a redirect URL has been provided then use that
// this allows servlets etc. to provide a URL to return too after a successful login
String redirectURL = loginOutcomeBean.getRedirectURL();
// ALF-10312: Validate we are redirecting within this web app
if (redirectURL != null && !redirectURL.isEmpty() && !redirectURL.startsWith(fc.getExternalContext().getRequestContextPath())) {
if (logger.isWarnEnabled())
logger.warn("Security violation. Unable to redirect to external location: " + redirectURL);
redirectURL = null;
}
if (redirectURL != null && redirectURL.length() > 0) {
if (logger.isDebugEnabled())
logger.debug("Redirect URL found: " + redirectURL);
try {
fc.getExternalContext().redirect(redirectURL);
fc.responseComplete();
return null;
} catch (IOException ioErr) {
logger.warn("Unable to redirect to url: " + redirectURL, ioErr);
}
} else {
// special case to handle jump to My Alfresco page initially
// note: to enable MT runtime client config customization, need to re-init NavigationBean
// in context of tenant login page
this.navigator.initFromClientConfig();
if (NavigationBean.LOCATION_MYALFRESCO.equals(this.preferences.getStartLocation())) {
return "myalfresco";
} else {
// generally this will navigate to the generic browse screen
return "success";
}
}
} catch (AuthenticationDisallowedException aerr) {
Utils.addErrorMessage(Application.getMessage(fc, MSG_ERROR_LOGIN_DISALLOWED));
} catch (AuthenticationMaxUsersException aerr) {
Utils.addErrorMessage(Application.getMessage(fc, MSG_ERROR_LOGIN_MAXUSERS));
} catch (AuthenticationException aerr) {
Utils.addErrorMessage(Application.getMessage(fc, MSG_ERROR_UNKNOWN_USER));
} catch (InvalidNodeRefException refErr) {
String msg;
if (refErr.getNodeRef() != null) {
msg = refErr.getNodeRef().toString();
} else {
msg = Application.getMessage(fc, MSG_NONE);
}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(fc, Repository.ERROR_NOHOME), msg));
}
} else {
Utils.addErrorMessage(Application.getMessage(fc, MSG_ERROR_MISSING));
}
return outcome;
}
use of org.alfresco.repo.security.authentication.AuthenticationException in project acs-community-packaging by Alfresco.
the class BasicAuthenticationHandler method isUserAuthenticated.
/**
* Returns <code>true</code> if the user is authenticated and their details are cached in the session
*
* @param context
* the servlet context
* @param request
* the servlet request
* @return <code>true</code>, if the user is authenticated
* @throws IOException
* Signals that an I/O exception has occurred.
* @throws ServletException
* On other errors.
*/
public boolean isUserAuthenticated(ServletContext context, HttpServletRequest request) throws IOException, ServletException {
String authHdr = request.getHeader(HEADER_AUTHORIZATION);
HttpSession session = request.getSession(false);
SessionUser sessionUser = session == null ? null : (SessionUser) session.getAttribute(USER_SESSION_ATTRIBUTE);
if (sessionUser == null) {
if (remoteUserMapper != null && (!(remoteUserMapper instanceof ActivateableBean) || ((ActivateableBean) remoteUserMapper).isActive())) {
String userId = remoteUserMapper.getRemoteUser(request);
if (userId != null) {
// authenticated by other
authenticationComponent.setCurrentUser(userId);
request.getSession().setAttribute(USER_SESSION_ATTRIBUTE, new User(userId, authenticationService.getCurrentTicket(), personService.getPerson(userId)));
return true;
}
}
if (authHdr != null && authHdr.length() > 5 && authHdr.substring(0, 5).equalsIgnoreCase(BASIC_START)) {
String basicAuth = new String(Base64.decodeBase64(authHdr.substring(5).getBytes()));
String username = null;
String password = null;
int pos = basicAuth.indexOf(":");
if (pos != -1) {
username = basicAuth.substring(0, pos);
password = basicAuth.substring(pos + 1);
} else {
username = basicAuth;
password = "";
}
try {
if (logger.isDebugEnabled())
logger.debug("Authenticating user '" + username + "'");
authenticationService.authenticate(username, password.toCharArray());
// Normalize the user ID taking into account case sensitivity settings
username = authenticationService.getCurrentUserName();
if (logger.isDebugEnabled())
logger.debug("Authenticated user '" + username + "'");
authenticationListener.userAuthenticated(new BasicAuthCredentials(username, password));
request.getSession().setAttribute(USER_SESSION_ATTRIBUTE, new User(username, authenticationService.getCurrentTicket(), personService.getPerson(username)));
return true;
} catch (AuthenticationException ex) {
authenticationListener.authenticationFailed(new BasicAuthCredentials(username, password), ex);
}
}
} else {
try {
authenticationService.validate(sessionUser.getTicket());
authenticationListener.userAuthenticated(new TicketCredentials(sessionUser.getTicket()));
return true;
} catch (AuthenticationException ex) {
authenticationListener.authenticationFailed(new TicketCredentials(sessionUser.getTicket()), ex);
session.invalidate();
}
}
return false;
}
Aggregations