Springmvc+Shiro实战

原文链接:http://blog.csdn.net/qq_37936542/article/details/79010449

springmvc+shiro实现系统粗细粒度的权限管理步骤:

1:表格设计

2:配置maven依赖

3:web.xml配置shiro过滤器

4:web.xml引入applicationContext-shiro.xml的配置文件

5:配置applicationContext-shiro.xml配置文件

6:配置shiro缓存文件

7:自定义realm实现用户认证和授权

8:实现登录逻辑

9:页面控制权限


一:表格设计(一个用户对应一个系统角色,一个系统角色具有多个操作权限)









二:导入相关依赖 pom.xml

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.     <groupId>debo</groupId>  
  5.     <artifactId>debo</artifactId>  
  6.     <version>0.0.1-SNAPSHOT</version>  
  7.     <packaging>war</packaging>  
  8.     <properties>  
  9.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  10.         <spring.version>4.3.6.RELEASE</spring.version>  
  11.     </properties>  
  12.     <dependencies>  
  13.         <!-- 导入java ee jar 包 -->  
  14.         <dependency>  
  15.             <groupId>javax</groupId>  
  16.             <artifactId>javaee-api</artifactId>  
  17.             <version>6.0</version>  
  18.             <scope>provided</scope>  
  19.         </dependency>  
  20.         <dependency>  
  21.             <groupId>javax</groupId>  
  22.             <artifactId>javaee-web-api</artifactId>  
  23.             <version>6.0</version>  
  24.             <scope>provided</scope>  
  25.         </dependency>  
  26.         <dependency>  
  27.             <groupId>javax.servlet</groupId>  
  28.             <artifactId>servlet-api</artifactId>  
  29.             <version>2.5</version>  
  30.             <scope>provided</scope>  
  31.         </dependency>  
  32.         <dependency>  
  33.             <groupId>javax.servlet</groupId>  
  34.             <artifactId>jstl</artifactId>  
  35.             <version>1.2</version>  
  36.         </dependency>  
  37.         <!-- spring框架包 start -->  
  38.         <dependency>  
  39.             <groupId>org.springframework</groupId>  
  40.             <artifactId>spring-test</artifactId>  
  41.             <version>${spring.version}</version>  
  42.         </dependency>  
  43.         <dependency>  
  44.             <groupId>org.springframework</groupId>  
  45.             <artifactId>spring-core</artifactId>  
  46.             <version>${spring.version}</version>  
  47.         </dependency>  
  48.         <dependency>  
  49.             <groupId>org.springframework</groupId>  
  50.             <artifactId>spring-oxm</artifactId>  
  51.             <version>${spring.version}</version>  
  52.         </dependency>  
  53.         <dependency>  
  54.             <groupId>org.springframework</groupId>  
  55.             <artifactId>spring-tx</artifactId>  
  56.             <version>${spring.version}</version>  
  57.         </dependency>  
  58.         <dependency>  
  59.             <groupId>org.springframework</groupId>  
  60.             <artifactId>spring-jdbc</artifactId>  
  61.             <version>${spring.version}</version>  
  62.         </dependency>  
  63.         <dependency>  
  64.             <groupId>org.springframework</groupId>  
  65.             <artifactId>spring-aop</artifactId>  
  66.             <version>${spring.version}</version>  
  67.         </dependency>  
  68.         <dependency>  
  69.             <groupId>org.springframework</groupId>  
  70.             <artifactId>spring-context</artifactId>  
  71.             <version>${spring.version}</version>  
  72.         </dependency>  
  73.         <dependency>  
  74.             <groupId>org.springframework</groupId>  
  75.             <artifactId>spring-context-support</artifactId>  
  76.             <version>${spring.version}</version>  
  77.         </dependency>  
  78.         <dependency>  
  79.             <groupId>org.springframework</groupId>  
  80.             <artifactId>spring-expression</artifactId>  
  81.             <version>${spring.version}</version>  
  82.         </dependency>  
  83.         <dependency>  
  84.             <groupId>org.springframework</groupId>  
  85.             <artifactId>spring-orm</artifactId>  
  86.             <version>${spring.version}</version>  
  87.         </dependency>  
  88.         <dependency>  
  89.             <groupId>org.springframework</groupId>  
  90.             <artifactId>spring-web</artifactId>  
  91.             <version>${spring.version}</version>  
  92.         </dependency>  
  93.         <dependency>  
  94.             <groupId>org.springframework</groupId>  
  95.             <artifactId>spring-webmvc</artifactId>  
  96.             <version>${spring.version}</version>  
  97.         </dependency>  
  98.         <dependency>  
  99.             <groupId>org.springframework</groupId>  
  100.             <artifactId>spring-websocket</artifactId>  
  101.             <version>${spring.version}</version>  
  102.         </dependency>  
  103.         <dependency>  
  104.             <groupId>org.aspectj</groupId>  
  105.             <artifactId>aspectjrt</artifactId>  
  106.             <version>1.8.10</version>  
  107.         </dependency>  
  108.         <dependency>  
  109.             <groupId>org.aspectj</groupId>  
  110.             <artifactId>aspectjweaver</artifactId>  
  111.             <version>1.6.12</version>  
  112.         </dependency>  
  113.         <dependency>  
  114.             <groupId>org.springframework</groupId>  
  115.             <artifactId>spring-messaging</artifactId>  
  116.             <version>${spring.version}</version>  
  117.         </dependency>  
  118.         <!-- spring框架包 end -->  
  119.   
  120.         <!-- mybatis框架包 start -->  
  121.         <dependency>  
  122.             <groupId>org.mybatis</groupId>  
  123.             <artifactId>mybatis</artifactId>  
  124.             <version>3.3.0</version>  
  125.         </dependency>  
  126.         <dependency>  
  127.             <groupId>org.mybatis</groupId>  
  128.             <artifactId>mybatis-spring</artifactId>  
  129.             <version>1.3.0</version>  
  130.         </dependency>  
  131.         <!-- mybatis框架包 end -->  
  132.   
  133.         <!-- shiro -->  
  134.         <dependency>  
  135.             <groupId>org.apache.shiro</groupId>  
  136.             <artifactId>shiro-core</artifactId>  
  137.             <version>1.3.2</version>  
  138.         </dependency>  
  139.         <dependency>  
  140.             <groupId>org.apache.shiro</groupId>  
  141.             <artifactId>shiro-web</artifactId>  
  142.             <version>1.3.2</version>  
  143.         </dependency>  
  144.         <dependency>  
  145.             <groupId>org.apache.shiro</groupId>  
  146.             <artifactId>shiro-spring</artifactId>  
  147.             <version>1.3.2</version>  
  148.         </dependency>  
  149.         <dependency>  
  150.             <groupId>org.apache.shiro</groupId>  
  151.             <artifactId>shiro-ehcache</artifactId>  
  152.             <version>1.3.2</version>  
  153.         </dependency>  
  154.   
  155.         <!-- log4j -->  
  156.         <dependency>  
  157.             <groupId>log4j</groupId>  
  158.             <artifactId>log4j</artifactId>  
  159.             <version>1.2.16</version>  
  160.         </dependency>  
  161.   
  162.         <!-- lang3 -->  
  163.         <dependency>  
  164.             <groupId>org.apache.commons</groupId>  
  165.             <artifactId>commons-lang3</artifactId>  
  166.             <version>3.6</version>  
  167.         </dependency>  
  168.   
  169.         <!-- dhcp连接池 -->  
  170.         <dependency>  
  171.             <groupId>commons-dbcp</groupId>  
  172.             <artifactId>commons-dbcp</artifactId>  
  173.             <version>1.4</version>  
  174.         </dependency>  
  175.   
  176.         <!-- MySql -->  
  177.         <dependency>  
  178.             <groupId>mysql</groupId>  
  179.             <artifactId>mysql-connector-java</artifactId>  
  180.             <version>5.1.38</version>  
  181.         </dependency>  
  182.   
  183.         <!-- poi -->  
  184.         <dependency>  
  185.             <groupId>org.apache.poi</groupId>  
  186.             <artifactId>poi</artifactId>  
  187.             <version>3.17</version>  
  188.         </dependency>  
  189.         <dependency>  
  190.             <groupId>org.apache.poi</groupId>  
  191.             <artifactId>poi-ooxml-schemas</artifactId>  
  192.             <version>3.17</version>  
  193.         </dependency>  
  194.         <dependency>  
  195.             <groupId>org.apache.poi</groupId>  
  196.             <artifactId>poi-ooxml</artifactId>  
  197.             <version>3.17</version>  
  198.         </dependency>  
  199.   
  200.         <!-- jack json -->  
  201.         <dependency>  
  202.             <groupId>com.fasterxml.jackson.core</groupId>  
  203.             <artifactId>jackson-core</artifactId>  
  204.             <version>2.7.3</version>  
  205.         </dependency>  
  206.         <dependency>  
  207.             <groupId>com.fasterxml.jackson.core</groupId>  
  208.             <artifactId>jackson-annotations</artifactId>  
  209.             <version>2.7.3</version>  
  210.         </dependency>  
  211.         <dependency>  
  212.             <groupId>com.fasterxml.jackson.core</groupId>  
  213.             <artifactId>jackson-databind</artifactId>  
  214.             <version>2.7.3</version>  
  215.         </dependency>  
  216.   
  217.         <!-- commons-io -->  
  218.         <dependency>  
  219.             <groupId>commons-io</groupId>  
  220.             <artifactId>commons-io</artifactId>  
  221.             <version>2.4</version>  
  222.         </dependency>  
  223.   
  224.         <dependency>  
  225.             <groupId>commons-fileupload</groupId>  
  226.             <artifactId>commons-fileupload</artifactId>  
  227.             <version>1.3.1</version>  
  228.         </dependency>  
  229.   
  230.     </dependencies>  
  231.     <build>  
  232.         <plugins>  
  233.             <plugin>  
  234.                 <artifactId>maven-compiler-plugin</artifactId>  
  235.                 <version>2.3.2</version>  
  236.                 <configuration>  
  237.                     <source>1.7</source>  
  238.                     <target>1.7</target>  
  239.                 </configuration>  
  240.             </plugin>  
  241.             <plugin>  
  242.                 <artifactId>maven-war-plugin</artifactId>  
  243.                 <version>2.2</version>  
  244.                 <configuration>  
  245.                     <version>3.1</version>  
  246.                     <failOnMissingWebXml>false</failOnMissingWebXml>  
  247.                 </configuration>  
  248.             </plugin>  
  249.         </plugins>  
  250.     </build>  
  251. </project>  


三:web.xml配置shiro拦截器

  1. <!-- 这里的filter-name 要和spring 的applicationContext-shiro.xml 里的  
  2. g.apache.shiro.spring.web.ShiroFilterFactoryBean 的bean name 相同 -->  
  3.   <filter>  
  4.       <filter-name>shiroFilter</filter-name>  
  5.       <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  6.       <init-param>  
  7.           <param-name>targetFilterLifecycle</param-name>  
  8.           <param-value>true</param-value>  
  9.       </init-param>  
  10.   </filter>  
  11.   <filter-mapping>  
  12.       <filter-name>shiroFilter</filter-name>  
  13.       <url-pattern>/*</url-pattern>  
  14.   </filter-mapping>  


四:web.xml引入applicationContext-shiro.xml文件
  1. <!-- springmvc控制器 -->  
  2.     <servlet>  
  3.         <servlet-name>dispatcherServlet</servlet-name>  
  4.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  5.         <!-- 加载springmvc配置文件 -->  
  6.         <init-param>  
  7.             <param-name>contextConfigLocation</param-name>  
  8.             <param-value>classpath:spring/springmvc-servlet.xml,classpath:spring/applicationContext*.xml</param-value>  
  9.         </init-param>  
  10.         <load-on-startup>1</load-on-startup>  
  11.     </servlet>  
  12.     <servlet-mapping>  
  13.         <servlet-name>dispatcherServlet</servlet-name>  
  14.         <url-pattern>/</url-pattern>  
  15.     </servlet-mapping>  

配置文件目录结构:




五:配置applicationContext-shiro.xml文件
  1.     <!-- 配置shiro安全管理器 -->  
  2.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  3.         <property name="realm" ref="shiroDbRealm"/>  
  4.         <!-- 配置缓存 -->  
  5.         <property name="cacheManager" ref="cacheManager"/>  
  6.     </bean>  
  7.   
  8.     <!-- 自定义的Realm:用于用户的认证和授权 -->  
  9.     <bean id="shiroDbRealm" class="com.debo.login.controller.ShiroDbRealm"/>  
  10.      
  11.     <!-- 此bean要被web.xml引用,和web.xml中的filtername同名 -->  
  12.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  13.         <property name="securityManager" ref="securityManager"/>  
  14.         <property name="loginUrl" value="/login.jsp" /> <!-- 没有认证返回地址 -->  
  15.         <property name="unauthorizedUrl" value="/noPromission.jsp" /> <!-- 没有授权返回地址 -->  
  16.         <property name="filterChainDefinitions">  
  17.             <value>            <!-- **代表任意子目录 -->           
  18.          /css/** = anon  
  19.           /img/** = anon  
  20.          /js/** = anon  
  21.          /jsp/** = user  
  22.          /web/** = anon  
  23.          /**/**=user  
  24.             </value>  
  25.         </property>  
  26.     </bean>  
  27.   
  28.     <!-- 用户授权/认证信息Cache, 采用EhCache  缓存 -->  
  29.    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
  30.        <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>  
  31.    </bean>  
  32.   
  33.     <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  
  34.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  

六:配置ehcache-shiro.xml文件
  1. <ehcache updateCheck="false" name="shiroCache">  
  2.   
  3.     <defaultCache  
  4.             maxElementsInMemory="10000"  
  5.             eternal="false"  
  6.             timeToIdleSeconds="120"  
  7.             timeToLiveSeconds="120"  
  8.             overflowToDisk="false"  
  9.             diskPersistent="false"  
  10.             diskExpiryThreadIntervalSeconds="120"  
  11.             />  
  12. </ehcache>  

七:自定义realm AuthRealm

  1. package com.debo.login.controller;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.apache.shiro.authc.AuthenticationException;  
  6. import org.apache.shiro.authc.AuthenticationInfo;  
  7. import org.apache.shiro.authc.AuthenticationToken;  
  8. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  9. import org.apache.shiro.authc.UsernamePasswordToken;  
  10. import org.apache.shiro.authz.AuthorizationInfo;  
  11. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  12. import org.apache.shiro.realm.AuthorizingRealm;  
  13. import org.apache.shiro.subject.PrincipalCollection;  
  14. import org.springframework.beans.factory.annotation.Autowired;  
  15.   
  16. import com.debo.security.pojo.User;  
  17. import com.debo.security.service.RoleService;  
  18. import com.debo.security.service.UserService;  
  19.   
  20. public class ShiroDbRealm extends AuthorizingRealm {  
  21.   
  22.     @Autowired  
  23.     private UserService userService;  
  24.     @Autowired  
  25.     private RoleService roleService;  
  26.   
  27.     /**  
  28.      * shiro认证  
  29.      */  
  30.     @Override  
  31.     protected AuthenticationInfo doGetAuthenticationInfo(  
  32.             AuthenticationToken authcToken) throws AuthenticationException {  
  33.   
  34.         UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
  35.         String loginName = token.getUsername();  
  36.         if (loginName != null && !"".equals(loginName)) {  
  37.             // 通過登录名获取用户  
  38.             User user = userService.getUserByLoginName(loginName);  
  39.             if (user != null) {  
  40.                 // 如果身份认证验证成功,返回一个AuthenticationInfo实现  
  41.                 return new SimpleAuthenticationInfo(user.getLoginName(),  
  42.                         user.getPassword(), getName());  
  43.             }  
  44.         }  
  45.         return null;  
  46.     }  
  47.   
  48.     /**  
  49.      * shiro授权  
  50.      */  
  51.     @Override  
  52.     protected AuthorizationInfo doGetAuthorizationInfo(  
  53.             PrincipalCollection principals) {  
  54.         String loginName = (String) getAvailablePrincipal(principals); // 使用Shiro提供的方法获取用户名称  
  55.         if (loginName != null) {  
  56.             String roleId = userService.getRoleIdByLoginName(loginName);  
  57.   
  58.             // 获取用户的权限  
  59.             List<String> permTokens = roleService.getPermTokens(roleId);  
  60.   
  61.             SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  62.             if (roleId != null) {  
  63.                 info.addRole(roleId); // 加入用户角色  
  64.             }  
  65.             if (permTokens != null) {  
  66.                 info.addStringPermissions(permTokens); // 加入用户许可标记  
  67.             }  
  68.             return info;  
  69.         }  
  70.         return null;  
  71.     }  
  72. }  

八:书写登录逻辑
  1. package com.debo.login.controller;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpSession;  
  5.   
  6. import org.apache.shiro.SecurityUtils;  
  7. import org.apache.shiro.authc.AuthenticationException;  
  8. import org.apache.shiro.authc.UsernamePasswordToken;  
  9. import org.apache.shiro.subject.Subject;  
  10. import org.springframework.beans.factory.annotation.Autowired;  
  11. import org.springframework.stereotype.Controller;  
  12. import org.springframework.web.bind.annotation.RequestMapping;  
  13. import org.springframework.web.bind.annotation.RequestMethod;  
  14. import org.springframework.web.context.ContextLoader;  
  15. import org.springframework.web.context.WebApplicationContext;  
  16. import org.springframework.web.servlet.mvc.support.RedirectAttributes;  
  17.   
  18. import com.debo.company.service.CompanyService;  
  19. import com.debo.develop.service.MenuService;  
  20. import com.debo.security.pojo.User;  
  21. import com.debo.security.service.UserService;  
  22.   
  23.   
  24. @Controller  
  25. @RequestMapping("/login")  
  26. public class LoginController {  
  27.   
  28.     @Autowired  
  29.     private MenuService menuService;  
  30.       
  31.     @Autowired  
  32.     private UserService userService;  
  33.   
  34.     @Autowired  
  35.     private CompanyService companyService;  
  36.   
  37.     @RequestMapping(method = {RequestMethod.GET})  
  38.     public String login(HttpServletRequest request) {  
  39.         System.out.println("欢迎登陆!……");  
  40.         return "/login";  
  41.     }  
  42.   
  43.     @RequestMapping(method = {RequestMethod.POST})  
  44.     public String loginPost(User user, RedirectAttributes redirectAttributes, HttpServletRequest request) {  
  45.         Subject currentUser = SecurityUtils.getSubject();  
  46.         UsernamePasswordToken token = new UsernamePasswordToken(user.getLoginName(), user.getPassword(), user.isRememberMe());  
  47.         try {  
  48.             //用户认证  
  49.             currentUser.login(token);  
  50.         } catch (AuthenticationException e) {  
  51.             System.out.println(e);  
  52.             redirectAttributes.addFlashAttribute("message", "用户名或密码错误!");  
  53.             return "redirect:/login";  
  54.         }  
  55.         if (currentUser.isAuthenticated()) {  
  56.             //登录成功,保存用户相关信息  
  57.             sessionHandle(user, request);  
  58.             //跳转成功页面  
  59.             return "redirect:/index";  
  60.         } else {  
  61.             redirectAttributes.addFlashAttribute("message", "用户名或密码错误!");  
  62.             return "redirect:/login";  
  63.         }  
  64.     }  
  65.   
  66.     private void sessionHandle(User user, HttpServletRequest request) {  
  67.         HttpSession session = request.getSession();  
  68.         User loginUser = userService.getUserByLoginName(user.getLoginName());  
  69.         if(loginUser != null){  
  70.             session.setAttribute("companyId", loginUser.getCompanyId());  
  71.             session.setAttribute("username", loginUser.getNickName());  
  72.             session.setAttribute("userId", loginUser.getId());  
  73.         }  
  74.         //menuService.updateMenuInSession(request);  
  75.     }  
  76. }  



九:jsp页面控制权限

  1. <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%><!-- 导入标签库  -->  
  2.      <!-- 如果用户有deleteUser的权限 则显示删除 -->  
  3.      <shiro:hasPermission name="deleteUser">  
  4.         <span id="delete" onclick="delete(this)">删除</span>  
  5.      </shiro:hasPermission> 

文末福利:

福利一:前端,Java,产品经理,微信小程序,Python等8G资源合集大放送:https://www.jianshu.com/p/e8197d4d9880

福利二:微信小程序入门与实战全套详细视频教程

领取方式:
如果需要学习视频,欢迎关注 【编程微刊】微信公众号,回复【领取资源】一键领取以下所有干货资源,获取更多有用技术干货、文档资料。所有文档会持续更新,欢迎关注一起成长!



posted @ 2018-03-21 14:00  前端视听  阅读(132)  评论(0编辑  收藏  举报