org.artifactory.webapp.wicket.application.ArtifactoryWebSession.java Source code

Java tutorial

Introduction

Here is the source code for org.artifactory.webapp.wicket.application.ArtifactoryWebSession.java

Source

/*
 * Artifactory is a binaries repository manager.
 * Copyright (C) 2012 JFrog Ltd.
 *
 * Artifactory is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Artifactory is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Artifactory.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.artifactory.webapp.wicket.application;

import org.apache.commons.lang.StringUtils;
import org.apache.wicket.Session;
import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
import org.apache.wicket.proxy.IProxyTargetLocator;
import org.apache.wicket.proxy.LazyInitProxyFactory;
import org.apache.wicket.request.Request;
import org.artifactory.UiAuthenticationDetails;
import org.artifactory.api.context.ArtifactoryContext;
import org.artifactory.api.context.ContextHelper;
import org.artifactory.api.search.SavedSearchResults;
import org.artifactory.api.security.AuthorizationService;
import org.artifactory.api.security.SecurityService;
import org.artifactory.common.wicket.util.WicketUtils;
import org.artifactory.security.AccessLogger;
import org.artifactory.security.ArtifactoryPermission;
import org.artifactory.security.HttpAuthenticationDetails;
import org.artifactory.security.UserInfo;
import org.artifactory.util.SerializablePair;
import org.artifactory.webapp.servlet.RequestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author Yoav Landman
 */
public class ArtifactoryWebSession extends AuthenticatedWebSession {

    private static final Logger log = LoggerFactory.getLogger(ArtifactoryWebSession.class);

    private AuthenticationManager authenticationManager;
    private Authentication authentication;
    private Roles roles;
    private Map<String, SavedSearchResults> results;
    private SerializablePair<String, Long> lastLoginInfo;

    public static ArtifactoryWebSession get() {
        return (ArtifactoryWebSession) Session.get();
    }

    public ArtifactoryWebSession(Request request) {
        super(request);
        authenticationManager = (AuthenticationManager) LazyInitProxyFactory
                .createProxy(AuthenticationManager.class, new SecurityServiceLocator());
    }

    @Override
    public boolean authenticate(final String username, final String password) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
                password);
        HttpServletRequest servletRequest = WicketUtils.getHttpServletRequest();
        HttpServletResponse servletResponse = WicketUtils.getHttpServletResponse();
        replaceSession(); // protect against session fixation
        WebAuthenticationDetails details = new UiAuthenticationDetails(servletRequest, servletResponse);
        authenticationToken.setDetails(details);
        boolean authenticated;
        try {
            Authentication authentication = authenticationManager.authenticate(authenticationToken);
            authenticated = authentication.isAuthenticated();
            if (authenticated) {
                setAuthentication(authentication);
                if (StringUtils.isNotBlank(username) && (!username.equals(UserInfo.ANONYMOUS))) {

                    //Save the user's last login info in the web session so we can display it in the welcome page
                    ArtifactoryContext context = ContextHelper.get();
                    SecurityService securityService = context.beanForType(SecurityService.class);
                    SerializablePair<String, Long> lastLoginInfo = securityService.getUserLastLoginInfo(username);
                    ArtifactoryWebSession.get().setLastLoginInfo(lastLoginInfo);

                    //Update the user's current login info in the database
                    String remoteAddress = new HttpAuthenticationDetails(servletRequest).getRemoteAddress();
                    securityService.updateUserLastLogin(username, remoteAddress, System.currentTimeMillis());
                }
            }
        } catch (AuthenticationException e) {
            authenticated = false;
            AccessLogger.loginDenied(authenticationToken);
            if (log.isDebugEnabled()) {
                log.debug("Failed to authenticate " + username, e);
            }
        }
        return authenticated;
    }

    private void setWicketRoles(Authentication authentication) {
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        String[] authorityRoles = new String[authorities.size()];
        int i = 0;
        for (GrantedAuthority authority : authorities) {
            String role = authority.getAuthority();
            authorityRoles[i] = role;
            i++;
        }
        roles = new Roles(authorityRoles);
    }

    public void signOutArtifactory() {
        signOut();

        // Remove the authentication attribute early
        RequestUtils.removeAuthentication(WicketUtils.getHttpServletRequest());

        // Clear authentication and authorization data saved in this session
        // (this WICKET session will still be used in the logout page)
        roles = null;
        authentication = null;
        results = null;
        SecurityContextHolder.clearContext();
        invalidate();
    }

    void setAuthentication(Authentication authentication) {
        this.authentication = authentication;
        if (authentication.isAuthenticated()) {
            setWicketRoles(authentication);
            //Log authentication if not anonymous
            if (!isAnonymous()) {
                AccessLogger.loggedIn(authentication);
            }
            //Set a http session token so that we can reuse the login in direct repo browsing
            HttpServletRequest httpServletRequest = WicketUtils.getHttpServletRequest();
            RequestUtils.setAuthentication(httpServletRequest, authentication, true);

            //Update the spring  security context
            bindAuthentication();
        }
        dirty();
    }

    void initAnonymousAuthentication() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated()) {
            if (!isSignedIn()
                    || (isAnonymous() && !UserInfo.ANONYMOUS.equals("" + authentication.getPrincipal()))) {
                // session is not logged in yet, but was already authenticated (probably by a filter) so set the
                // authentication and call signIn with empty params which will mark the session as authenticated
                setAuthentication(authentication);
                markSignedIn();
            }
        }
    }

    /**
     * @return True is anonymous user is logged in to this session.
     */
    boolean isAnonymous() {
        return authentication != null && UserInfo.ANONYMOUS.equals(authentication.getPrincipal().toString());
    }

    @Override
    public Roles getRoles() {
        return roles;
    }

    public boolean hasRole(String role) {
        return roles != null && roles.hasRole(role);
    }

    public void setResults(SavedSearchResults savedSearchResults) {
        AuthorizationService authService = ContextHelper.get().getAuthorizationService();
        if (authService.hasPermission(ArtifactoryPermission.DEPLOY)) {
            getResults().put(savedSearchResults.getName(), savedSearchResults);
        }
    }

    public SavedSearchResults getResults(String resultsName) {
        if (results != null) {
            return getResults().get(resultsName);
        } else {
            return null;
        }
    }

    public void removeResult(String resultsName) {
        if (results != null) {
            getResults().remove(resultsName);
        }
    }

    public Set<String> getResultNames() {
        if (results == null) {
            return Collections.emptySet();
        }
        return getResults().keySet();
    }

    public boolean hasResults() {
        return results != null && !results.isEmpty();
    }

    public SerializablePair<String, Long> getLastLoginInfo() {
        return lastLoginInfo;
    }

    public void setLastLoginInfo(SerializablePair<String, Long> lastLoginInfo) {
        this.lastLoginInfo = lastLoginInfo;
    }

    private Map<String, SavedSearchResults> getResults() {
        if (results == null) {
            results = new HashMap<>();
        }
        return results;
    }

    @Override
    public void detach() {
        SecurityContextHolder.clearContext();
        super.detach();
    }

    void bindAuthentication() {
        //Add the authentication to the request thread
        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authentication);
    }

    /**
     * Call this method when external authentication is performed (eg, cookie, token).
     */
    public void markSignedIn() {
        super.signIn(true);
    }

    private static class SecurityServiceLocator implements IProxyTargetLocator {
        @Override
        public Object locateProxyTarget() {
            ArtifactoryContext context = ContextHelper.get();
            // get the "ui" authentication manager (no password encryption stuff)
            AuthenticationManager security = (AuthenticationManager) context.getBean("authenticationManager");
            return security;
        }
    }
}