Package org.geoserver.security.cas

Source Code of org.geoserver.security.cas.GeoServerCasAuthenticationFilter

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/

package org.geoserver.security.cas;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.logging.Level;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.security.LogoutFilterChain;
import org.geoserver.security.config.SecurityNamedServiceConfig;
import org.geoserver.security.filter.GeoServerLogoutFilter;
import org.geoserver.security.filter.GeoServerPreAuthenticatedUserNameFilter;
import org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.session.SingleSignOutHandler;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.TicketValidationException;
import org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.util.StringUtils;

/**
* CAS Authentication filter receiving/validating proxy tickets
* and service tickets.
*
* If {@link #singleSignOut} is <code>true</code>, this filter
* handles logout requests sent from the CAS server.
*
* This filter implements the {@link LogoutHandler} interface
* for log out requests triggered by GeoServer
*
* @author mcr
*
*/
public class GeoServerCasAuthenticationFilter extends GeoServerPreAuthenticatedUserNameFilter implements LogoutHandler {
   
   
    protected GeoServerCas20ProxyTicketValidator validator;
    protected ServiceAuthenticationDetailsSource casAuthenticationDetailsSource = new ServiceAuthenticationDetailsSource();
    protected String casLogoutURL;
    protected String urlInCasLogoutPage;
    protected boolean singleSignOut;
   
    protected ProxyGrantingTicketStorage pgtStorageFilter;

    public GeoServerCasAuthenticationFilter(ProxyGrantingTicketStorage pgtStorageFilter) {
        this.pgtStorageFilter = pgtStorageFilter;
    }
   

    @Override
    public void initializeFromConfig(SecurityNamedServiceConfig config) throws IOException {
        super.initializeFromConfig(config);

               
        CasAuthenticationFilterConfig authConfig =
                (CasAuthenticationFilterConfig) config;
       
        validator = new GeoServerCas20ProxyTicketValidator(authConfig.getCasServerUrlPrefix());
        validator.setAcceptAnyProxy(true);
        validator.setProxyGrantingTicketStorage(pgtStorageFilter);
       
        validator.setRenew(authConfig.isSendRenew());
        if (StringUtils.hasLength(authConfig.getProxyCallbackUrlPrefix()))
                validator.setProxyCallbackUrl(GeoServerCasConstants.createProxyCallBackURl(authConfig.getProxyCallbackUrlPrefix()));
       
        casLogoutURL=GeoServerCasConstants.createCasURl(authConfig.getCasServerUrlPrefix(), GeoServerCasConstants.LOGOUT_URI);
        if (StringUtils.hasLength(authConfig.getUrlInCasLogoutPage()))
                casLogoutURL+="?"+GeoServerCasConstants.LOGOUT_URL_PARAM+"="+URLEncoder.encode(authConfig.getUrlInCasLogoutPage(),"utf-8");
               
        singleSignOut=authConfig.isSingleSignOut();
        aep = new GeoServerCasAuthenticationEntryPoint(authConfig);
    }
   

       
    protected Assertion getCASAssertion(HttpServletRequest request) {
      String ticket = request.getParameter(GeoServerCasConstants.ARTIFACT_PARAMETER);
     
      if (ticket==null) return null;
      if ((ticket.startsWith(GeoServerCasConstants.PROXY_TICKET_PREFIX) ||
              ticket.startsWith(GeoServerCasConstants.SERVICE_TICKET_PREFIX))==false)
          return null;
     
      try {
          String service = retrieveService(request);
          return validator.validate(ticket,service );         
         
      } catch (TicketValidationException e) {
          LOGGER.warning(e.getMessage());
      }
      return null;
    }
   
    protected static String retrieveService(HttpServletRequest request) {
       
        String serviceBaseUrl = null;
        String proxyBaseUrl = GeoServerExtensions.getProperty("PROXY_BASE_URL");
        if (StringUtils.hasLength(proxyBaseUrl)) {
            serviceBaseUrl = proxyBaseUrl;
        } else {
            serviceBaseUrl = request.getRequestURL().toString();
        }
        StringBuffer buff  = new StringBuffer(serviceBaseUrl);
       
       
        if (StringUtils.hasLength(request.getQueryString())) {
            String query = request.getQueryString();
            String[] params = query.split("&");
            boolean firsttime=true;
            for (String param : params
            { 
                               
                String[] keyValue = param.split("=");
                if (keyValue.length == 0) continue;
                String name = keyValue[0];
               
                if (GeoServerCasConstants.ARTIFACT_PARAMETER.equals(name.trim()))
                    continue;
                if (GeoServerCasAuthenticationEntryPoint.CAS_REDIRECT.equals(name.trim()))
                    continue;
                if (firsttime) {
                    buff.append("?");
                    firsttime=false;
                } else {
                    buff.append("&");
                }                                   
                buff.append(param);
            }                           
        }
        String serviceUrl = buff.toString();
        if (LOGGER.isLoggable(Level.FINE))
            LOGGER.fine("CAS Service URL: "+serviceUrl);
        return serviceUrl;
    }
   
   
    protected String getPreAuthenticatedPrincipal(HttpServletRequest request) {
       
        String principal = super.getPreAuthenticatedPrincipal(request);
       
        HttpSession session = request.getSession(false);       

        if (principal!=null && session!=null) {
            session.setAttribute(GeoServerCasConstants.CAS_ASSERTION_KEY,
                    request.getAttribute(GeoServerCasConstants.CAS_ASSERTION_KEY));
            request.removeAttribute(GeoServerCasConstants.CAS_ASSERTION_KEY);
            getHandler().recordSession(request);
        }
       
        if (principal==null) {
            request.removeAttribute(GeoServerCasConstants.CAS_ASSERTION_KEY);
        }               
        return principal;
       
    }
   
    /**
     */
    @Override
    protected String getPreAuthenticatedPrincipalName(HttpServletRequest request) {
       
       
        Assertion assertion = getCASAssertion(request);
        if (assertion==null) return null;               
        request.setAttribute(GeoServerCasConstants.CAS_ASSERTION_KEY,assertion);       
        return assertion.getPrincipal().getName();
    }

   
    protected static SingleSignOutHandler getHandler() {
        return GeoServerExtensions.bean(SingleSignOutHandler.class);
    }

   
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
       
        HttpServletRequest httpReq= (HttpServletRequest) req;
        HttpServletResponse httpRes= (HttpServletResponse) res;
               
        SingleSignOutHandler handler = getHandler();
        // check for sign out request from cas server
        if (handler.isLogoutRequest(httpReq)) {
            if (singleSignOut) { // do we participate
                LOGGER.info("Single Sign Out received from CAS server --> starting log out");
                handler.destroySession(httpReq);               
                LogoutFilterChain logOutChain = (LogoutFilterChain)
                        getSecurityManager().getSecurityConfig().getFilterChain().getRequestChainByName("webLogout");
                logOutChain.doLogout(getSecurityManager(), httpReq, httpRes,getName());
            } else
                LOGGER.info("Single Sign Out received from CAS server --> ignoring");
            return;
        }
       
        super.doFilter(req, res, chain);
       
        if (SecurityContextHolder.getContext().getAuthentication()!=null) {
            HttpSession session = httpReq.getSession(false);       

            if (session !=null &&
                    session.getAttribute(GeoServerCasConstants.CAS_ASSERTION_KEY)!=null && singleSignOut) {
                getHandler().recordSession(httpReq);
                if (LOGGER.isLoggable(Level.INFO))
                    LOGGER.info("Record HTTP Session "+session.getId()+ " for CAS single sign out");
            }
        }
           

               
    }

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) {
            request.setAttribute(GeoServerLogoutFilter.LOGOUT_REDIRECT_ATTR,casLogoutURL);
    }

}
TOP

Related Classes of org.geoserver.security.cas.GeoServerCasAuthenticationFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.