Title / Description
Code package njust.consman.secman; import hirondelle.web4j.security.SafeText; import hirondelle.web4j.util.Util; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; 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 njust.consman.model.user.PrivilegeGroup; import njust.consman.model.user.PrivilegeGroupUtil; import njust.consman.model.user.User; import njust.consman.model.user.UserPrivilegeCache; import org.apache.commons.lang3.StringUtils; import static njust.consman.model.user.UserUtil.LOGIN_STATE; import static njust.consman.model.user.UserUtil.LOGIN_USER; public final class SecurityManager implements Filter{ @Override public void destroy() { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; String base = request.getContextPath(); String uri = StringUtils.removeStart(request.getRequestURI(), base); log.fine(uri); // 根目录下的都能访问,一般是一些静态的HTML文件 if (isRoot(uri)) { chain.doFilter(req, res); return; } // 忽略的URI前缀 for (String i : ignoredPrefix) { if (uri.startsWith(i)) { chain.doFilter(req, res); return; } } Boolean login = Boolean.FALSE; // 当前是否有用户已经登陆 HttpSession session = request.getSession(false); if (session != null) { login = (Boolean)session.getAttribute(LOGIN_STATE); } login = Util.nullMeansFalse(login); // 未登录则跳转到登陆页面 if (!login) { response.sendRedirect(base + loginURI); log.info("Access denied when requesting:" + uri); return; } /* 到此用户肯定已经登陆了 */ // 注销和文件下载URI只要登录便可访问 // FIXME 文件下载URI根据用户的权限做进一步访问控制,可能需要在文件下载的Servlet中做 if (uri.startsWith(logoutURI) || uri.startsWith(resURI) || uri.startsWith(welcomeURI)) { chain.doFilter(req, res); return; } // 登录用户都可以访问设置页面(密码修改,个人信息修改) if (uri.startsWith(settingURI)) { chain.doFilter(req, res); return; } // 四个平台的访问控制 User user = (User)session.getAttribute(LOGIN_USER); SafeText name = user.getName(); List<PrivilegeGroup> privileges = UserPrivilegeCache.get(name.getRawString()); for (PrivilegeGroup i : privileges) { String prefix = i.getPlatform().getRawString(); if (uri.startsWith(prefix) || hasImplicitPermission(prefix, uri)) { chain.doFilter(req, res); return; } } // 其余全部拒绝访问 response.sendError(HttpServletResponse.SC_FORBIDDEN); } private boolean hasImplicitPermission(String prefix, String uri) { if (PrivilegeGroupUtil.BASIC_PLATFORM.equals(prefix) || PrivilegeGroupUtil.STAT_PLATFORM.equals(prefix)) { return uri.startsWith(PrivilegeGroupUtil.INFO_PLATFORM); } return false; } @Override public void init(FilterConfig config) throws ServletException { String ignores = config.getInitParameter(PARAM_IGNORE); if(ignores != null) { for(String i : StringUtils.split(ignores, ',')) ignoredPrefix.add(i.trim()); } log.info("Ignore prefixs:\n" + Util.logOnePerLine(ignoredPrefix)); loginURI = config.getInitParameter(PARAM_LOGIN_URI); log.info("Login URI: " + loginURI); logoutURI = config.getInitParameter(PARAM_LOGOUT_URI); log.info("Logout URI: " + logoutURI); resURI = config.getInitParameter(PARAM_RES_URI); log.info("Resource download URI: " + resURI); welcomeURI = config.getInitParameter(PARAM_WELCOME_URI); log.info("Welcome URI: " + welcomeURI); settingURI = config.getInitParameter(PARAM_SETTING_URI); log.info("settings URI: " + settingURI); } // PRIVATE // private static final String PARAM_IGNORE = "ignore"; private static final String PARAM_LOGOUT_URI = "logout-uri"; private static final String PARAM_LOGIN_URI = "login-uri"; private static final String PARAM_RES_URI = "res-uri"; private static final String PARAM_WELCOME_URI = "welcome-uri"; private static final String PARAM_SETTING_URI = "setting-uri"; private static final String URI_SEPERATOR = "/"; private String loginURI; // 系统登陆的URI private String resURI, logoutURI, welcomeURI; // 文件下载的URI,注销URI,以及欢迎URI private String settingURI; // 个人信息管理 private List<String> ignoredPrefix = new ArrayList<String>(); private static final Logger log = Util.getLogger(SecurityManager.class); /** * Test if a URI is located in the root path. * @param uri URI to test * @return true if URI is located in the root path, otherwise return false; */ private boolean isRoot(String uri) { int idx = uri.lastIndexOf(URI_SEPERATOR); return (idx == 0); } }
Author
Highlight as C C++ CSS Clojure Delphi ERb Groovy (beta) HAML HTML JSON Java JavaScript PHP Plain text Python Ruby SQL XML YAML diff code