1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.shiro.web.filter.authc; 20 21 import org.apache.shiro.SecurityUtils; 22 import org.apache.shiro.session.SessionException; 23 import org.apache.shiro.subject.Subject; 24 import org.apache.shiro.web.servlet.AdviceFilter; 25 import org.apache.shiro.web.util.WebUtils; 26 import org.slf4j.Logger; 27 import org.slf4j.LoggerFactory; 28 29 import javax.servlet.ServletRequest; 30 import javax.servlet.ServletResponse; 31 32 /** 33 * Simple Filter that, upon receiving a request, will immediately log-out the currently executing 34 * {@link #getSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) subject} 35 * and then redirect them to a configured {@link #getRedirectUrl() redirectUrl}. 36 * 37 * @since 1.2 38 */ 39 public class LogoutFilter extends AdviceFilter { 40 41 private static final Logger log = LoggerFactory.getLogger(LogoutFilter.class); 42 43 /** 44 * The default redirect URL to where the user will be redirected after logout. The value is {@code "/"}, Shiro's 45 * representation of the web application's context root. 46 */ 47 public static final String DEFAULT_REDIRECT_URL = "/"; 48 49 /** 50 * The URL to where the user will be redirected after logout. 51 */ 52 private String redirectUrl = DEFAULT_REDIRECT_URL; 53 54 /** 55 * Acquires the currently executing {@link #getSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) subject}, 56 * a potentially Subject or request-specific 57 * {@link #getRedirectUrl(javax.servlet.ServletRequest, javax.servlet.ServletResponse, org.apache.shiro.subject.Subject) redirectUrl}, 58 * and redirects the end-user to that redirect url. 59 * 60 * @param request the incoming ServletRequest 61 * @param response the outgoing ServletResponse 62 * @return {@code false} always as typically no further interaction should be done after user logout. 63 * @throws Exception if there is any error. 64 */ 65 @Override 66 protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { 67 Subject subject = getSubject(request, response); 68 String redirectUrl = getRedirectUrl(request, response, subject); 69 //try/catch added for SHIRO-298: 70 try { 71 subject.logout(); 72 } catch (SessionException ise) { 73 log.debug("Encountered session exception during logout. This can generally safely be ignored.", ise); 74 } 75 issueRedirect(request, response, redirectUrl); 76 return false; 77 } 78 79 /** 80 * Returns the currently executing {@link Subject}. This implementation merely defaults to calling 81 * {@code SecurityUtils.}{@link org.apache.shiro.SecurityUtils#getSubject() getSubject()}, but can be overridden 82 * by subclasses for different retrieval strategies. 83 * 84 * @param request the incoming Servlet request 85 * @param response the outgoing Servlet response 86 * @return the currently executing {@link Subject}. 87 */ 88 protected Subject getSubject(ServletRequest request, ServletResponse response) { 89 return SecurityUtils.getSubject(); 90 } 91 92 /** 93 * Issues an HTTP redirect to the specified URL after subject logout. This implementation simply calls 94 * {@code WebUtils.}{@link WebUtils#issueRedirect(javax.servlet.ServletRequest, javax.servlet.ServletResponse, String) issueRedirect(request,response,redirectUrl)}. 95 * 96 * @param request the incoming Servlet request 97 * @param response the outgoing Servlet response 98 * @param redirectUrl the URL to where the browser will be redirected immediately after Subject logout. 99 * @throws Exception if there is any error. 100 */ 101 protected void issueRedirect(ServletRequest request, ServletResponse response, String redirectUrl) throws Exception { 102 WebUtils.issueRedirect(request, response, redirectUrl); 103 } 104 105 /** 106 * Returns the redirect URL to send the user after logout. This default implementation ignores the arguments and 107 * returns the static configured {@link #getRedirectUrl() redirectUrl} property, but this method may be overridden 108 * by subclasses to dynamically construct the URL based on the request or subject if necessary. 109 * <p/> 110 * Note: the Subject is <em>not</em> yet logged out at the time this method is invoked. You may access the Subject's 111 * session if one is available and if necessary. 112 * <p/> 113 * Tip: if you need to access the Subject's session, consider using the 114 * {@code Subject.}{@link Subject#getSession(boolean) getSession(false)} method to ensure a new session isn't created unnecessarily. 115 * If a session would be created, it will be immediately stopped after logout, not providing any value and 116 * unnecessarily taxing session infrastructure/resources. 117 * 118 * @param request the incoming Servlet request 119 * @param response the outgoing ServletResponse 120 * @param subject the not-yet-logged-out currently executing Subject 121 * @return the redirect URL to send the user after logout. 122 */ 123 protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject) { 124 return getRedirectUrl(); 125 } 126 127 /** 128 * Returns the URL to where the user will be redirected after logout. Default is the web application's context 129 * root, i.e. {@code "/"} 130 * 131 * @return the URL to where the user will be redirected after logout. 132 */ 133 public String getRedirectUrl() { 134 return redirectUrl; 135 } 136 137 /** 138 * Sets the URL to where the user will be redirected after logout. Default is the web application's context 139 * root, i.e. {@code "/"} 140 * 141 * @param redirectUrl the url to where the user will be redirected after logout 142 */ 143 public void setRedirectUrl(String redirectUrl) { 144 this.redirectUrl = redirectUrl; 145 } 146 }