zoukankan      html  css  js  c++  java
  • Shiro学习总结(10)——Spring集成Shiro

    1.引入Shiro的Maven依赖

    [html] view plain copy
    1. <!-- Spring 整合Shiro需要的依赖 -->  
    2.   
    3.     <dependency>  
    4.         <groupId>org.apache.shiro</groupId>  
    5.         <artifactId>shiro-core</artifactId>  
    6.         <version>1.2.1</version>  
    7.     </dependency>  
    8.     <dependency>  
    9.         <groupId>org.apache.shiro</groupId>  
    10.         <artifactId>shiro-web</artifactId>  
    11.         <version>1.2.1</version>  
    12.     </dependency>  
    13.     <dependency>  
    14.         <groupId>org.apache.shiro</groupId>  
    15.         <artifactId>shiro-ehcache</artifactId>  
    16.         <version>1.2.1</version>  
    17.     </dependency>  
    18.     <dependency>  
    19.         <groupId>org.apache.shiro</groupId>  
    20.         <artifactId>shiro-spring</artifactId>  
    21.         <version>1.2.1</version>  
    22.     </dependency>  
    23.     <!-- 除此之外还有一些东西也不可少spring, spring-mvc, ibatis等 spring.3.1.2 spring-mvc.3.1.2   
    24.         ibatis.2.3.4 cglib.2.2 -->  




    2.web.xml中配置


    [html] view plain copy
    1. <!-- 配置shiro的核心拦截器 -->  
    2.    <filter>    
    3.        <filter-name>shiroFilter</filter-name>    
    4.        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    
    5.    </filter>    
    6.    <filter-mapping>    
    7.        <filter-name>shiroFilter</filter-name>    
    8.        <url-pattern>/*</url-pattern>    
    9.    </filter-mapping>   




    3.    编写自己的UserRealm类继承自Realm,主要实现认证和授权的管理操作


    [java] view plain copy
    1. package com.jay.demo.shiro;  
    2.   
    3. import java.util.HashSet;  
    4. import java.util.Iterator;  
    5. import java.util.Set;  
    6.   
    7. import org.apache.shiro.authc.AuthenticationException;  
    8. import org.apache.shiro.authc.AuthenticationInfo;  
    9. import org.apache.shiro.authc.AuthenticationToken;  
    10. import org.apache.shiro.authc.LockedAccountException;  
    11. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
    12. import org.apache.shiro.authc.UnknownAccountException;  
    13. import org.apache.shiro.authz.AuthorizationInfo;  
    14. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
    15. import org.apache.shiro.realm.AuthorizingRealm;  
    16. import org.apache.shiro.subject.PrincipalCollection;  
    17. import org.springframework.beans.factory.annotation.Autowired;  
    18.   
    19. import com.jay.demo.bean.Permission;  
    20. import com.jay.demo.bean.Role;  
    21. import com.jay.demo.bean.User;  
    22. import com.jay.demo.service.UserService;  
    23.   
    24. public class UserRealm extends AuthorizingRealm{  
    25.       
    26.     @Autowired  
    27.     private UserService userService;  
    28.   
    29.     /** 
    30.      * 授权操作 
    31.      */  
    32.     @Override  
    33.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
    34. //      String username = (String) getAvailablePrincipal(principals);  
    35.         String username = (String) principals.getPrimaryPrincipal();  
    36.           
    37.         Set<Role> roleSet =  userService.findUserByUsername(username).getRoleSet();  
    38.         //角色名的集合  
    39.         Set<String> roles = new HashSet<String>();  
    40.         //权限名的集合  
    41.         Set<String> permissions = new HashSet<String>();  
    42.           
    43.         Iterator<Role> it = roleSet.iterator();  
    44.         while(it.hasNext()){  
    45.             roles.add(it.next().getName());  
    46.             for(Permission per:it.next().getPermissionSet()){  
    47.                 permissions.add(per.getName());  
    48.             }  
    49.         }  
    50.   
    51.           
    52.         SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();  
    53.           
    54.         authorizationInfo.addRoles(roles);  
    55.         authorizationInfo.addStringPermissions(permissions);  
    56.           
    57.           
    58.         return authorizationInfo;  
    59.     }  
    60.   
    61.     /** 
    62.      * 身份验证操作 
    63.      */  
    64.     @Override  
    65.     protected AuthenticationInfo doGetAuthenticationInfo(  
    66.             AuthenticationToken token) throws AuthenticationException {  
    67.           
    68.         String username = (String) token.getPrincipal();  
    69.         User user = userService.findUserByUsername(username);  
    70.           
    71.         if(user==null){  
    72.             //木有找到用户  
    73.             throw new UnknownAccountException("没有找到该账号");  
    74.         }  
    75.         /* if(Boolean.TRUE.equals(user.getLocked())) {   
    76.                 throw new LockedAccountException(); //帐号锁定   
    77.             } */  
    78.           
    79.         /** 
    80.          * 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以在此判断或自定义实现   
    81.          */  
    82.         SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(),getName());  
    83.           
    84.           
    85.         return info;  
    86.     }  
    87.       
    88.     @Override  
    89.     public String getName() {  
    90.         return getClass().getName();  
    91.     }  
    92.   
    93. }  


    4.在Spring的applicationContext.xml中进行Shiro的相关配置


    1、添加shiroFilter定义 

    Xml代码  收藏代码
    1. <!-- Shiro Filter -->  
    2. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
    3.     <property name="securityManager" ref="securityManager" />  
    4.     <property name="loginUrl" value="/login" />  
    5.     <property name="successUrl" value="/user/list" />  
    6.     <property name="unauthorizedUrl" value="/login" />  
    7.     <property name="filterChainDefinitions">  
    8.         <value>  
    9.             /login = anon  
    10.             /user/** = authc  
    11.             /role/edit/* = perms[role:edit]  
    12.             /role/save = perms[role:edit]  
    13.             /role/list = perms[role:view]  
    14.             /** = authc  
    15.         </value>  
    16.     </property>  
    17. </bean>  

    2、添加securityManager定义 
    Xml代码  收藏代码
    1. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
    2.     <property name="realm" ref="myRealm" />  
    3. </bean>  

    3、添加realm定义 
    Xml代码  收藏代码
    1. <bean id=" myRealm" class="com.jay.demo.shiro.UserRealm/>
    4、配置EhCache

      <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" />

    5、保证实现了Shiro内部lifecycle函数的bean执行

    <span class="code-tag" style="color: rgb(0, 0, 145); background-color: inherit;"><bean id=<span class="code-quote" style="color: rgb(0, 145, 0); background-color: inherit;">"lifecycleBeanPostProcessor"</span> class=<span class="code-quote" style="color: rgb(0, 145, 0); background-color: inherit;">"org.apache.shiro.spring.LifecycleBeanPostProcessor"</span>/></span>


    特别注意:

       如果使用Shiro相关的注解,需要在springmvc-servlet.xml中配置一下信息


    <span class="code-tag" style="color: rgb(0, 0, 145); background-color: inherit;"><bean class=<span class="code-quote" style="color: rgb(0, 145, 0); background-color: inherit;">"org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"</span> depends-on=<span class="code-quote" style="color: rgb(0, 145, 0); background-color: inherit;">"lifecycleBeanPostProcessor"</span>/></span>
    <span class="code-tag" style="color: rgb(0, 0, 145); background-color: inherit;"><bean class=<span class="code-quote" style="color: rgb(0, 145, 0); background-color: inherit;">"org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"</span>></span>
        <span class="code-tag" style="color: rgb(0, 0, 145); background-color: inherit;"><property name=<span class="code-quote" style="color: rgb(0, 145, 0); background-color: inherit;">"securityManager"</span> ref=<span class="code-quote" style="color: rgb(0, 145, 0); background-color: inherit;">"securityManager"</span>/></span>
    <span class="code-tag" style="color: rgb(0, 0, 145); background-color: inherit;"></bean></span>


    备注:Shiro权限管理的过滤器解释:


    [java] view plain copy
    1. 默认过滤器(10个)   
    2. anon -- org.apache.shiro.web.filter.authc.AnonymousFilter  
    3. authc -- org.apache.shiro.web.filter.authc.FormAuthenticationFilter  
    4. authcBasic -- org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter  
    5. perms -- org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter  
    6. port -- org.apache.shiro.web.filter.authz.PortFilter  
    7. rest -- org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter  
    8. roles -- org.apache.shiro.web.filter.authz.RolesAuthorizationFilter  
    9. ssl -- org.apache.shiro.web.filter.authz.SslFilter  
    10. user -- org.apache.shiro.web.filter.authc.UserFilter  
    11. logout -- org.apache.shiro.web.filter.authc.LogoutFilter  
    12.   
    13.   
    14. anon:例子/admins/**=anon 没有参数,表示可以匿名使用。   
    15. authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数   
    16. roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。   
    17. perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。   
    18. rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。   
    19. port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。   
    20. authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证   
    21. ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https   
    22. user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查   


    关于Shiro的标签应用:

    [java] view plain copy
    1. <shiro:authenticated> 登录之后  
    2. <shiro:notAuthenticated> 不在登录状态时  
    3. <shiro:guest> 用户在没有RememberMe时  
    4. <shiro:user> 用户在RememberMe时  
    5. <shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色时  
    6. <shiro:hasRole name="abc"> 拥有角色abc  
    7. <shiro:lacksRole name="abc"> 没有角色abc  
    8. <shiro:hasPermission name="abc"> 拥有权限abc  
    9. <shiro:lacksPermission name="abc"> 没有权限abc  
    10. <shiro:principal> 显示用户登录名  


    以上是Shiro的相关配置,出于安全的考虑,一般都会使用ACL(基于角色的用户权限管理去控制用户登录后的权限)

    ACL详细代码案例如下:


    涉及到的表:3+2(User,Role,Permission  +  user-role,role-permission)

    3张实体表+2张关系表

    1.关于User类:

    [java] view plain copy
    1. package com.jay.demo.bean;  
    2.   
    3. import java.util.HashSet;  
    4. import java.util.Set;  
    5.   
    6. public class User {  
    7.     private String id;  
    8.     private String username;  
    9.     private String password;  
    10.     private Set<Role> roleSet = new HashSet<Role>();  
    11.       
    12.     public User() {  
    13.     }  
    14.   
    15.     public String getId() {  
    16.         return id;  
    17.     }  
    18.   
    19.     public void setId(String id) {  
    20.         this.id = id;  
    21.     }  
    22.   
    23.     public String getUsername() {  
    24.         return username;  
    25.     }  
    26.   
    27.     public void setUsername(String username) {  
    28.         this.username = username;  
    29.     }  
    30.   
    31.     public String getPassword() {  
    32.         return password;  
    33.     }  
    34.   
    35.     public void setPassword(String password) {  
    36.         this.password = password;  
    37.     }  
    38.   
    39.     public Set<Role> getRoleSet() {  
    40.         return roleSet;  
    41.     }  
    42.   
    43.     public void setRoleSet(Set<Role> roleSet) {  
    44.         this.roleSet = roleSet;  
    45.     }  
    46.   
    47.       
    48. }  


    2.关于Role表

    [java] view plain copy
    1. package com.jay.demo.bean;  
    2.   
    3. import java.io.Serializable;  
    4. import java.util.HashSet;  
    5. import java.util.Set;  
    6.   
    7. public class Role implements Serializable {  
    8.   
    9.     private static final long serialVersionUID = -4987248128309954399L;  
    10.   
    11.     private Integer id;  
    12.     private String name;  
    13.     private Set<Permission> permissionSet = new HashSet<Permission>();  
    14.   
    15.     public Role() {  
    16.         super();  
    17.     }  
    18.       
    19.     // --------------------------------------------------------------------------------  
    20.   
    21.     @Override  
    22.     public int hashCode() {  
    23.         final int prime = 31;  
    24.         int result = 1;  
    25.         result = prime * result + ((id == null) ? 0 : id.hashCode());  
    26.         return result;  
    27.     }  
    28.   
    29.     @Override  
    30.     public boolean equals(Object obj) {  
    31.         if (this == obj)  
    32.             return true;  
    33.         if (obj == null)  
    34.             return false;  
    35.         if (getClass() != obj.getClass())  
    36.             return false;  
    37.         Role other = (Role) obj;  
    38.         if (id == null) {  
    39.             if (other.id != null)  
    40.                 return false;  
    41.         } else if (!id.equals(other.id))  
    42.             return false;  
    43.         return true;  
    44.     }  
    45.       
    46.     // --------------------------------------------------------------------------------  
    47.   
    48.     public Integer getId() {  
    49.         return id;  
    50.     }  
    51.   
    52.     public void setId(Integer id) {  
    53.         this.id = id;  
    54.     }  
    55.   
    56.     public String getName() {  
    57.         return name;  
    58.     }  
    59.   
    60.     public void setName(String name) {  
    61.         this.name = name;  
    62.     }  
    63.   
    64.     public Set<Permission> getPermissionSet() {  
    65.         return permissionSet;  
    66.     }  
    67.   
    68.     public void setPermissionSet(Set<Permission> permissionSet) {  
    69.         this.permissionSet = permissionSet;  
    70.     }  
    71.   
    72. }  


    3.关于permission表

    [java] view plain copy
    1. <pre name="code" class="java">package com.jay.demo.bean;  
    2.   
    3. import java.io.Serializable;  
    4.   
    5. public class Permission implements Serializable {  
    6.   
    7.     private static final long serialVersionUID = -8025597823572680802L;  
    8.   
    9.     private Integer id;  
    10.     private String name;  
    11.   
    12.     public Permission() {  
    13.         super();  
    14.     }  
    15.   
    16.     // --------------------------------------------------------------------------------------  
    17.   
    18.     @Override  
    19.     public int hashCode() {  
    20.         final int prime = 31;  
    21.         int result = 1;  
    22.         result = prime * result + ((id == null) ? 0 : id.hashCode());  
    23.         return result;  
    24.     }  
    25.   
    26.     @Override  
    27.     public boolean equals(Object obj) {  
    28.         if (this == obj)  
    29.             return true;  
    30.         if (obj == null)  
    31.             return false;  
    32.         if (getClass() != obj.getClass())  
    33.             return false;  
    34.         Permission other = (Permission) obj;  
    35.         if (id == null) {  
    36.             if (other.id != null)  
    37.                 return false;  
    38.         } else if (!id.equals(other.id))  
    39.             return false;  
    40.         return true;  
    41.     }  
    42.   
    43.     // --------------------------------------------------------------------------------------  
    44.   
    45.     public Integer getId() {  
    46.         return id;  
    47.     }  
    48.   
    49.     public void setId(Integer id) {  
    50.         this.id = id;  
    51.     }  
    52.   
    53.     public String getName() {  
    54.         return name;  
    55.     }  
    56.   
    57.     public void setName(String name) {  
    58.         this.name = name;  
    59.     }  
    60.   
    61. }  


    
    

    4.dao层接口

    [java] view plain copy
    1. package com.jay.demo.dao;  
    2.   
    3. import com.jay.demo.bean.User;  
    4.   
    5. public interface UserDao {  
    6.       
    7.     User findUserByUsername(String username);   
    8. }  


    4.使用Mybatis完成的Dao层实现


    [html] view plain copy
    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >  
    3. <mapper namespace="com.jay.demo.dao.UserDao">  
    4.     <resultMap id="userMap" type="com.jay.demo.bean.User">  
    5.     <id property="id" column="USER_ID"/>  
    6.     <result property="username" column="USER_USERNAME"/>  
    7.     <result property="password" column="USER_PASSWORD"/>  
    8.     <!-- 进行 多表关联插叙,先关联user和role -->  
    9.     <collection property="roleSet" column="roleid" ofType="com.jay.demo.bean.Role">  
    10.     <id property="id" column="ROLE_ID"/>  
    11.     <result property="name" column="ROLE_NAME"/>  
    12.     <!-- 再在role中关联role和permission -->  
    13.     <collection property="permissionSet" column="permissionid" ofType="com.jay.demo.bean.Permission">  
    14.     <id property="id" column="permission_id"/>  
    15.     <result property="name" column="permission_name"/>  
    16.     </collection>  
    17.     </collection>  
    18.       
    19.     </resultMap>  
    20.       
    21.       
    22.       
    23.       
    24.     <!--  通过User来查找Role   -->    
    25.     <!-- <select id="selectRoleByUser" parameterType="int" resultMap="RoleMap">    
    26.         select * from tbl_role_user user_id  = #{id}     
    27.     </select>    
    28.       
    29.   
    30.     <resultMap  id="roleMap" type="com.jay.demo.bean.User">  
    31.         <result property="id" column="ROLE_ID" />  
    32.         <result property="name" column="ROLE_NAME" />  
    33.     </resultMap>  
    34.       
    35.     <resultMap id="permissionMap" type="com.jay.demo.bean.Permission">  
    36.         <result property="id" column="PERMISSION_ID" />  
    37.         <result property="name" column="PERMISSION_NAME" />  
    38.     </resultMap> -->  
    39.       
    40.       
    41.   
    42. <sql id="select-base-01">    
    43.         SELECT     
    44.             u.USER_ID,    
    45.             u.USER_USERNAME,    
    46.             u.USER_PASSWORD,    
    47.             r.ROLE_ID,    
    48.             r.ROLE_NAME,    
    49.             p.PERMISSION_ID,    
    50.             p.PERMISSION_NAME    
    51.         FROM    
    52.           tbl_user as u,    
    53.           tbl_role as r,    
    54.           tbl_permission as p,    
    55.           tbl_permission_role as pr,    
    56.           tbl_role_user as ru    
    57.         WHERE    
    58.           u.USER_ID = ru.USER_ID    
    59.         AND    
    60.           r.ROLE_ID = ru.ROLE_ID    
    61.         AND    
    62.           p.PERMISSION_ID = pr.PERMISSION_ID    
    63.         AND    
    64.           r.ROLE_ID = pr.ROLE_ID    
    65.     </sql>    
    66.       
    67.     <select id="findUserByUsername" parameterType="string" resultMap="userMap">    
    68.        <include refid="select-base-01" />    
    69.         AND    
    70.             u.USER_USERNAME = #{username}      
    71.             <!-- select * from tbl_user u, tbl_role r, tbl_role_user tu   
    72.             where u.user_id = tu.user_id and r.role_id = tu.role_id   
    73.             and user_username=#{username} -->  
    74.     </select>  
    75.       
    76. </mapper>  
  • 相关阅读:
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    OA办公系统 Springboot Activiti6 工作流 集成代码生成器 vue.js 前后分离 跨域
    java企业官网源码 自适应响应式 freemarker 静态引擎 SSM 框架
    java OA办公系统源码 Springboot Activiti工作流 vue.js 前后分离 集成代码生成器
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    java 视频播放 弹幕技术 视频弹幕 视频截图 springmvc mybatis SSM
    最后阶段总结
    第二阶段学习总结
    第一阶段学习总结
  • 原文地址:https://www.cnblogs.com/zhanghaiyang/p/7213123.html
Copyright © 2011-2022 走看看