本文来自网易云社区

作者:王飞

首先引入一段关于shiro的介绍:

开发系统中,少不了权限,目前java里的权限框架有SpringSecurity和Shiro(以前叫做jsecurity),对于SpringSecurity:功能太过强大以至于功能比较分散,使用起来也比较复杂,跟Spring结合的比较好。对于初学Spring Security者来说,曲线还是较大,需要深入学习其源码和框架,配置起来也需要费比较大的力气,扩展性也不是特别强。

对于新秀Shiro来说,好评还是比较多的,使用起来比较简单,功能也足够强大,扩展性也较好。听说连Spring的官方都不用Spring Security,用的是Shiro,足见Shiro的优秀。网上找到两篇介绍:http://www.infoq.com/cn/articles/apache-shiro http://www.ibm.com/developerworks/cn/opensource/os-cn-shiro/,http://itindex.net/detail/50410-apache-shiro-%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C,官网http://shiro.apache.org/ ,使用和配置起来还是比较简单。

下面只是简单介绍下我们是如何配置和使用Shiro的。

pom.xml引入相关jar包

1             <!-- spring结合 -->
 2             <dependency>
 3                 <groupId>org.apache.shiro</groupId>
 4                 <artifactId>shiro-spring</artifactId>
 5                 <version>1.4.0</version>
 6             </dependency>
 7             <!--缓存包-->
 8             <dependency>
 9                 <groupId>org.apache.shiro</groupId>
10                 <artifactId>shiro-ehcache</artifactId>
11                 <version>1.4.0</version>
12             </dependency>
13             <!--核心包-->
14             <dependency>
15                 <groupId>org.apache.shiro</groupId>
16                 <artifactId>shiro-core</artifactId>
17                 <version>1.4.0</version>
18             </dependency>

web.xml增加过滤

 1     <!-- shiro 权限控制的过滤器 -->
 2     <filter>
 3         <filter-name>shiroFilter</filter-name>
 4         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 5     </filter>
 6 
 7     <filter-mapping>
 8         <filter-name>shiroFilter</filter-name>
 9         <url-pattern>/*</url-pattern>
10     </filter-mapping>

增加一个shiro.xml的配置文件

  1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" 5     xmlns:util="http://www.springframework.org/schema/util" 6     xsi:schemaLocation=" 7     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 8     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
 9     http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd 
10     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd11     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"12     default-lazy-init="false">
13 
14     <!-- 缓存管理器 使用memory实现 -->
15 
16 
17     <!--rememberMe 30天 -->
18     <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
19         <constructor-arg value="COOKIE_NAME" />
20         <property name="httpOnly" value="true" />
21         <property name="maxAge" value="2592000" />
22 
23     </bean>
24 
25     <!-- rememberMe管理器 -->
26     <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
27         <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
28         <property name="cookie" ref="rememberMeCookie" />
29     </bean>
30 
31     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
32         <!-- 继承AuthorizingRealm的类-->
33         <property name="realm" ref="userRealm" />
34         <property name="rememberMeManager" ref="rememberMeManager" />
35     </bean>
36 
37     <!-- Shiro Filter -->
38     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
39         <property name="securityManager" ref="securityManager" />
40         <property name="loginUrl" value="/openid" />
41         <property name="successUrl" value="/manage" />
42         <property name="unauthorizedUrl" value="/openid" />
43         <property name="filterChainDefinitions">
44             <value>
45                 /api/**=anon46                 /res/**=anon47                 /src/**=anon48                 /health/**=anon49                 /logout=authc50                 /openid=anon51                 /callback=anon52                 /=authc53                 /**=anon54             </value>
55         </property>
56     </bean>
57 
58 
59     <!-- Shiro生命周期处理器 -->
60     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
61 
62 </beans>

对bean的扫描配置

1     <!-- shiro相关的配置文件和路径扫描的配置必须要放在项目的mvc的配置文件(即xxx-servlet.xml)里 -->
2     <aop:config proxy-target-class="true" />

4     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
5         <property name="securityManager" ref="securityManager" />
6     </bean>

UserRealm

  1 @Component
 2 public class UserRealm extends AuthorizingRealm {
 3 
 4     private Logger logger = org.slf4j.LoggerFactory.getLogger(UserRealm.class);
 5 
 6     public final static String CREDENTIALS = "openid";
 7 
 8     @Autowired
 9     private SessionService sessionService;
10     @Autowired
11     private PermissionService permissionService;
12 
13     // 记录是否已经设置过PemissionResover
14     private boolean hasSetPemissionResover = false;
15 
16     @Override
17     public PermissionResolver getPermissionResolver() {
18         if (!hasSetPemissionResover) {
19             setPermissionResolver(new WildcardExtPermissionResolver());
20             hasSetPemissionResover = true;
21         }
22         return super.getPermissionResolver();
23     }
24 
25     /**
26      * 获取授权信息
27      *
28      * @param principals
29      * @return
30      */
31     @Override
32     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
33         try {
34             Iterator<String> iter = principals.fromRealm(getName()).iterator();
35             if (!iter.hasNext()) {
36                 logger.info("shiro 验证 无权限");
37                 return null;
38             }
39             String email = iter.next();
40             if (!Strings.isNullOrEmpty(email)) {
41                 // set session
42                 SessionObject so = sessionService.getSession(email);
43                 if (so == null) {
44                     logger.info("so 缓存为空");
45                     return null;
46                 }
47                 SessionUtils.setSo(so);
48 
49                 // set auth
50                 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
51                 info.addStringPermissions(permissionService.getPermsForUser(so.getRoleId()));
52                 return info;
53             }
54             logger.info("邮箱为空");
55             return null;
56         } catch (Exception e) {
57             logger.error("shiro 权限获取异常:", e);
58             return null;
59         }
60     }
61 
62     /**
63      * 获取身份验证相关信息:
64      *
65      * @param authcToken
66      * @return
67      * @throws AuthenticationException
68      */
69     @Override
70     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
71         try {
72             UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
73             String email = token.getUsername();
74             String password = new String(token.getPassword());
75             if (!StringUtils.isEmpty(email) && CREDENTIALS.equals(password)) {
76                 SessionObject so = SessionUtils.getSo();
77                 sessionService.addOrUpdateSession(so);
78                 return new SimpleAuthenticationInfo(email, CREDENTIALS, getName());
79             }
80             logger.info("登录验证失败,shiro 不添加权限信息");
81             return null;
82         } catch (Exception e) {
83             logger.error("shiro 身份验证异常:", e);
84             return null;
85         }
86     }
87 
88 
89 }

登录调用

              UsernamePasswordToken token = new UsernamePasswordToken(
                     "username", "password", true);
 
             SecurityUtils.getSubject().login(token);

退出调用

1 SecurityUtils.getSubject().logout();

权限注解

@RequiresPermissions(value = {"ROLE_KEY"})

网易云免费体验馆,0成本体验20+款云产品!

更多网易研发、产品、运营经验分享请访问网易云社区

相关文章:
【推荐】 如何看待P2P领域的羊毛党?
【推荐】 类似gitlab代码提交的热力图怎么做?

小白用shiro(1)的更多相关文章

  1. 小白用shiro(2)

    本文来自网易云社区 作者:王飞 以上的配置走完以后就可以用,下面讲讲个人需求,以及踩过的坑: 1.如何修改cookie的名称,默认名称"rememberMe"太丑了有木有? 首先丢 ...

  2. 数据库路由中间件MyCat - 使用篇(4)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 配置MyCat 3. 配置conf/rule.xml 1.5GA版本中的规则配置比较笨,2.0中优化了一些, ...

  3. Spring Boot 学习系列(09)—自定义Bean的顺序加载

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...

  4. shiro的小白学习

    1. shiro是啥就不用说了吧 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理 SecurityManager 是shiro的核心.它不同于java. ...

  5. spring-boot整合shiro作权限认证

    spring-shiro属于轻量级权限框架,即使spring-security更新换代,市场上大多数企业还是选择shiro 废话不多说  引入pom文件 <!--shiro集成spring--& ...

  6. 一套基于SpringBoot+Vue+Shiro 前后端分离 开发的代码生成器

    一.前言 最近花了一个月时间完成了一套基于Spring Boot+Vue+Shiro前后端分离的代码生成器,目前项目代码已基本完成 止步传统CRUD,进阶代码优化: 该项目可根据数据库字段动态生成 c ...

  7. 关于postman与shiro权限验证问题

    作为一个java的开发小白 , 写完一个web方法测试是必不可少的 , 只有测试号没问题的方法给别人时 ,别人才不知道你是小白 , 要不然很尴尬的 .新手入坑的测试工具是postman .这个工具用起 ...

  8. Shiro Demo 示例(SpringMVC-Mybatis-Shiro-redis)

    Shiro Demo 准备工作 运行前申明 请看完本页面的所有细节,对你掌握这个项目来说很重要,别一上来就搞,你不爽,我也不爽. 本项目需要一定的Java功底,需要对SpringMvc,Mybatis ...

  9. SpringBoot+Shiro学习(七):Filter过滤器管理

    SpringBoot+Shiro学习(七):Filter过滤器管理 Hiwayz 关注  0.5 2018.09.06 19:09* 字数 1070 阅读 5922评论 1喜欢 20 先从我们写的一个 ...

随机推荐

  1. Java基础:(八)异常

    Throwable可以用来表示任何可以作为异常抛出的类,分为两种:Error和Exception.其中Error用来表示JVM无法处理的错误, Exception又分为两种: 受检异常:需要用try. ...

  2. FastDFS整合Nginx

    浏览器访问FastDFS存储的图片需要通过Nginx访问 需要安装fastdfs-nginx-module.Nginx 安装fastdfs-nginx-module模块 (1)将fastdfs-ngi ...

  3. Java并发(二):基础概念

    并发编程的第二部分,先来谈谈发布(Publish)与逸出(Escape); 发布是指:对象能够在当前作用域之外的代码中使用,例如:将对象的引用传递到其他类的方法中,对象的引用保存在其他类可以访问的地方 ...

  4. Generator 和 函数异步应用 笔记

    Generator > ES6 提供的一种异步编程解决方案 > Generator 函数是一个状态机,封装了多个内部状态.还是一个遍历器对象生成函数.返回<label>遍历器对 ...

  5. ServletContext--HttpServletResponse--web项目执行流程

    一.ServletContext 接口(javax.servlet) 定义:public interface ServletContext 原理:     Tomcat启动的时候,需要识别webapp ...

  6. 多线程-Thread-Runnable

    一.多线程     1.基本概念         进程:正在运行中的程序,一个进程中至少包含一个线程         线程:进程的任务,执行任务的一个通道,一个进程中可以包含多个线程     2.多线 ...

  7. File类--System.out.print(Object obj)的理解

    一.File 类(java.io) 概述:Java中使用File类来表示文件或者文件夹对象!     抽象路径名:描述文件或文件夹时,使用的路径符号,就是一个对象的字符串表示形式,如"c:\ ...

  8. 第二章 你第首个Electron应用 | Electron in Action(中译)

    本章主要内容 构建并启动Electron应用 生成package.json,配置成Electron应用 在你的项目中包含预先构建Electron版本 配置package.json以启动主进程 从主进程 ...

  9. JVM的内存划分

    1.栈内存:栈内存主要是用来运行函数的,在函数中定义的所有变量,都会在这个内存开辟空间. 在栈内存中定义的变量,不初始化,是不能直接使用的. 注意:所有的函数都必须在栈内存中运行. 而jvm只会运行处 ...

  10. LINQ 组合查询 和分页查询的使用

    前端代码 <%@ Page Language="C#" AutoEventWireup="true" Debug="true" Cod ...