/** * 权限检查标签类 */ public class PermissionTag extends TagSupport { private static final long serialVersionUID = -5285732412976711256L; private String module; private String privilege; @Override public int doStartTag() throws JspException { boolean result = false; Employee employee = WebUtil.getEmployee((HttpServletRequest) pageContext.getRequest()); SystemPrivilege privilege = new SystemPrivilege(new SystemPrivilegePK(this.module, this.privilege)); for (PrivilegeGroup group : employee.getGroups()) { if (group.getPrivileges().contains(privilege)) { result = true; break; } } return result ? EVAL_BODY_INCLUDE : SKIP_BODY; } public String getModule() { return module; } public void setModule(String module) { this.module = module; } public String getPrivilege() { return privilege; } public void setPrivilege(String privilege) { this.privilege = privilege; } }
2. 配置标签tld文件
<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <description>itcast babasport permission taglib</description> <display-name>permission taglib</display-name> <tlib-version>1.0</tlib-version> <short-name>itcast</short-name> <uri>http://www.itcast.cn/babasport</uri> <tag> <description>权限校验标签,有权限就显示标签体的内容,否则不显示</description> <name>permission</name> <tag-class>com.shop.action.privilege.PermissionTag</tag-class> <body-content>JSP</body-content> <attribute> <description>所在模块</description> <name>module</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <description>所予权限</description> <name>privilege</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> </taglib>
3. 在需要进行权限控制的JSP片段中:
<itcast:permission privilege="update" module="product"> <div align="center"><a href="/shop/control/product/editUI.do?productid=${entry.id}"><img src="/shop/images/edit.gif" width="15" height="16" border="0"></a></div> </itcast:permission></td>
// ------ 以上还不够, JSP还不是安全的, 要在JAVA程序中在进行过滤:
4. 定义注解Permission:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Permission { String module(); String privilege(); }
5. 在需要进行权限检查的Controller方法上打上注解:
@RequestMapping("/control/product/list") @Permission(module = "product", privilege = "view") public String list(ProductBean formbean, HttpServletRequest request) {} @RequestMapping("/control/product/addUI") @Permission(module = "product", privilege = "insert") public String addUI(HttpServletRequest request) throws Exception {}
6. 定义一个Interceptor, 拦截所有需要进行权限检查的URL:
SpringMVC中的实现:
public class PrivilegeRequestInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // like /shop/control/department/list.do String requestURI = WebUtil.getRequestURI(request); // like /control/department/list String reqMapping = requestURI.substring(5, requestURI.indexOf(".do")); Map<String, String[]> reqInfo = new LinkedHashMap<String, String[]>(); Method targetMethod = getTargetMethod(handler, reqMapping); if (reqMapping.startsWith("/control/")) {//只对办公平台中的action进行校验 boolean validateResult = validate(request, targetMethod); reqInfo.put("permission validate:", new String[] { validateResult + "" }); log.debug("request info: " + getJSONString(reqInfo)); if (!validateResult) {//没有权限的时候执行下面这段代码 request.setAttribute("message", "您没有执行该操作的权限"); request.setAttribute("urladdress", SiteUrl.readUrl("control.control.right")); request.getRequestDispatcher("/WEB-INF/page/share/message.jsp").forward(request, response); return false; } return true; } log.debug("request info: " + getJSONString(reqInfo)); return true; } private Method getTargetMethod(Object handler, String reqMapping) { Method[] methods = handler.getClass().getDeclaredMethods(); for (Method method : methods) { boolean isAnnoted = method.isAnnotationPresent(RequestMapping.class); RequestMapping mappingAnnoted = method.getAnnotation(RequestMapping.class); if (isAnnoted && reqMapping.equals(mappingAnnoted.value()[0])) { return method; } } return null; } /** * 权限校验 * @return */ private boolean validate(HttpServletRequest request, Method targetMethod) { if (targetMethod == null || !targetMethod.isAnnotationPresent(Permission.class)) { return true; } Permission permission = targetMethod.getAnnotation(Permission.class);//得到方法上的注解 //下面是得到执行方法需要的权限 SystemPrivilegePK targetPrivilege = new SystemPrivilegePK(permission.module(), permission.privilege()); Employee employee = WebUtil.getEmployee(request); for (PrivilegeGroup group : employee.getGroups()) { for (SystemPrivilege privilege : group.getPrivileges()) { if (privilege.getPermission().equals(targetPrivilege)) { return true; } } } return false; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { Collection<String> headNames = response.getHeaderNames(); for (String headName : headNames) { log.debug("HTTP head{" + headName + ":" + response.getHeader(headName) + "}"); } super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { super.afterCompletion(request, response, handler, ex); // 可以在此通过判断ex是否为null,来检查Controller是否抛出了异常. } }
7. 在springmvc-servlet.xml中配置Interceptor:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <list> <bean class="com.shop.web.support.PrivilegeRequestInterceptor" /> </list> </property> </bean>