下面的内容以获取用户状态插件的类(PresenceStatusServlet)为例子说明
@Override public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); plugin =(PresencePlugin) XMPPServer.getInstance().getPluginManager().getPlugin("presence"); xmlProvider = new XMLPresenceProvider(); imageProvider = new ImagePresenceProvider(this); textProvider = new TextPresenceProvider(); available = loadResource("/images/user-green-16x16.gif"); away = loadResource("/images/user-yellow-16x16.gif"); chat = loadResource("/images/user-green-16x16.gif"); dnd = loadResource("/images/user-red-16x16.gif"); offline = loadResource("/images/user-clear-16x16.gif"); xa = loadResource("/images/user-yellow-16x16.gif"); // Exclude this servlet from requering the user to login //不包括下面这个servlet请求,即下面这个请求不会被拦截 AuthCheckFilter.addExclude("presence/status"); }
package org.jivesoftware.admin; import java.io.IOException; import java.net.URLEncoder; import java.util.Set; import java.util.StringTokenizer; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.jivesoftware.util.ConcurrentHashSet; import org.jivesoftware.util.WebManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A simple filter which checks for the auth token in the user's session. If it's not there * the filter will redirect to the login page. */ public class AuthCheckFilter implements Filter { private static final Logger Log = LoggerFactory.getLogger(AuthCheckFilter.class); //excludes是过滤器不需要认证的路径,将其缓存起来,实现动态的添加和删除 private static Set<String> excludes = new ConcurrentHashSet<String>(); private ServletContext context; private String defaultLoginPage; //动态添加额外不需要认证的路径 public static void addExclude(String exclude) { excludes.add(exclude); } //动态删除不需要认证的路径 public static void removeExclude(String exclude) { excludes.remove(exclude); } /** * Returns true if a URL passes an exclude rule. * * @param url the URL to test. * @param exclude the exclude rule. * @return true if the URL passes the exclude test. */ public static boolean testURLPassesExclude(String url, String exclude) { // If the exclude rule includes a "?" character, the url must exactly match the exclude rule. // If the exclude rule does not contain the "?" character, we chop off everything starting at the first "?" // in the URL and then the resulting url must exactly match the exclude rule. If the exclude ends with a "*" // character then the URL is allowed if it exactly matches everything before the * and there are no ".." // characters after the "*". All data in the URL before // the "@" character is chopped. if (url.contains("@")) { url = url.substring(url.indexOf("@")); } if (exclude.endsWith("*")) { if (url.startsWith(exclude.substring(0, exclude.length()-1))) { // Now make sure that there are no ".." characters in the rest of the URL. if (!url.contains("..") && !url.toLowerCase().contains("%2e")) { return true; } } } else if (exclude.contains("?")) { if (url.equals(exclude)) { return true; } } else { int paramIndex = url.indexOf("?"); if (paramIndex != -1) { url = url.substring(0, paramIndex); } if (url.equals(exclude)) { return true; } } return false; } //从配置文件(OpenFire/src/web/WEB-INF/web.xml)中获取不需要认证的路径,将其缓存起来 public void init(FilterConfig config) throws ServletException { context = config.getServletContext(); defaultLoginPage = config.getInitParameter("defaultLoginPage"); String excludesProp = config.getInitParameter("excludes"); if (excludesProp != null) { StringTokenizer tokenizer = new StringTokenizer(excludesProp, ","); while (tokenizer.hasMoreTokens()) { String tok = tokenizer.nextToken().trim(); excludes.add(tok); } } } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; // Reset the defaultLoginPage variable String loginPage = defaultLoginPage; if (loginPage == null) { loginPage = request.getContextPath() + "/login.jsp"; } // Get the page we're on: String url = request.getRequestURI().substring(1); if (url.startsWith("plugins/")) { url = url.substring("plugins/".length()); } // See if it's contained in the exclude list. If so, skip filter execution boolean doExclude = false; for (String exclude : excludes) { if (testURLPassesExclude(url, exclude)) { doExclude = true; break; } } //如果发送请求的URL在excludes范围内中,则终端过滤器链,终止运行,如果不在,则继续运行,执行下一个过滤器 if (!doExclude) { WebManager manager = new WebManager(); manager.init(request, response, request.getSession(), context); if (manager.getUser() == null) { response.sendRedirect(getRedirectURL(request, loginPage, null)); return; } } chain.doFilter(req, res); } public void destroy() { } private String getRedirectURL(HttpServletRequest request, String loginPage, String optionalParams) { StringBuilder buf = new StringBuilder(); try { buf.append(request.getRequestURI()); String qs = request.getQueryString(); if (qs != null) { buf.append("?").append(qs); } } catch (Exception e) { Log.error(e.getMessage(), e); } try { return loginPage + "?url=" + URLEncoder.encode(buf.toString(), "ISO-8859-1") + (optionalParams != null ? "&"+optionalParams : ""); } catch (Exception e) { Log.error(e.getMessage(), e); return null; } } }
OpenFire/src/web/WEB-INF/web.xml内容
<filter> <filter-name>AuthCheck</filter-name> <filter-class>org.jivesoftware.admin.AuthCheckFilter</filter-class> <init-param> <param-name>excludes</param-name> <param-value> login.jsp,index.jsp?logout=true,setup/index.jsp,setup/setup-*,.gif,.png,error-serverdown.jsp,setup/clearspace-integration-prelogin.jsp </param-value> </init-param> </filter>