Coverage Report - org.kuali.student.security.filter.KSLogoutFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
KSLogoutFilter
0%
0/57
0%
0/24
2.4
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.security.filter;
 17  
 
 18  
 import java.io.IOException;
 19  
 
 20  
 import javax.servlet.FilterChain;
 21  
 import javax.servlet.ServletException;
 22  
 import javax.servlet.ServletRequest;
 23  
 import javax.servlet.ServletResponse;
 24  
 import javax.servlet.http.HttpServletRequest;
 25  
 import javax.servlet.http.HttpServletResponse;
 26  
 
 27  
 import org.springframework.security.core.Authentication;
 28  
 import org.springframework.security.core.context.SecurityContextHolder;
 29  
 import org.springframework.security.web.DefaultRedirectStrategy;
 30  
 import org.springframework.security.web.authentication.logout.LogoutHandler;
 31  
 import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
 32  
 import org.springframework.security.web.util.UrlUtils;
 33  
 import org.springframework.util.Assert;
 34  
 import org.springframework.util.StringUtils;
 35  
 import org.springframework.web.filter.GenericFilterBean;
 36  
 
 37  
 /**
 38  
  * This is a description of what this class does - Rich don't forget to fill this in. 
 39  
  * 
 40  
  * @author Kuali Rice Team (kuali-rice@googlegroups.com)
 41  
  *
 42  
  */
 43  
 public class KSLogoutFilter extends GenericFilterBean {
 44  
 
 45  0
     private String filterProcessesUrl = "/j_spring_security_logout";
 46  0
     private String logoutSuccessUrl = "/";
 47  
     private LogoutHandler[] handlers;
 48  0
     String invalidateSession = "true";
 49  
     
 50  0
     public KSLogoutFilter(){
 51  0
         handlers = new SecurityContextLogoutHandler[1];
 52  0
         SecurityContextLogoutHandler sclh = new SecurityContextLogoutHandler();
 53  0
         if ("true".equals(invalidateSession)) {
 54  0
             sclh.setInvalidateHttpSession(true);
 55  
         } else {
 56  0
             sclh.setInvalidateHttpSession(false);
 57  
         }
 58  0
         handlers[0] = sclh;
 59  0
     }
 60  
     
 61  0
     public KSLogoutFilter(String logoutSuccessUrl, LogoutHandler[] handlers) {
 62  0
         Assert.notEmpty(handlers, "LogoutHandlers are required");
 63  0
         this.logoutSuccessUrl = logoutSuccessUrl;
 64  0
         Assert.isTrue(UrlUtils.isValidRedirectUrl(logoutSuccessUrl), logoutSuccessUrl + " isn't a valid redirect URL");
 65  0
         this.handlers = handlers;
 66  0
     }
 67  
 
 68  
     public void doFilter(ServletRequest request, ServletResponse response,
 69  
                         FilterChain chain) throws IOException, ServletException {
 70  0
                 if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
 71  0
                         doFilterHttp((HttpServletRequest) request,
 72  
                                         (HttpServletResponse) response, chain);
 73  
                 } else {
 74  
                         // TODO: handle this
 75  
                 }
 76  0
         }
 77  
     
 78  
     public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException,
 79  
             ServletException {
 80  
 
 81  0
         if (requiresLogout(request, response)) {
 82  0
             Authentication auth = SecurityContextHolder.getContext().getAuthentication();
 83  
 
 84  0
             if (logger.isDebugEnabled()) {
 85  0
                 logger.debug("Logging out user '" + auth + "' and redirecting to logout page");
 86  
             }
 87  
 
 88  0
             for (int i = 0; i < handlers.length; i++) {
 89  0
                 handlers[i].logout(request, response, auth);
 90  
             }
 91  
 
 92  0
             String targetUrl = determineTargetUrl(request, response);
 93  
 
 94  0
             sendRedirect(request, response, targetUrl);
 95  
 
 96  0
             return;
 97  
         }
 98  
 
 99  0
         chain.doFilter(request, response);
 100  0
     }
 101  
 
 102  
     /**
 103  
      * Allow subclasses to modify when a logout should take place.
 104  
      *
 105  
      * @param request the request
 106  
      * @param response the response
 107  
      *
 108  
      * @return <code>true</code> if logout should occur, <code>false</code> otherwise
 109  
      */
 110  
     protected boolean requiresLogout(HttpServletRequest request, HttpServletResponse response) {
 111  0
         String uri = request.getRequestURI();
 112  0
         int pathParamIndex = uri.indexOf(';');
 113  
 
 114  0
         if (pathParamIndex > 0) {
 115  
             // strip everything from the first semi-colon
 116  0
             uri = uri.substring(0, pathParamIndex);
 117  
         }
 118  
 
 119  0
         int queryParamIndex = uri.indexOf('?');
 120  
 
 121  0
         if (queryParamIndex > 0) {
 122  
             // strip everything from the first question mark
 123  0
             uri = uri.substring(0, queryParamIndex);
 124  
         }
 125  
 
 126  0
         if ("".equals(request.getContextPath())) {
 127  0
             return uri.endsWith(filterProcessesUrl);
 128  
         }
 129  
         
 130  
         //return uri.endsWith(request.getContextPath() + filterProcessesUrl);
 131  
         
 132  
         // we are setting the logout url j_spring_security_logout in gwt by doing a window assing.url
 133  
         // this does not take context into account. if we can change that then we can go back to the line above
 134  0
         return uri.endsWith(filterProcessesUrl);
 135  
     }
 136  
     
 137  
     
 138  
     /**
 139  
      * Returns the target URL to redirect to after logout.
 140  
      * <p>
 141  
      * By default it will check for a <tt>logoutSuccessUrl</tt> parameter in
 142  
      * the request and use this. If that isn't present it will use the configured <tt>logoutSuccessUrl</tt>. If this
 143  
      * hasn't been set it will check the Referer header and use the URL from there.
 144  
      *
 145  
      */
 146  
     protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
 147  0
         String targetUrl = request.getParameter("logoutSuccessUrl");
 148  
 
 149  0
         if(!StringUtils.hasLength(targetUrl)) {
 150  0
             targetUrl = getLogoutSuccessUrl();
 151  
         }
 152  
 
 153  0
         if (!StringUtils.hasLength(targetUrl)) {
 154  0
             targetUrl = request.getHeader("Referer");
 155  
         }        
 156  
 
 157  0
         if (!StringUtils.hasLength(targetUrl)) {
 158  0
             targetUrl = "/";
 159  
         }
 160  
 
 161  0
         return targetUrl;
 162  
     }
 163  
 
 164  
     /**
 165  
      * Allow subclasses to modify the redirection message.
 166  
      *
 167  
      * @param request  the request
 168  
      * @param response the response
 169  
      * @param url      the URL to redirect to
 170  
      *
 171  
      * @throws IOException in the event of any failure
 172  
      */
 173  
     protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url)
 174  
             throws IOException {
 175  
 
 176  0
         new DefaultRedirectStrategy().sendRedirect(request, response, url);
 177  
         
 178  0
     }
 179  
 
 180  
     public void setFilterProcessesUrl(String filterProcessesUrl) {
 181  0
         Assert.hasText(filterProcessesUrl, "FilterProcessesUrl required");
 182  0
         Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL");
 183  0
         this.filterProcessesUrl = filterProcessesUrl;
 184  0
     }
 185  
 
 186  
     protected String getLogoutSuccessUrl() {
 187  0
         return logoutSuccessUrl;
 188  
     }    
 189  
     
 190  
     protected String getFilterProcessesUrl() {
 191  0
         return filterProcessesUrl;
 192  
     }
 193  
 
 194  
     /* We can't do this unless we create a new Redirect Strategy.  Thanks Spring!
 195  
     public void setUseRelativeContext(boolean useRelativeContext) {
 196  
         this.useRelativeContext = useRelativeContext;
 197  
     }*/
 198  
 
 199  
     /* I don't think we need this
 200  
     public int getOrder() {
 201  
         return FilterChainOrder.LOGOUT_FILTER;
 202  
     } */
 203  
 
 204  
 }