基于Shiro 拦截URL,实现权限控制

 

虽然网上很多关于Shiro的样例,但是LZ看了很多,觉得他们好多都不是自己想要的。

 

不是没有URL过滤功能,就是写死在xml配置文件里,还有好多不能使。

 

LZ不才,只能写一些简单样例给大家看看。

 

基础要求:SSH都会,了解权限管理的架构。

 

接下来是代码:

 

 先给出表

Sql代码   收藏代码
  1. CREATE TABLE `t_privilege` (  
  2.   `id` int(11) NOT NULL auto_increment,  
  3.   `perms` varchar(255) default NULL,  
  4.   `url` varchar(255) default NULL,  
  5.   PRIMARY KEY  (`id`)  
  6. ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;  
  7.   
  8.   
  9. CREATE TABLE `t_user` (  
  10.   `id` int(11) NOT NULL auto_increment,  
  11.   `passwordvarchar(255) default NULL,  
  12.   `username` varchar(255) default NULL,  
  13.   `role_id` int(11) default NULL,  
  14.   PRIMARY KEY  (`id`),  
  15.   KEY `FKCB63CCB613F1722F` (`role_id`),  
  16.   CONSTRAINT `FKCB63CCB613F1722F` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`)  
  17. ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;  
  18.   
  19.   
  20. CREATE TABLE `t_role` (  
  21.   `id` int(11) NOT NULL,  
  22.   `namevarchar(255) default NULL,  
  23.   PRIMARY KEY  (`id`)  
  24. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  25.   
  26.   
  27. CREATE TABLE `t_role_t_privilege` (  
  28.   `t_role_id` int(11) NOT NULL,  
  29.   `privileges_id` int(11) NOT NULL,  
  30.   PRIMARY KEY  (`t_role_id`,`privileges_id`),  
  31.   KEY `FK6947A6C85C5EE234` (`privileges_id`),  
  32.   KEY `FK6947A6C8CF836564` (`t_role_id`),  
  33.   CONSTRAINT `FK6947A6C8CF836564` FOREIGN KEY (`t_role_id`) REFERENCES `t_role` (`id`),  
  34.   CONSTRAINT `FK6947A6C85C5EE234` FOREIGN KEY (`privileges_id`) REFERENCES `t_privilege` (`id`)  
  35. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  

 这里设计的就是一个User,一个Role。但是Role有很多的URL。

 

DAO,Service 就不给了。

 

action:

 

 

Java代码   收藏代码
  1. package com.vti.action;  
  2.   
  3. import javax.annotation.Resource;  
  4. import javax.servlet.http.HttpServletRequest;  
  5. import javax.servlet.http.HttpServletResponse;  
  6.   
  7. import org.apache.shiro.SecurityUtils;  
  8. import org.apache.shiro.authc.UsernamePasswordToken;  
  9. import org.apache.shiro.subject.Subject;  
  10. import org.springframework.stereotype.Controller;  
  11. import org.springframework.ui.ModelMap;  
  12. import org.springframework.web.bind.annotation.RequestMapping;  
  13.   
  14. import com.vti.model.User;  
  15. import com.vti.service.UserService;  
  16.   
  17. @Controller  
  18. @RequestMapping(value="/")  
  19. public class LoginController {  
  20.       
  21.     private UserService userService;  
  22.       
  23.     public UserService getUserService() {  
  24.         return userService;  
  25.     }  
  26.   
  27.     @Resource  
  28.     public void setUserService(UserService userService) {  
  29.         this.userService = userService;  
  30.     }  
  31.       
  32.     @RequestMapping(value = "/login")  
  33.     public String login(String username, String password, ModelMap map){  
  34.         if(this.userService.checkUser(username, password)){  
  35.             setLogin(username, password);  
  36.             return "index.do";  
  37.         }else{  
  38.             map.addAttribute("msg""username or password error !");  
  39.             return "login.jsp";  
  40.         }  
  41.     }  
  42.       
  43.     @RequestMapping(value = "/index")  
  44.     public String index(HttpServletRequest request, HttpServletResponse response,ModelMap map){  
  45.         Subject currentUser = SecurityUtils.getSubject();  
  46.         User user=userService.getByUserLoginId(currentUser.getPrincipal().toString());  
  47.         map.addAttribute("LoginUser",user);  
  48.         return "index.jsp";  
  49.     }  
  50.       
  51.     @RequestMapping(value = "/logout")  
  52.     public String logout(HttpServletRequest request, HttpServletResponse response,ModelMap map){  
  53.         Subject currentUser = SecurityUtils.getSubject();  
  54.         currentUser.logout();  
  55.         return "login.jsp";  
  56.     }  
  57.       
  58.     private void setLogin(String userName, String password) {  
  59.         Subject currentUser = SecurityUtils.getSubject();  
  60.         if (!currentUser.isAuthenticated()) {  
  61.             UsernamePasswordToken token = new UsernamePasswordToken(userName, password);  
  62.             token.setRememberMe(false);  
  63.             currentUser.login(token);  
  64.         }  
  65.     }  
  66. }  

 

 

 

web.xml

 

 

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  5.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  6.   
  7.     <welcome-file-list>  
  8.         <welcome-file>login.jsp</welcome-file>  
  9.     </welcome-file-list>  
  10.   
  11.   
  12.     <context-param>  
  13.         <param-name>contextConfigLocation</param-name>  
  14.         <param-value>classpath:beans.xml</param-value>  
  15.     </context-param>  
  16.   
  17.     <listener>  
  18.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  19.     </listener>  
  20.       
  21.     <filter>  
  22.         <filter-name>shiroFilter</filter-name>  
  23.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  24.         <init-param>  
  25.             <param-name>targetFilterLifecycle</param-name>  
  26.             <param-value>true</param-value>  
  27.         </init-param>  
  28.     </filter>  
  29.     <filter-mapping>  
  30.         <filter-name>shiroFilter</filter-name>  
  31.         <url-pattern>/*</url-pattern>  
  32.         <dispatcher>REQUEST</dispatcher>  
  33.         <dispatcher>FORWARD</dispatcher>  
  34.         <dispatcher>INCLUDE</dispatcher>  
  35.         <dispatcher>ERROR</dispatcher>  
  36.     </filter-mapping>  
  37.   
  38.     <servlet>  
  39.         <servlet-name>springMVC</servlet-name>  
  40.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  41.         <init-param>  
  42.             <param-name>contextConfigLocation</param-name>  
  43.             <param-value>classpath:SpringMVC.xml</param-value>  
  44.         </init-param>  
  45.         <load-on-startup>1</load-on-startup>  
  46.     </servlet>  
  47.     <servlet-mapping>  
  48.         <servlet-name>springMVC</servlet-name>  
  49.         <url-pattern>*.do</url-pattern>  
  50.     </servlet-mapping>  
  51.       
  52. </web-app>  

 

 

 

beans.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"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  8.            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
  9.            http://www.springframework.org/schema/context  
  10.            http://www.springframework.org/schema/context/spring-context-3.2.xsd  
  11.            http://www.springframework.org/schema/aop  
  12.            http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
  13.            http://www.springframework.org/schema/tx   
  14.            http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">  
  15.   
  16.     <context:annotation-config />  
  17.     <context:component-scan base-package="com.vti"></context:component-scan>  
  18.       
  19.     <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">  
  20.         <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
  21.         <property name="url" value="jdbc:mysql://localhost:3306/test" />  
  22.         <property name="username" value="root" />  
  23.         <property name="password" value="admin" />  
  24.           
  25.         <property name="initialSize" value="5" />  
  26.         <property name="maxActive" value="500" />  
  27.         <property name="maxIdle" value="50" />  
  28.         <property name="minIdle" value="10" />  
  29.         <property name="timeBetweenEvictionRunsMillis" value="3600000" />  
  30.         <property name="minEvictableIdleTimeMillis" value="3600000" />  
  31.       
  32.     </bean>  
  33.       
  34.     <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
  35.         <property name="dataSource" ref="dataSource" />  
  36.         <property name="packagesToScan">  
  37.             <list>  
  38.                 <value>com.vti.model</value>  
  39.                 </list>  
  40.         </property>  
  41.           
  42.         <property name="hibernateProperties">  
  43.             <props>  
  44.                 <prop key="hibernate.dialect">  
  45.                     org.hibernate.dialect.MySQLDialect  
  46.                 </prop>  
  47.                 <prop key="hibernate.show_sql">true</prop>  
  48.                 <prop key="hibernate.hbm2ddl.auto">update</prop>  
  49.                 </props>  
  50.         </property>  
  51.           
  52.     </bean>  
  53.   
  54.     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">  
  55.         <property name="sessionFactory" ref="sessionFactory"></property>  
  56.     </bean>  
  57.       
  58.     <bean id="txManager"  
  59.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  60.         <property name="sessionFactory" ref="sessionFactory" />  
  61.     </bean>  
  62.   
  63.     <aop:config>  
  64.         <aop:pointcut id="bussinessService" expression="execution(public * com.vti.service.*.*(..))" />  
  65.         <aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" />  
  66.     </aop:config>  
  67.   
  68.     <tx:advice id="txAdvice" transaction-manager="txManager">  
  69.         <tx:attributes>  
  70.             <tx:method name="save*" propagation="REQUIRED"/>  
  71.             <tx:method name="find*" read-only="true"/>  
  72.             <tx:method name="get*" read-only="true"/>  
  73.         </tx:attributes>  
  74.     </tx:advice>  
  75.       
  76.       
  77.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  78.         <property name="realm" ref="shiroDbRealm" />  
  79.     </bean>  
  80.       
  81.     <bean id="shiroDbRealm" class="com.vti.shiro.MyShiroRealm" />  
  82.       
  83.     <bean id="chainDefinitionSectionMetaSource" class="com.vti.shiro.ChainDefinitionSectionMetaSource">  
  84.         <property name="filterChainDefinitions">  
  85.             <value>  
  86.                 /login.do = anon  
  87.                 /logoutlogout.do = logout  
  88.             </value>  
  89.         </property>  
  90.     </bean>  
  91.       
  92.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  93.         <property name="securityManager" ref="securityManager" />  
  94.         <property name="loginUrl" value="/login.jsp" />  
  95.         <property name="successUrl" value="/index.do" />  
  96.         <property name="unauthorizedUrl" value="/403.htm" />  
  97.           
  98.         <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" />  
  99.     </bean>  
  100.       
  101.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  102.       
  103.     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" >  
  104.     </bean>  
  105.       
  106.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  107.         <property name="securityManager" ref="securityManager"/>  
  108.     </bean>  
  109.       
  110. </beans>  

 

 

 

 

 

ChainDefinitionSectionMetaSource

 

 

Java代码   收藏代码
  1. package com.vti.shiro;  
  2.   
  3. import java.text.MessageFormat;  
  4. import java.util.Iterator;  
  5. import java.util.List;  
  6.   
  7. import javax.annotation.Resource;  
  8.   
  9. import org.apache.shiro.config.Ini;  
  10. import org.apache.shiro.config.Ini.Section;  
  11. import org.springframework.beans.factory.FactoryBean;  
  12. import org.springframework.util.StringUtils;  
  13.   
  14. import com.vti.dao.PrivilegeDao;  
  15. import com.vti.model.Privilege;  
  16.   
  17. public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section>{  
  18.       
  19.     public static final String PREMISSION_STRING="perms[\"{0}\"]";  
  20.       
  21.     private String filterChainDefinitions;  
  22.       
  23.     private PrivilegeDao privilegeDao;  
  24.   
  25.     public PrivilegeDao getPrivilegeDao() {  
  26.         return privilegeDao;  
  27.     }  
  28.       
  29.     public String getFilterChainDefinitions() {  
  30.         return filterChainDefinitions;  
  31.     }  
  32.       
  33.     @Resource  
  34.     public void setFilterChainDefinitions(String filterChainDefinitions) {  
  35.         String fiter="";//改正后的url配置  
  36.         List<Privilege> list = privilegeDao.getAll();  
  37.         for (Iterator<Privilege> it = list.iterator(); it.hasNext();) {  
  38.             Privilege privilege = it.next();  
  39.             if(!StringUtils.isEmpty(privilege.getUrl())) {  
  40.                 fiter+="/"+privilege.getUrl()+" = authc," +MessageFormat.format(PREMISSION_STRING,privilege.getPerms()) +"\n";  
  41.             }//追加beans.xml中已经有的过滤  
  42.         }  
  43.         System.out.println(filterChainDefinitions+fiter);  
  44.         this.filterChainDefinitions = filterChainDefinitions+fiter;  
  45.     }  
  46.   
  47.     @Resource  
  48.     public void setPrivilegeDao(PrivilegeDao privilegeDao) {  
  49.         this.privilegeDao = privilegeDao;  
  50.     }  
  51.       
  52.     public Section getObject(){  
  53.         Ini ini = new Ini();//网上好多都是在这里配置URL的。但是发现是错误的。  
  54.         ini.load(filterChainDefinitions);  
  55.         Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);  
  56.         return section;  
  57.     }  
  58.   
  59.     public Class<?> getObjectType() {  
  60.         return this.getClass();  
  61.     }  
  62.   
  63.     public boolean isSingleton() {  
  64.         return false;  
  65.     }  
  66.   
  67. }  

 

 

 

 

MyShiroRealm

 

 

Java代码   收藏代码
  1. package com.vti.shiro;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.annotation.Resource;  
  6.   
  7. import org.apache.shiro.authc.AccountException;  
  8. import org.apache.shiro.authc.AuthenticationException;  
  9. import org.apache.shiro.authc.AuthenticationInfo;  
  10. import org.apache.shiro.authc.AuthenticationToken;  
  11. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  12. import org.apache.shiro.authc.UnknownAccountException;  
  13. import org.apache.shiro.authc.UsernamePasswordToken;  
  14. import org.apache.shiro.authz.AuthorizationException;  
  15. import org.apache.shiro.authz.AuthorizationInfo;  
  16. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  17. import org.apache.shiro.realm.AuthorizingRealm;  
  18. import org.apache.shiro.subject.PrincipalCollection;  
  19. import org.springframework.util.StringUtils;  
  20.   
  21. import com.vti.model.Privilege;  
  22. import com.vti.model.User;  
  23. import com.vti.service.UserService;  
  24.   
  25. public class MyShiroRealm extends AuthorizingRealm{  
  26.     private UserService userService;  
  27.       
  28.     public UserService getUserService() {  
  29.         return userService;  
  30.     }  
  31.       
  32.     @Resource  
  33.     public void setUserService(UserService userService) {  
  34.         this.userService = userService;  
  35.     }  
  36.   
  37.     @Override  
  38.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
  39.         if(principals == null){  
  40.             throw new AuthorizationException("principals should not be null");  
  41.         }  
  42.         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  43.         String username =(String) principals.fromRealm(this.getName()).iterator().next();  
  44.         List<Privilege> privileges = userService.getAllPrivilegeByUserId(username);  
  45.         for(Privilege p : privileges){  
  46.             info.addStringPermission(p.getPerms());  
  47.         }  
  48.         return info;  
  49.     }  
  50.   
  51.     @Override  
  52.     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authecToken){  
  53.         UsernamePasswordToken token = (UsernamePasswordToken)authecToken;  
  54.           
  55.         if(StringUtils.isEmpty(token.getUsername())){  
  56.             throw new AccountException("用户名不能为空");  
  57.         }   
  58.           
  59.         User user = userService.getByUserLoginId(token.getUsername());  
  60.         if(user == null){  
  61.             throw new UnknownAccountException("用户名没找到");  
  62.         } else if(user.getPassword().equals(new String(token.getPassword()))){  
  63.             return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), this.getName());  
  64.         } else {  
  65.             throw new AuthenticationException("授权失败");  
  66.         }  
  67.     }  
  68.       
  69.       
  70. }  

 

 

 

给出index,jsp

有shiro的标签使用

Html代码   收藏代码
  1. <%@ page language="java" contentType="text/html; utf-8" pageEncoding="utf-8"%>  
  2. <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>  
  3.   
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  5. <html>  
  6.     <head>  
  7.         <meta http-equiv="Content-Type" content="text/html; utf-8">  
  8.         <title>Insert title here</title>  
  9.     </head>  
  10.     <body>  
  11.       
  12.     <shiro:authenticated>  
  13.         <h3>Login User Can see it</h3>  
  14.         <h4>You are  ${LoginUser.role.name}, Your name is ${LoginUser.username}</h4>  
  15.     </shiro:authenticated>  
  16.       
  17.     <shiro:hasPermission name="set">  
  18.         <a href="3.jsp">系统设置</a><br>  
  19.     </shiro:hasPermission>  
  20.     <shiro:hasPermission name="view">  
  21.         <a href="2.jsp">总账查看</a><br>  
  22.     </shiro:hasPermission>  
  23.     <shiro:hasPermission name="sale">  
  24.         <a href="1.jsp">卖货</a><br><br>  
  25.     </shiro:hasPermission>  
  26.       
  27.     <shiro:notAuthenticated>  
  28.         Please <a href="login.jsp">login</a> in order to update your credit card information.  
  29.     </shiro:notAuthenticated>  
  30.       
  31.     <shiro:authenticated>  
  32.         <a href="logout.do">注销</a>  
  33.     </shiro:authenticated>  
  34.       
  35.     </body>  
  36.       
  37. </html>  

 

 

最后讲下逻辑思路:

 

 系统分为三个等级。 分别是:售货员,经理,管理员

 售货员:登录,卖货,注销

经理:查账,登录,卖货,注销

管理员:系统设置,查账,登录,卖货,注销。

 

主要是围绕这样的功能去分配url的。




数据库在附件中给出。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Shiro拦截URL动态配置在数据库中可以实现灵活的权限管理和动态的权限控制。传统的权限控制方式通常是在代码中硬编码,当权限配置发生变化时,需要重新编译代码并重新部署,不方便管理和维护。而将Shiro拦截URL配置存储在数据库中,可以在运行时动态修改权限配置,不需要重新编译代码。 使用数据库作为权限配置的存储介质,我们可以通过数据库操作来修改URL权限信息,如添加新的URL权限、修改已有URL权限或者删除不再需要的URL权限。这样就可以实现对系统权限的实时管理和控制。 通过将Shiro拦截URL动态配置在数据库中,我们可以更加灵活地控制用户的权限。可以根据用户角色、用户组织、用户类型等条件动态决定用户能够访问的URL资源。当用户权限发生变化时,只需修改数据库中相关的权限配置数据,就可以实现权限的动态调整,无需停机或者重新加载。 此外,将Shiro拦截URL动态配置在数据库中还可以方便地对权限进行维护和管理。可以通过数据库的工具和SQL语句来管理URL权限,如查询某个用户具有的URL权限、查询系统中所有的URL权限等。 总之,将Shiro拦截URL动态配置在数据库中可以实现权限的灵活管理和动态控制,提高系统的可维护性和扩展性。同时,通过数据库的管理工具,也可以方便地对权限进行管理和维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值