Search in sources :

Example 11 with SessionUser

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);
}
Also used : TicketCredentials(org.alfresco.repo.web.auth.TicketCredentials) CharsetDecoder(java.nio.charset.CharsetDecoder) BasicAuthCredentials(org.alfresco.repo.web.auth.BasicAuthCredentials) AuthenticationException(org.alfresco.repo.security.authentication.AuthenticationException) NoSuchPersonException(org.alfresco.service.cmr.security.NoSuchPersonException) HttpServletResponse(javax.servlet.http.HttpServletResponse) CharacterCodingException(java.nio.charset.CharacterCodingException) HttpServletRequest(javax.servlet.http.HttpServletRequest) Authorization(org.alfresco.repo.security.authentication.Authorization) SessionUser(org.alfresco.repo.SessionUser) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 12 with SessionUser

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;
}
Also used : TicketCredentials(org.alfresco.repo.web.auth.TicketCredentials) NegTokenTarg(org.alfresco.jlan.server.auth.spnego.NegTokenTarg) AuthenticationException(org.alfresco.repo.security.authentication.AuthenticationException) HttpSession(javax.servlet.http.HttpSession) KerberosCredentials(org.alfresco.repo.web.auth.KerberosCredentials) IOException(java.io.IOException) SessionUser(org.alfresco.repo.SessionUser) NegTokenInit(org.alfresco.jlan.server.auth.spnego.NegTokenInit) WebCredentials(org.alfresco.repo.web.auth.WebCredentials)

Example 13 with SessionUser

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);
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) SessionUser(org.alfresco.repo.SessionUser) Matcher(java.util.regex.Matcher) AuthenticationException(org.alfresco.repo.security.authentication.AuthenticationException) HttpServletResponse(javax.servlet.http.HttpServletResponse)

Example 14 with SessionUser

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;
}
Also used : SessionUser(org.alfresco.repo.SessionUser) AuthenticationException(org.alfresco.repo.security.authentication.AuthenticationException) HttpSession(javax.servlet.http.HttpSession) ActivateableBean(org.alfresco.repo.management.subsystems.ActivateableBean)

Example 15 with 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;
}
Also used : Authorization(org.alfresco.repo.security.authentication.Authorization) NodeRef(org.alfresco.service.cmr.repository.NodeRef) SessionUser(org.alfresco.repo.SessionUser) RetryingTransactionCallback(org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback) AuthenticationException(org.alfresco.repo.security.authentication.AuthenticationException) HttpSession(javax.servlet.http.HttpSession)

Aggregations

SessionUser (org.alfresco.repo.SessionUser)25 AuthenticationException (org.alfresco.repo.security.authentication.AuthenticationException)14 HttpSession (javax.servlet.http.HttpSession)9 User (org.alfresco.web.bean.repository.User)9 IOException (java.io.IOException)5 TicketCredentials (org.alfresco.repo.web.auth.TicketCredentials)5 AuthenticationService (org.alfresco.service.cmr.security.AuthenticationService)5 WebApplicationContext (org.springframework.web.context.WebApplicationContext)5 HttpServletRequest (javax.servlet.http.HttpServletRequest)4 PortletSession (javax.portlet.PortletSession)3 HttpServletResponse (javax.servlet.http.HttpServletResponse)3 Authorization (org.alfresco.repo.security.authentication.Authorization)3 BasicAuthCredentials (org.alfresco.repo.web.auth.BasicAuthCredentials)3 Serializable (java.io.Serializable)2 UnknownHostException (java.net.UnknownHostException)2 CharacterCodingException (java.nio.charset.CharacterCodingException)2 CharsetDecoder (java.nio.charset.CharsetDecoder)2 Date (java.util.Date)2 HashSet (java.util.HashSet)2 LinkedHashSet (java.util.LinkedHashSet)2