文档章节

spring简单权限

zhchl2010
 zhchl2010
发布于 2014/12/05 22:53
字数 798
阅读 14
收藏 0
1.权限类注释
/**只要在Controller上增加这个类,都要进行权限的控制*/
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthClass {

    /**如果value为admin,就表明这个类只能超级管理员访问,
     * 如果value为login表示这个类中的方法,某些可能需要相应的角色支持*/
    public String value() default "admin";
    
}

2.权限具体方法注释
/**用来确定哪些方法由哪些角色访问
 * 属性有一个role:如果role的值为base表示这个方法可以被所有的登陆用户访问
 * 如果为ROLE_PUBLISH表示只能为文章发布人员访问
 * 如果某个方法中没有加注释表示只能管理员访问*/
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthMethod {

    public String role() default "base";
}

3.相关资源注释扫描工具类
/**反射实现权限控制*/
public class AuthUtil {

    /**初始化系统的角色所访问的功能信息*/
    public static Map<String,Set<String>> initAuth(String pname){
        Map<String,Set<String>> auths=new HashMap<String,Set<String>>();
        String[] ps=getClassByPackage(pname);
        for(String p:ps){
            try {
                //System.out.println(p);//class名称
                String pc=pname+"."+p.substring(0,p.indexOf(".class"));
                //System.out.println(pc);//类名
                //得到类的class对象
                Class clz=Class.forName(pc);
                if(!clz.isAnnotationPresent(AuthClass.class))
                    continue;
                //System.out.println(pc);//类名
                //获取每个类的方法,以确定哪些角色可以访问哪些方法
                Method[] ms=clz.getDeclaredMethods();
                /*遍历method来判断每个method上面是否存在相应的
                 * AuthMethod,如果存在就直接将这个方法存储到auths中,
                 * 如果不存在就不存储,不存储就以为着只能超级管理员访问*/
                for(Method m:ms){
                    if(!m.isAnnotationPresent(AuthMethod.class))
                        continue;
                    //如果存在就要获取这个Annotation
                    AuthMethod am=m.getAnnotation(AuthMethod.class);
                    String role=am.role();
                    Set<String> actions=auths.get(role);
                    if(actions==null){
                        actions=new HashSet<String>();
                        auths.put(role,actions);
                    }
                    actions.add(pc+"."+m.getName());
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return auths;
    }
    /**根据包名获取包内所有的类*/
    private static String[] getClassByPackage(String pname) {
        String pr=pname.replace(".","/");
        String pp=AuthUtil.class.getClassLoader().getResource(pr).getPath();
        //System.out.println(pp);
        File file=new File(pp);
        String[] fs=file.list(new FilenameFilter() {
            
            @Override
            public boolean accept(File dir, String name) {
                if(name.endsWith("class")) return true;
                return false;
            }
        });
        return fs;
    }
    
    public static void main(String[] args) {
        System.out.println(initAuth("org.konghao.cms.controller"));
    }
}

4.设置servlet容器启动时扫描不同角色可以访问的资源
public class InitServlet extends HttpServlet{

    private static final long serialVersionUID = -7674955333691573745L;
    private static WebApplicationContext wc;
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        //1.初始化spring的工厂
        wc=WebApplicationContextUtils
                .getWebApplicationContext(this.getServletContext());
        //2.初始化权限信息
        Map<String,Set<String>> auths=
                AuthUtil.initAuth("org.konghao.cms.controller");
        this.getServletContext().setAttribute("allAuths",auths);
        System.out.println("-------权限系统初始化成功-----------------------");
    }
    
    public static WebApplicationContext getWc(){
        return wc;
    }
}

5.设置随servlet启动web.xml
<servlet>
    <servlet-name>initServlet</servlet-name>
       <servlet-class>org.konghao.cms.web.InitServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
  </servlet>

6.spring  mvc拦截器过滤请求并判断权限
public class AuthInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod hm=(HandlerMethod)handler;
        /*System.out.println(hm.getBean().getClass().getName()
                +"."+hm.getMethod().getName());*/
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("loginUser");
        if(user==null) {
            response.sendRedirect(request.getContextPath()+"/login");
        }else{
            boolean isAdmin=(Boolean)session.getAttribute("isAdmin");
            if(!isAdmin){
                //不是超级管理员,就需要判断是否有权限访问某些功能
                Set<String> actions=(Set<String>)session.getAttribute("allActions");
                String aname=hm.getBean().getClass().getName()
                        +"."+hm.getMethod().getName();
                if(!actions.contains(aname))
                    throw new CmsException("没有权限访问该功能");
            }
        }
        return super.preHandle(request, response, handler);
    }
}

7.spring mvc中过滤器注册springmvc-servlet.xml
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/admin/**"/>
            <bean class="org.konghao.cms.web.AuthInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

8.注释需要权限控制的资源
@Controller
@AuthClass("login")
@RequestMapping("/admin/topic")
public class TopicController {

    @RequestMapping("/add")
    @AuthMethod(role="ROLE_PUBLISH")
    public void add(){
        
    }
    
    @RequestMapping("/delete")
    @AuthMethod(role="ROLE_PUBLISH")
    public void delete(){
        
    }
    
    @RequestMapping("/audit")
    @AuthMethod(role="ROLE_AUDIT")
    public void audit(){
        
    }
}


© 著作权归作者所有

共有 人打赏支持
上一篇: javascript记录
下一篇: 验证码
zhchl2010
粉丝 3
博文 80
码字总数 77710
作品 0
成都
程序员
私信 提问
Spring Boot 中使用 Spring Security + JWT 构建身份认证系统

权限控制是非常常见的功能,在各种后台管理里权限控制更是重中之重。在 Spring Boot 中使用 Spring Security 构建权限系统是非常轻松和简单的。Spring Security 是一个能够为基于 Spring 的企...

辣姜哥丶
2018/08/28
0
0
Shiro和Spring Security对比

Shiro简介 Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不...

有余力则学文
2018/04/27
0
0
Spring Boot [集成-Spring Security]

导读 在上一篇文章中对Spring Boot 集成Shrio做了一个简单的介绍,这篇文章中主要围绕Spring Boot 集成 Spring Security展开,文章末尾附有学习资料。 快速上手: 1.引入pom依赖 2.实现一个简...

yangrd
2018/08/27
0
0
SpringBoot集成Spring Security(1)——入门程序

因为项目需要,第一次接触Spring Security,早就听闻Spring Security强大但上手困难,今天学习了一天,翻遍了全网资料,才仅仅出入门道,特整理这篇文章来让后来者少踩一点坑(本文附带实例程...

yuanlaijike
2018/05/09
0
0
【spring boot 系列】spring security 实践 + 源码分析

前言 本文将从示例、原理、应用3个方面介绍 spring data jpa。 以下分析基于spring boot 2.0 + spring 5.0.4版本源码 概述 Spring Security 是一个能够为基于 Spring 的企业应用系统提供声明...

java高级架构牛人
2018/06/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

拒绝拖拽 使用ConstraintLayout优化你的布局吧

ConstraintLayout出现有一段时间了,不过一直没有特别去关注,也多多少少看了一些文字介绍,多数都是对使用可视化布局拖拽,个人对拖拽一直不看好,直到前端时间看到该文: 解析ConstraintL...

SuShine
3分钟前
0
0
开源 java CMS - FreeCMS2.8 数据对象 report

项目地址:http://www.freeteam.cn/ report 在使用申报相关标签时,标签会封装report供页面调用。 属性 说明 id id name 项目名称 unit 申报单位 filename 申报文件名称 filenum 申报文件文号...

freeteam
5分钟前
0
0
MySQL配置主从复制

1.master配置my.ini添加: log-bin=mysql-bin//开启二进制日志server-id=1innodb_flush_log_at_trx_commit=1//每次事务的结束都会触发Log Thread 将log buffer 中的数据写入文件并通知文...

ty淡然
6分钟前
0
0
在vs2017中将.obj链接到.lib中

项目属性-库管理器-常规-附加依赖项-"your.obj;....."

simpower
11分钟前
0
0
同一数据库,从这个表迁移到另外一张表

要求: 1、同一个数据库 2、两张表结构相同 insert into t_walk_user_step_history(user_id,city_id,steps,prop_steps,today_praise,today_date,insert_time)selectuser_id,city_id,st......

就叫程舰
11分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部