apache-shiro 学习笔记

使用过Spring Security 3,了解到shiro,没时间自己研究,就先转个博客学习一下,在这里做下记录,另外找时间比较一下二者的区别。

原文地址:http://yingzhuo.iteye.com/blog/1709002


(一) 看到SpringSide4居然也用shiro作为安全框架,不是用的spring-security。着实有点惊讶。 

apache-shiro的强大可见一斑。 

(二) apache-shiro依赖的包 
Xml代码   收藏代码
  1. <dependency>  
  2.     <groupId>org.apache.shiro</groupId>  
  3.     <artifactId>shiro-core</artifactId>  
  4.     <version>1.2.1</version>  
  5. </dependency>  
  6. <dependency>  
  7.     <groupId>org.apache.shiro</groupId>  
  8.     <artifactId>shiro-web</artifactId>  
  9.     <version>1.2.1</version>  
  10. </dependency>  
  11. <dependency>  
  12.     <groupId>org.apache.shiro</groupId>  
  13.     <artifactId>shiro-ehcache</artifactId>  
  14.     <version>1.2.1</version>  
  15. </dependency>  
  16. <dependency>  
  17.     <groupId>org.apache.shiro</groupId>  
  18.     <artifactId>shiro-spring</artifactId>  
  19.     <version>1.2.1</version>  
  20. </dependency>  

除此之外还有一些东西也不可少spring, spring-mvc, ibatis等 
  • spring.3.1.2
  • spring-mvc.3.1.2
  • ibatis.2.3.4
  • cglib.2.2


(三) demo采取比较典型的“User-Role-Permission”模型 
Sql代码   收藏代码
  1. -- -----------------------------------------------------  
  2. -- Table `shiro`.`TBL_PERMISSION`  
  3. -- -----------------------------------------------------  
  4. DROP TABLE IF EXISTS `shiro`.`TBL_PERMISSION` ;  
  5.   
  6. CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_PERMISSION` (  
  7.   `PERMISSION_ID` INT NOT NULL AUTO_INCREMENT ,  
  8.   `PERMISSION_NAME` VARCHAR(45) NULL ,  
  9.   PRIMARY KEY (`PERMISSION_ID`) ,  
  10.   UNIQUE INDEX `PERMISSION_NAME_UNIQUE` (`PERMISSION_NAME` ASC) )  
  11. ENGINE = InnoDB;  
  12.   
  13. -- -----------------------------------------------------  
  14. -- Table `shiro`.`TBL_ROLE`  
  15. -- -----------------------------------------------------  
  16. DROP TABLE IF EXISTS `shiro`.`TBL_ROLE` ;  
  17.   
  18. CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_ROLE` (  
  19.   `ROLE_ID` INT NOT NULL AUTO_INCREMENT ,  
  20.   `ROLE_NAME` VARCHAR(45) NULL ,  
  21.   PRIMARY KEY (`ROLE_ID`) ,  
  22.   UNIQUE INDEX `ROLE_NAME_UNIQUE` (`ROLE_NAME` ASC) )  
  23. ENGINE = InnoDB;  
  24.   
  25. -- -----------------------------------------------------  
  26. -- Table `shiro`.`TBL_USER`  
  27. -- -----------------------------------------------------  
  28. DROP TABLE IF EXISTS `shiro`.`TBL_USER` ;  
  29.   
  30. CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_USER` (  
  31.   `USER_ID` INT NOT NULL AUTO_INCREMENT ,  
  32.   `USER_USERNAME` VARCHAR(45) NOT NULL ,  
  33.   `USER_PASSWORD` CHAR(32) NOT NULL ,  
  34.   PRIMARY KEY (`USER_ID`) ,  
  35.   UNIQUE INDEX `USER_USERNAME_UNIQUE` (`USER_USERNAME` ASC) )  
  36. ENGINE = InnoDB;  
  37.   
  38. -- -----------------------------------------------------  
  39. -- Table `shiro`.`TBL_PERMISSION_ROLE`  
  40. -- -----------------------------------------------------  
  41. DROP TABLE IF EXISTS `shiro`.`TBL_PERMISSION_ROLE` ;  
  42.   
  43. CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_PERMISSION_ROLE` (  
  44.   `ROLE_ID` INT NOT NULL ,  
  45.   `PERMISSION_ID` INT NOT NULL ,  
  46.   PRIMARY KEY (`ROLE_ID`, `PERMISSION_ID`) )  
  47. ENGINE = InnoDB;  
  48.   
  49. -- -----------------------------------------------------  
  50. -- Table `shiro`.`TBL_ROLE_USER`  
  51. -- -----------------------------------------------------  
  52. DROP TABLE IF EXISTS `shiro`.`TBL_ROLE_USER` ;  
  53.   
  54. CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_ROLE_USER` (  
  55.   `ROLE_ID` INT NOT NULL ,  
  56.   `USER_ID` INT NOT NULL ,  
  57.   PRIMARY KEY (`ROLE_ID`, `USER_ID`) )  
  58. ENGINE = InnoDB;  


自己实现一个UserDao, ibatis实现。 
这个不是本文要记述的重点,简单贴一下代码。 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">  
  3. <sqlMap namespace="user">  
  4.   
  5.     <typeAlias alias="User" type="com.ztgame.sd.domain.User"/>  
  6.   
  7.     <resultMap class="User" id="result-map-01" groupBy="id">  
  8.         <result property="id" column="USER_ID" />  
  9.         <result property="username" column="USER_USERNAME" />  
  10.         <result property="password" column="USER_PASSWORD" />  
  11.         <result property="roleSet" resultMap="role.result-map-01" />  
  12.     </resultMap>  
  13.       
  14.     <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->  
  15.   
  16.     <sql id="select-base-01">  
  17.         SELECT   
  18.             u.USER_ID,  
  19.             u.USER_USERNAME,  
  20.             u.USER_PASSWORD,  
  21.             r.ROLE_ID,  
  22.             r.ROLE_NAME,  
  23.             p.PERMISSION_ID,  
  24.             p.PERMISSION_NAME  
  25.         FROM  
  26.           tbl_user as u,  
  27.           tbl_role as r,  
  28.           tbl_permission as p,  
  29.           tbl_permission_role as pr,  
  30.           tbl_role_user as ru  
  31.         WHERE  
  32.           u.USER_ID = ru.USER_ID  
  33.         AND  
  34.           r.ROLE_ID = ru.ROLE_ID  
  35.         AND  
  36.           p.PERMISSION_ID = pr.PERMISSION_ID  
  37.         AND  
  38.           r.ROLE_ID = pr.ROLE_ID  
  39.     </sql>  
  40.       
  41.     <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->  
  42.       
  43.     <select id="select-01" parameterClass="string" resultMap="result-map-01">  
  44.         <include refid="select-base-01" />  
  45.         AND  
  46.             u.USER_USERNAME = #username#  
  47.     </select>  
  48.   
  49. </sqlMap>  

Java代码   收藏代码
  1. public interface UserDao {  
  2.   
  3.     User findUserByUsername(String username);  
  4.   
  5. }  
  6.   
  7. @Repository("userDao")  
  8. public class UserDaoImpl implements UserDao {  
  9.   
  10.     @Resource  
  11.     private SqlMapClientTemplate sqlMapClientTemplate;  
  12.       
  13.     @Override  
  14.     public User findUserByUsername(String username) {  
  15.         Validate.notEmpty(username, "用户名不可为null或empty string");  
  16.         return (User) sqlMapClientTemplate.queryForObject("user.select-01", username);  
  17.     }  
  18.   
  19. }  


(三) 用户和权限数据源是自己设计的,应该实现自己的Realm对象。 
Java代码   收藏代码
  1. package com.ztgame.sd.security.realm;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.   
  6. import org.apache.shiro.authc.AuthenticationException;  
  7. import org.apache.shiro.authc.AuthenticationInfo;  
  8. import org.apache.shiro.authc.AuthenticationToken;  
  9. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  10. import org.apache.shiro.authc.UsernamePasswordToken;  
  11. import org.apache.shiro.authz.AuthorizationInfo;  
  12. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  13. import org.apache.shiro.realm.AuthorizingRealm;  
  14. import org.apache.shiro.realm.Realm;  
  15. import org.apache.shiro.subject.PrincipalCollection;  
  16. import org.springframework.beans.factory.InitializingBean;  
  17. import org.springframework.util.Assert;  
  18.   
  19. import com.ztgame.sd.dao.UserDao;  
  20. import com.ztgame.sd.domain.Permission;  
  21. import com.ztgame.sd.domain.Role;  
  22. import com.ztgame.sd.domain.User;  
  23.   
  24. public class JdbcRealm extends AuthorizingRealm   
  25.     implements  
  26.             Realm,   
  27.             InitializingBean  
  28. {  
  29.   
  30.     private UserDao userDao;  
  31.   
  32.     // ------------------------------------------------------------------------------------------------------------  
  33.   
  34.     @Override  
  35.     public void afterPropertiesSet() throws Exception {  
  36.         Assert.notNull(userDao);  
  37.     }  
  38.   
  39.     // ------------------------------------------------------------------------------------------------------------  
  40.   
  41.     @Override  
  42.     public String getName() {  
  43.         return getClass().getName();  
  44.     }  
  45.   
  46.     @Override  
  47.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
  48.           
  49.         String username = (String) super.getAvailablePrincipal(principals);  
  50.         User user = userDao.findUserByUsername(username);  
  51.           
  52.         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  53.         Set<String> roles = new HashSet<String>();  
  54.         Set<String> permissions = new HashSet<String>();  
  55.   
  56.         for (Role role : user.getRoleSet()) {  
  57.             roles.add(role.getName());  
  58.             for (Permission per : role.getPermissionSet()) {  
  59.                 permissions.add(per.getName());  
  60.             }  
  61.         }  
  62.   
  63.         info.addRoles(roles);  
  64.         info.addStringPermissions(permissions);  
  65.   
  66.         return info;  
  67.     }  
  68.   
  69.     @Override  
  70.     protected AuthenticationInfo doGetAuthenticationInfo(  
  71.             AuthenticationToken token) throws AuthenticationException {  
  72.   
  73.         SimpleAuthenticationInfo info = null;  
  74.   
  75.         UsernamePasswordToken upt = (UsernamePasswordToken) token;  
  76.         String username = upt.getUsername();  
  77.         User user = userDao.findUserByUsername(username);  
  78.           
  79.         if (user == null) {  
  80.             throw new AuthenticationException();  
  81.         }  
  82.   
  83.         info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());  
  84.   
  85.         return info;  
  86.     }  
  87.   
  88.     // ------------------------------------------------------------------------------------------------------------  
  89.   
  90.     public void setUserDao(UserDao userDao) {  
  91.         this.userDao = userDao;  
  92.     }  
  93.   
  94. }  


(四) apache-shiro的配置 
web.xml 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  5.       
  6.     <!-- apache-shiro 核心拦截器 -->  
  7.     <filter>  
  8.         <filter-name>shiroFilter</filter-name>  
  9.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  10.     </filter>  
  11.     <filter-mapping>  
  12.         <filter-name>shiroFilter</filter-name>  
  13.         <url-pattern>/*</url-pattern>  
  14.     </filter-mapping>  
  15.   
  16.     <!-- 其他无关apache-shiro -->  
  17.   
  18. </web-app>  


spring-shiro.xml 
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:p="http://www.springframework.org/schema/p"  
  4.     xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  6.     xmlns:context="http://www.springframework.org/schema/context"  
  7.     xsi:schemaLocation="  
  8.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  9.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd  
  10.         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
  11.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
  12.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">  
  13.           
  14.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  15.   
  16.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  17.         <property name="securityManager" ref="securityManager" />  
  18.         <property name="loginUrl" value="/login" />  
  19.         <property name="successUrl" value="/login/loginSuccessFull" />  
  20.         <property name="unauthorizedUrl" value="/login/unauthorized" />  
  21.         <!--  
  22.         <property name="filterChainDefinitions">  
  23.             <value>  
  24.                 / = anon  
  25.             </value>  
  26.         </property>  
  27.         -->  
  28.     </bean>  
  29.   
  30.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  31.         <property name="authenticator" ref="authenticator" />  
  32.         <property name="sessionManager" ref="sessionManager" />  
  33.         <property name="cacheManager" ref="cacheManager" />  
  34.         <property name="realms">  
  35.             <list>  
  36.                 <bean class="com.ztgame.sd.security.realm.JdbcRealm">  
  37.                     <property name="userDao" ref="userDao" />  
  38.                     <property name="credentialsMatcher" ref="hashedCredentialsMatcher" />  
  39.                 </bean>  
  40.             </list>  
  41.         </property>  
  42.     </bean>  
  43.   
  44.     <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator" />    
  45.   
  46.     <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  47.         <property name="sessionDAO" ref="sessionDAO" />  
  48.     </bean>  
  49.   
  50.     <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" />  
  51.   
  52.     <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO" />  
  53.   
  54.     <bean id="hashedCredentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">  
  55.         <property name="hashAlgorithmName" value="MD5" />  
  56.         <property name="storedCredentialsHexEncoded" value="true" />  
  57.         <property name="hashIterations" value="1" />  
  58.     </bean>  
  59. </beans>  


spring-mvc.xml 
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:p="http://www.springframework.org/schema/p"  
  4.     xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"  
  7.     xsi:schemaLocation="  
  8.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  9.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd  
  10.         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
  11.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
  12.         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
  13.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">  
  14.   
  15.     <!-- 其他spring-mvc框架配置 -->  
  16.   
  17.     <!--   
  18.         以下两个bean的配置是为了在Controller层使用元注释控制权限  
  19.         如果使用spring-mvc一定要不要放在webroot的配置文件中  
  20.      -->  
  21.     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />  
  22.   
  23.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  24.         <property name="securityManager" ref="securityManager" />  
  25.     </bean>  
  26.   
  27. </beans>  


(五) jsp-taglib 支持 
  • <shiro:authenticated> 登录之后
  • <shiro:notAuthenticated> 不在登录状态时
  • <shiro:guest> 用户在没有RememberMe时
  • <shiro:user> 用户在RememberMe时
  • <shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色时
  • <shiro:hasRole name="abc"> 拥有角色abc
  • <shiro:lacksRole name="abc"> 没有角色abc
  • <shiro:hasPermission name="abc"> 拥有权限abc
  • <shiro:lacksPermission name="abc"> 没有权限abc
  • <shiro:principal> 显示用户登录名

[官方文档]  http://shiro.apache.org/web.html#Web-taglibrary  

(六) 默认过滤器(10个) 
  • anon -- org.apache.shiro.web.filter.authc.AnonymousFilter
  • authc -- org.apache.shiro.web.filter.authc.FormAuthenticationFilter
  • authcBasic -- org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
  • perms -- org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
  • port -- org.apache.shiro.web.filter.authz.PortFilter
  • rest -- org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
  • roles -- org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
  • ssl -- org.apache.shiro.web.filter.authz.SslFilter
  • user -- org.apache.shiro.web.filter.authc.UserFilter
  • logout -- org.apache.shiro.web.filter.authc.LogoutFilter


anon:例子/admins/**=anon 没有参数,表示可以匿名使用。 
authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数 
roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。 
perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。 
rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。 
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。 
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证 
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https 
user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查 
[官方文档]  http://shiro.apache.org/web.html#Web-FilterChainDefinitions  

(七) 常用元注释 
  • @RequiresAuthentication 验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时
  • @RequiresUser 验证用户是否被记忆,user有两种含义:一种是成功登录的(subject.isAuthenticated()结果为true)另外一种是被记忆的(subject.isRemembered()结果为true)
  • @RequiresGuest 验证是否为匿名请求
  • @RequiresRoles 必须要有角色
  • @RequiresPermissions 必须要有权限
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值