您的位置:首页 > 编程语言

openfire 拦截servlet请求代码解析

2016-09-07 17:24 441 查看
下面的内容以获取用户状态插件的类(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>

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: