篇三:权限管理--自定义权限
导语:权限的管理通常在两个位置控制,一个是界面的权限控制,原理是展示与不展示;另一个是针对Controller的控制,没有对应权限时,请求会不执行;
自定义权限有个优点,1、代码轻量级,2、原理简单,实现方便,3、基本实现权限的两点功能,登录校验、权限控制
一、界面权限的实现
1、自定义标签
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"> </taglib>
字段解释
short-name:标签的别名,用于引用时使用,对应“prefix” tag-class:tag对应的java类,功能支持标签 body-content:有三个值可选;empty:标签体必须为空;jsp:标签由其他jsp元素组成比如标签中含有<%=attributeName%>的jsp元素,那么此时body-content的值就是实际attributeName传入的值;tagdependent:有标签解释不带jsp转换
required:是否是必填选项
rtexprvalue:这个参数的值是否可以写入,换句话说 就是这个参数是否可以动态赋值
permission.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>自定义权限标签库</description> <display-name>z tld</display-name> <tlib-version>1.0</tlib-version> <short-name>z</short-name> <tag> <description>permission tag</description> <name>permission</name> <tag-class>com.common.web.taglib.PermissionTaglib</tag-class> <body-content>JSP</body-content> <attribute> <name>value</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
2、支持标签功能的方法类
package com.common.web.taglib;
import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; import org.apache.commons.lang.StringUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.guduo.common.web.constants.PermissionConstant; /** * * @描述: 自定义权限权标签 . */ @SuppressWarnings("serial") public class PermissionTaglib extends BodyTagSupport { //private static final Log log = LogFactory.getLog(PermissionTaglib.class); private String value; //权限值 @Override public int doStartTag() throws JspException { //log.info("permission tag value=" + value); if (StringUtils.isNotBlank(value)){
//获取用户的权限集合 @SuppressWarnings("unchecked") final List<String> permissions = (List<String>) ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().getSession().getAttribute(PermissionConstant.ACTIONS_SESSION_KEY); if(permissions!=null){ String[] str = value.split(","); for(String s:str){ if (permissions.contains(s.trim())){ // 拥有此功能点权限 return EVAL_BODY_INCLUDE; } } } } return SKIP_BODY; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
3、在jsp中使用
<%@ taglib prefix="z" uri="/WEB-INF/permission.tld" %>
<z:permission value="pms:menu:view,pms:role:view,pms:operator:view,pms:action:view"> 内容,有权限就展示,pms:menu:view 权限码,多个用","隔开 </z:permission>
二、Controller权限的实现
1、自定义注解
package com.common.web.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author luck * Action层权限配置注解.<br/> * 模块标识和功能点标识共同构成唯一权限点. */ @Retention(RetentionPolicy.RUNTIME) //声明注解的保留期限 @Target(ElementType.METHOD) // 声明可以使用该注解的目标类型为在方法中使用 public @interface Permission { /** 权限值 */ String value(); // 注解成员 }
2、拦截器实现权限注解
package com.common.web.interceptor; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.guduo.common.web.annotation.Permission; import com.guduo.common.web.constants.PermissionConstant; import com.guduo.model.permission.PmsOperator; /** * 自定义的细粒度权限拦截. * @author luck */ public class PermissionInterceptor extends HandlerInterceptorAdapter { private static final Log log = LogFactory.getLog(PermissionInterceptor.class);
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean isPermission = true; HandlerMethod invocation = (HandlerMethod)handler; String baseUri = request.getContextPath(); // TODO Auto-generated method stub if (invocation.getMethod().isAnnotationPresent(Permission.class)) { PmsOperator user = (PmsOperator)request.getSession().getAttribute(PermissionConstant.OPERATOR_SESSION_KEY); if(user==null){ //登录页面 response.sendRedirect(baseUri+"/loginUI"); return false; } log.info("=== invoke PermissionInterceptor"); // 得到方法上的Permission注解 final Permission pm = invocation.getMethod().getAnnotation(Permission.class); // 获取被注解方法中的request参数,要求方法中一定要有HttpServletRequest参数 @SuppressWarnings("unchecked") final List<String> permissions = (List<String>) ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().getSession().getAttribute(PermissionConstant.ACTIONS_SESSION_KEY); if (permissions.contains(pm.value())){ // 拥有此功能点权限 // 执行被拦截的方法,如果此方法不调用,则被拦截的方法不会被执行 log.info("== contain permission:" + pm.value()); isPermission = true; return isPermission; } // 没有此功能点权限 log.info("=== 您没有执行此操作的权限:" + pm.value()); isPermission = false; } return isPermission; } }
3、springMVC-servlet.xml 配置权限拦截器
没有使用 mvc:interceptor 则默认拦截所有请求
<mvc:interceptors> <bean class="com.common.web.interceptor.PermissionInterceptor" /></mvc:interceptors>
4、Controller添加注解
@Permission("pms:user:add")
priavte String addUser(){}

浙公网安备 33010602011771号