一种基于annotation的Spring-mvc权限控制方法

简介

本文介绍一种采用annotation来对spring-mvc进行权限控制的方法. 通过枚举类来定义权限项. 将annotation标注到需要控制权限的spring-mvc方法上. 然后,在spring-mvc中定义全局过滤器, 过滤所有spring-mvc方法, 查看方法上的权限annotation信息, 以此对权限进行控制.
程序源代码: https://github.com/eagle0445/sample/

优点

编写比较方便, 在需要控制权限的方法上进行annotation的标注即可, ide能够对annotation进行识别支持. 查看权限配置比较方便, 因为annotation就在方法上, 不用去其他地方翻看. 实现方式比较简单.

具体实现

1.建立权限枚举类

建立权限枚举类型, 用于描述权限的种类, 包含了权限的名称. 每个枚举值中包含了权限中文名称和权限索引值(即权限位). (思考:是否可以直接用中文名称作为枚举值的名称,我在其他程序已经用了中文枚举名称了,暂时没有遇到问题)

<!-- lang: java -->
public enum AuthorityType{
// 包含了枚举的中文名称, 枚举的索引值
WORKER("增删改查员工", 1),

SALES_ORDER_CREATE("创建订单", 6),
SALES_ORDER_FIND("查看订单", 7),
SALES_ORDER_MODIFY("修改订单", 8),
SALES_ORDER_DELETE("删除订单", 9),
;
private String name;
private int index;

private AuthorityType(String name, int index) {
    this.name = name;
    this.index = index;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getIndex() {
    return index;
}
public void setIndex(int index) {
    this.index = index;
}
}

2.登录方式的枚举类

登录方式的枚举类, page代表传统登录页面, json表示ajax的登录

<!-- lang: java -->
public enum ResultTypeEnum {
//整页刷新
page,
//json数据
json
}

3.建立表示权限annotation类

建立annotation类, 用于标注到需要权限验证的地方

<!-- lang: java -->
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FireAuthority {
    AuthorityType[] authorityTypes();
    ResultTypeEnum resultType() default ResultTypeEnum.page;
}

4.在user类中加入权限字段

在user用户类中添加文本字段表示权限, 字段长度为250字符(因为mysql默认255个字符,可以代表250个权限应该够用了), 字符内容是0或者1. 1表示有权限, 0表示无权限. 提示: 对于用户的权限配置, 只要将对应的权限位设置为0或者1即可.

<!-- lang: sql -->
    create table user (
        id integer not null auto_increment,
        name varchar(255),
        right_content varchar(255),
        primary key (id)
    ) type=InnoDB

5.权限验证算法

权限判断方法, 权限判断的实现算法, 用于判断是否有权限

<!-- lang: java -->
public class AuthorityHelper {

/**
 * 判断是否有权限
 * @param akey  aString中位置的索引值,也就是权限位
 * @param aString  权限字段,比如 11010101011101
 * @return
 */
public static boolean hasAuthority(int akey,String aString){
    return ConstanHelper.getAuthorityVaule(akey,rc);
    if(aString==null || "".equals(aString)){
        return false;
    }

    char value = aString.charAt(akey);
    if(value == ‘1‘){
        return true;
    }

    return false;

}

}

6.建立控制权限的interceptor类

建立interceptor类, 用于过滤需要控制权限的方法.

<!-- lang: java -->
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class AuthorityAnnotationInterceptor extends HandlerInterceptorAdapter {

    final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.debug("");
        HandlerMethod handler2=(HandlerMethod) handler;
        FireAuthority fireAuthority = handler2.getMethodAnnotation(FireAuthority.class);

        if(null == fireAuthority){
            //没有声明权限,放行
            return true;
        }

        logger.debug("fireAuthority", fireAuthority.toString());

        HttpSession session = request.getSession();
        Worker manager = (Worker)session.getAttribute(SessionHelper.WorkerHandler);
        boolean aflag = false;

        for(AuthorityType at:fireAuthority.authorityTypes()){
            if(AuthorityHelper.hasAuthority(at.getIndex(), manager.getRightContent())==true){
                aflag = true;
                break;
            }
        }

        if(false == aflag){

            if (fireAuthority.resultType() == ResultTypeEnum.page) {
                //传统的登录页面
                StringBuilder sb = new StringBuilder();
                sb.append(request.getContextPath());
                sb.append("/oprst.jsp?oprst=false&opmsg=").append(URLEncoder.encode(ControllerProperty.NOT_HAVE_AUTHORITY,"utf-8"));
                response.sendRedirect(sb.toString());
            } else if (fireAuthority.resultType() == ResultTypeEnum.json) {
                //ajax类型的登录提示
                response.setCharacterEncoding("utf-8");
                response.setContentType("text/html;charset=UTF-8");
                OutputStream out = response.getOutputStream();
                PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,"utf-8"));
                pw.println("{\"result\":false,\"code\":12,\"errorMessage\":\""+ControllerProperty.NOT_HAVE_AUTHORITY+"\"}");
                pw.flush();
                pw.close();
            }

            return false;

        }
        return true;
    }

}

7.配置interceptor类

在spring-mvc中配置interceptor, 实现过滤.

<!-- lang: xml -->
    <mvc:interceptors>
        <bean class="interceptor.AuthorityAnnotationInterceptor"></bean>
    </mvc:interceptors>

8.标注需要控制权限的方法

在需要控制访问的spring-mvc方法上面加上对应的标注.
//方式一

<!-- lang: java -->
@FireAuthority(AuthorityType. SALES_ORDER_CREATE)
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String  name) throws Exception {
    //some code
}

//方式二

<!-- lang: java -->
@FireAuthority(authorityTypes = {AuthorityType.SALES_ORDER_DELETE,AuthorityType.SALES_ORDER_CREATE})
    @RequestMapping(value="/save.spr", method=RequestMethod.POST)
    public ModelAndView save(String  name) throws Exception {
        //some code
    }

//方式三

    <!-- lang: java -->
@FireAuthority(authorityTypes = AuthorityType.SALES_ORDER_DELETE, resultType=ResultTypeEnum.page)
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String  name) throws Exception {
    //some code
}

9.完成了

^_^

后续

还需要一套界面,以便进行用户权限的配置, 幸运的是本人已经实现了这一功能, 而代码相对比较简单, 将在后面的博客中进行详细解说.
程序源代码: https://github.com/eagle0445/sample/

© 著作权归作者所有

转自:http://my.oschina.net/kingfire/blog/102760

时间: 2024-08-30 03:52:32

一种基于annotation的Spring-mvc权限控制方法的相关文章

Spring7:基于注解的Spring MVC(下篇)

Model 上一篇文章<Spring6:基于注解的Spring MVC(上篇)>,讲了Spring MVC环境搭建.@RequestMapping以及参数绑定,这是Spring MVC中最基础也是最重要的内容,本篇文章继续讲讲Spring MVC中其余的知识点,先从Model开始. 前一篇文章比较详细地解读了数据从页面请求到服务器后台的一些细节,那么下一个要解决的问题就是数据如何从后台再次传回前台,答案就是这里要说的Model,关于Model在写例子之前我特别先说明三点: 1.Model本身是

基于注解的Spring MVC整合Hibernate

1.导入jar 2.web.xml配置 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&

基于注解的Spring MVC

1.加入?jar 2.web.xml配置: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocati

spring MVC 权限控制拦截

SecurityInterceptor实现spring mvc 框架的结构在访问控制@Controller之前的权限拦截,具体实现方法,增加总权限控制器 public class SecurityInterceptor extends HandlerInterceptorAdapter{ private static final Logger logger = Logger.getLogger(SecurityInterceptor.class); @Resource private Sessi

回顾 基于注解的spring mvc

回顾 基于注解的spring mvc

基于注解的Spring MVC的从零单建(简略版)

网上关于此教程各种版本,太多太多了,因为我之前没搭过框架,最近带着两个实习生,为了帮他们搭框架,我只好...惭愧啊...基本原理的话各位自己了解下,表示我自己从来没研究过Spring的源码,所以工作了一年多还是在写代码... 下面直接正题,怎么搭建 我的Project目录结构,jsp在web-inf目录,js之类的在webroot根目录. 1.配置web.xml SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet

Spring6:基于注解的Spring MVC(上篇)

什么是Spring MVC Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC和Structs.Structs2非常类似.Spring MVC的设计是围绕DispatcherServlet展开的,DispatcherServlet负责将请求派发到特定的handler.通过可配置的hander mappings.view resolution.locale以及theme res

一种基于策略的Android传感器权限管理框架——SemaDroid

SemaDroid : APrivacy-Aware Sensor Management Framework for Smartphones, (ACM Conference onData and Application Security and Privacy) CODASPY '15, 2015年3月 [1] http://dl.acm.org/citation.cfm?id=2699114 1.1. 背景 宾夕法尼亚州立大学的研究人员针对传感器数据可能造成用户数据泄露的问题,提出了一种基于

基于maven来Spring MVC的环境搭建遇到“坑”

1.注解配置路径问题: 在web.xml中配置spring mvc 路径时, 应该配置如下:classpath:classpath:spring-* 2.jdk版本和Spring MVC版本不一致问题: 运行4.0以上的spring web-mvc需要变更jdk为jdk8.0以上: 3.spring mvc版本变更或jdk版本变更 在变更spring 版本时,遇到,变更pom后依赖未更新问题:删除maven依赖后,重新配置.classpath;并更新maven项目才解决: 具体操作如下: htt