use of org.alfresco.repo.SessionUser in project alfresco-remote-api by Alfresco.
the class AuthenticationFilter method doFilterInternal.
protected void doFilterInternal(ServletContext context, ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
if (logger.isTraceEnabled()) {
logger.trace("Entering AuthenticationFilter.");
}
// Assume it's an HTTP request
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
// Get the user details object from the session
SessionUser user = getSessionUser(context, httpReq, httpResp, false);
if (user == null) {
if (logger.isDebugEnabled()) {
logger.debug("There is no user in the session.");
}
// Get the authorization header
String authHdr = httpReq.getHeader("Authorization");
if (authHdr != null && authHdr.length() > 5 && authHdr.substring(0, 5).equalsIgnoreCase("BASIC")) {
if (logger.isDebugEnabled()) {
logger.debug("Basic authentication details present in the header.");
}
byte[] encodedString = Base64.decodeBase64(authHdr.substring(5).getBytes());
// ALF-13621: Due to browser inconsistencies we have to try a fallback path of encodings
Set<String> attemptedAuths = new HashSet<String>(ENCODINGS.length * 2);
for (String encoding : ENCODINGS) {
CharsetDecoder decoder = Charset.forName(encoding).newDecoder().onMalformedInput(CodingErrorAction.REPORT);
try {
// Attempt to decode using this charset
String basicAuth = decoder.decode(ByteBuffer.wrap(encodedString)).toString();
// It decoded OK but we may already have tried this string.
if (!attemptedAuths.add(basicAuth)) {
// Already tried - no need to try again
continue;
}
String username = null;
String password = null;
// Split the username and password
int pos = basicAuth.indexOf(":");
if (pos != -1) {
username = basicAuth.substring(0, pos);
password = basicAuth.substring(pos + 1);
} else {
username = basicAuth;
password = "";
}
// Go to the repo and authenticate
Authorization auth = new Authorization(username, password);
if (auth.isTicket()) {
authenticationService.validate(auth.getTicket());
} else {
authenticationService.authenticate(username, password.toCharArray());
if (authenticationListener != null) {
authenticationListener.userAuthenticated(new BasicAuthCredentials(username, password));
}
}
user = createUserEnvironment(httpReq.getSession(), authenticationService.getCurrentUserName(), authenticationService.getCurrentTicket(), false);
if (logger.isTraceEnabled()) {
logger.trace("Successfully created user environment, login using basic auth or ROLE_TICKET for user: " + AuthenticationUtil.maskUsername(user.getUserName()));
}
// Success so break out
break;
} catch (CharacterCodingException e) {
if (logger.isDebugEnabled()) {
logger.debug("Didn't decode using " + decoder.getClass().getName(), e);
}
} catch (AuthenticationException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Authentication error ", ex);
}
} catch (NoSuchPersonException e) {
if (logger.isDebugEnabled()) {
logger.debug("There is no such person error ", e);
}
}
}
} else {
// Check if the request includes an authentication ticket
String ticket = req.getParameter(ARG_TICKET);
if (ticket != null && ticket.length() > 0) {
// PowerPoint bug fix
if (ticket.endsWith(PPT_EXTN)) {
ticket = ticket.substring(0, ticket.length() - PPT_EXTN.length());
}
if (logger.isTraceEnabled()) {
logger.trace("Logon via ticket from " + req.getRemoteHost() + " (" + req.getRemoteAddr() + ":" + req.getRemotePort() + ")" + " ticket=" + ticket);
}
// Validate the ticket
authenticationService.validate(ticket);
if (authenticationListener != null) {
authenticationListener.userAuthenticated(new TicketCredentials(ticket));
}
// Need to create the User instance if not already available
String currentUsername = authenticationService.getCurrentUserName();
user = createUserEnvironment(httpReq.getSession(), currentUsername, ticket, false);
if (logger.isTraceEnabled()) {
logger.trace("Successfully created user environment, login using TICKET for user: " + AuthenticationUtil.maskUsername(user.getUserName()));
}
}
}
if (user == null) {
if (logger.isDebugEnabled()) {
logger.debug("No user/ticket, force the client to prompt for logon details.");
}
httpResp.setHeader("WWW-Authenticate", "BASIC realm=\"Alfresco DAV Server\"");
httpResp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpResp.flushBuffer();
return;
}
} else {
if (authenticationListener != null) {
authenticationListener.userAuthenticated(new TicketCredentials(user.getTicket()));
}
if (logger.isTraceEnabled()) {
logger.trace("User already set to: " + AuthenticationUtil.maskUsername(user.getUserName()));
}
}
// Chain other filters
chain.doFilter(req, resp);
}
use of org.alfresco.repo.SessionUser in project alfresco-remote-api by Alfresco.
the class BaseKerberosAuthenticationFilter method authenticateRequest.
public boolean authenticateRequest(ServletContext context, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
// Check if there is an authorization header with an SPNEGO security blob
String authHdr = req.getHeader("Authorization");
boolean reqAuth = false;
if (authHdr != null) {
if (authHdr.startsWith("Negotiate"))
reqAuth = true;
else if (authHdr.startsWith("NTLM")) {
if (getLogger().isTraceEnabled()) {
getLogger().trace("Received NTLM logon from client");
}
// Restart the authentication
restartLoginChallenge(context, req, resp);
return false;
} else if (isFallbackEnabled()) {
return performFallbackAuthentication(context, req, resp);
}
}
// Check if the user is already authenticated
SessionUser user = getSessionUser(context, req, resp, true);
HttpSession httpSess = req.getSession(true);
if (user == null) {
user = (SessionUser) httpSess.getAttribute("_alfAuthTicket");
// MNT-13191 Opening /alfresco/webdav from a Kerberos-authenticated IE11 browser causes HTTP error 500
if (user != null) {
String userName = user.getUserName();
AuthenticationUtil.setFullyAuthenticatedUser(userName);
}
}
// the next filter
if (user != null && reqAuth == false) {
// Filter validate hook
onValidate(context, req, resp, new TicketCredentials(user.getTicket()));
if (getLogger().isTraceEnabled()) {
getLogger().trace("Authentication not required (user), chaining ...");
}
// Chain to the next filter
return true;
}
// Check if the login page is being accessed, do not intercept the login page
if (checkLoginPage(req, resp)) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Login page requested, chaining ...");
}
return true;
}
if (authHdr == null) {
if (allowsTicketLogons()) {
if (checkForTicketParameter(context, req, resp)) {
// Filter validate hook
if (getLogger().isTraceEnabled()) {
getLogger().trace("Authenticated with a ticket parameter.");
}
if (user == null) {
user = (SessionUser) httpSess.getAttribute(getUserAttributeName());
}
onValidate(context, req, resp, new TicketCredentials(user.getTicket()));
return true;
}
}
if (getLogger().isTraceEnabled()) {
getLogger().trace("New Kerberos auth request from " + req.getRemoteHost() + " (" + req.getRemoteAddr() + ":" + req.getRemotePort() + ")");
}
// MNT-21702 fixing Kerberos SSO fallback machanism for WebDAV
if (req.getRequestURL().toString().contains("webdav")) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("WebDAV request, fallback");
}
logonStartAgain(context, req, resp, false);
} else {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Non-WebDAV request, don't fallback");
}
logonStartAgain(context, req, resp, true);
}
return false;
} else {
// Decode the received SPNEGO blob and validate
final byte[] spnegoByts = Base64.decodeBase64(authHdr.substring(10).getBytes());
if (isNTLMSSPBlob(spnegoByts, 0)) {
if (getLogger().isTraceEnabled()) {
getLogger().trace("Client sent an NTLMSSP security blob");
}
// Restart the authentication
restartLoginChallenge(context, req, resp);
return false;
}
// Check the received SPNEGO token type
int tokType = -1;
try {
tokType = SPNEGO.checkTokenType(spnegoByts, 0, spnegoByts.length);
} catch (IOException ex) {
}
if (tokType == SPNEGO.NegTokenInit) {
// Parse the SPNEGO security blob to get the Kerberos ticket
NegTokenInit negToken = new NegTokenInit();
try {
// Decode the security blob
negToken.decode(spnegoByts, 0, spnegoByts.length);
// Determine the authentication mechanism the client is using and logon
String oidStr = null;
if (negToken.numberOfOids() > 0)
oidStr = negToken.getOidAt(0).toString();
if (oidStr != null && (oidStr.equals(OID.ID_MSKERBEROS5) || oidStr.equals(OID.ID_KERBEROS5))) {
try {
NegTokenTarg negTokenTarg = doKerberosLogon(negToken, req, resp, httpSess);
if (negTokenTarg != null) {
// Allow the user to access the requested page
onValidate(context, req, resp, new KerberosCredentials(negToken, negTokenTarg));
if (getLogger().isTraceEnabled()) {
getLogger().trace("Authenticated through Kerberos.");
}
return true;
} else {
// Send back a request for SPNEGO authentication
if (getLogger().isDebugEnabled()) {
getLogger().debug("Failed SPNEGO authentication.");
}
restartLoginChallenge(context, req, resp);
return false;
}
} catch (AuthenticationException ex) {
// max user limit
if (getLogger().isDebugEnabled()) {
getLogger().debug("Validate failed.", ex);
}
WebCredentials webCredentials = user == null ? null : new TicketCredentials(user.getTicket());
onValidateFailed(context, req, resp, httpSess, webCredentials);
return false;
}
} else {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Unsupported SPNEGO mechanism " + oidStr);
}
// Try again!
restartLoginChallenge(context, req, resp);
}
} catch (IOException ex) {
// Log the error
if (getLogger().isDebugEnabled()) {
getLogger().debug(ex);
}
}
} else {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Unknown SPNEGO token type");
}
// Send back a request for SPNEGO authentication
restartLoginChallenge(context, req, resp);
}
}
return false;
}
use of org.alfresco.repo.SessionUser 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.isTraceEnabled()) {
if (authHdr == null) {
logger.trace("Header not found: " + httpServletRequestAuthHeaderName);
} else {
logger.trace("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.isTraceEnabled()) {
logger.trace("User = " + AuthenticationUtil.maskUsername(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.isTraceEnabled()) {
logger.trace("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.SessionUser in project alfresco-remote-api by Alfresco.
the class BaseAuthenticationFilter method getSessionUser.
/**
* Callback to get the specific impl of the Session User for a filter.
*
* @param servletContext
* the servlet context
* @param httpServletRequest
* the http servlet request
* @param httpServletResponse
* the http servlet response
* @param externalAuth
* has the user been authenticated by SSO?
* @return User from the session
*/
protected SessionUser getSessionUser(ServletContext servletContext, final HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, final boolean externalAuth) {
String userId = null;
// If the remote user mapper is configured, we may be able to map in an externally authenticated user
if (remoteUserMapper != null && (!(remoteUserMapper instanceof ActivateableBean) || ((ActivateableBean) remoteUserMapper).isActive())) {
userId = remoteUserMapper.getRemoteUser(httpServletRequest);
if (getLogger().isTraceEnabled()) {
getLogger().trace("Found a remote user: " + AuthenticationUtil.maskUsername(userId));
}
}
String sessionAttrib = getUserAttributeName();
HttpSession session = httpServletRequest.getSession();
SessionUser sessionUser = (SessionUser) session.getAttribute(sessionAttrib);
if (sessionUser != null) {
try {
if (getLogger().isTraceEnabled()) {
getLogger().trace("Found a session user: " + AuthenticationUtil.maskUsername(sessionUser.getUserName()));
}
authenticationService.validate(sessionUser.getTicket());
setExternalAuth(session, externalAuth);
} catch (AuthenticationException e) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("The ticket may have expired or the person could have been removed, invalidating session.", e);
}
invalidateSession(httpServletRequest);
sessionUser = null;
}
}
if (userId != null) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("We have a previously-cached user with the wrong identity - replace them.");
}
if (sessionUser != null && !sessionUser.getUserName().equals(userId)) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Removing the session user, invalidating session.");
}
session.removeAttribute(sessionAttrib);
session.invalidate();
sessionUser = null;
}
if (sessionUser == null) {
// If we have been authenticated by other means, just propagate through the user identity
if (getLogger().isDebugEnabled()) {
getLogger().debug("Propagating through the user identity: " + AuthenticationUtil.maskUsername(userId));
}
authenticationComponent.setCurrentUser(userId);
session = httpServletRequest.getSession();
try {
sessionUser = createUserEnvironment(session, authenticationService.getCurrentUserName(), authenticationService.getCurrentTicket(), true);
} catch (Throwable e) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Error during ticket validation and user creation: " + e.getMessage(), e);
}
}
}
}
return sessionUser;
}
use of org.alfresco.repo.SessionUser 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.isTraceEnabled()) {
logger.trace("Authenticating user '" + AuthenticationUtil.maskUsername(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.isTraceEnabled()) {
logger.trace("Authenticated user '" + AuthenticationUtil.maskUsername(username) + "'");
}
request.getSession().setAttribute(userAttributeName, user);
return true;
} catch (AuthenticationException ex) {
// Do nothing, user object will be null
if (logger.isDebugEnabled()) {
logger.debug(ex.getMessage(), ex);
}
}
}
} else {
try {
authenticationService.validate(user.getTicket());
return true;
} catch (AuthenticationException ex) {
session.invalidate();
if (logger.isDebugEnabled()) {
logger.debug(ex.getMessage(), ex);
}
}
}
return false;
}
Aggregations