打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
shiro入门实例
     简介: Shiro 是一个 Apache Incubator 项目,旨在简化身份验证和授权。是一个很不错的安全框架。下面记录一下shiro和Spring整合的过程的一个小示例:
Web.xml配置
Xml代码  
  1.   
  2.         contextConfigLocation      classpath:applicationContext.xml,classpath:spring-shiro.xml  
  3.       
  4.   
  5.         
  6.         shiroFilter    
  7.         org.springframework.web.filter.DelegatingFilterProxy    
  8.             
  9.             targetFilterLifecycle    
  10.             true    
  11.             
  12.         
  13.     
  14.         
  15.         shiroFilter    
  16.         *.do    
  17.         
  18.         
  19.         shiroFilter    
  20.         *.jsp    
  21.         


第一部分是将shiro的配置文件引入到web.xml中,我这里是spring-shiro.xml;
下面的是一个过滤器,过滤.do,.jsp的请求,引入shiro web.xml就配这么多。
spring-shiro.xml配置文件
Xml代码 Shiro é????? /login.jsp* = anon /login.do* = anon /index.jsp*= anon /error/noperms.jsp*= anon /*.jsp* = authc /*.do* = authc " quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="z-index: 0;"> 
  1.   
  2. <="" li="">
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     
  6.     http://www.springframework.org/schema/util   
  7.     http://www.springframework.org/schema/util/spring-util-3.0.xsd">  
  8.     Shiro 配置  
  9.       
  10.           
  11.           
  12.           
  13.           
  14.           
  15.               
  16.                 /login.jsp* = anon  
  17.                 /login.do* = anon  
  18.                 /index.jsp*= anon  
  19.                 /error/noperms.jsp*= anon  
  20.                 /*.jsp* = authc  
  21.                 /*.do* = authc  
  22.               
  23.           
  24.       
  25.   
  26.       
  27.           
  28.           
  29.       
  30.   
  31.       
  32.   
  33.       
  34.       
  35.       
  36.     <>< li=""><>
  37.         class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">  
  38.         <>< li=""><>
  39.             value="org.apache.shiro.SecurityUtils.setSecurityManager" />  
  40.           
  41.       
  42.   
  43.       
  44.       
  45.     <>< li=""><>
  46.         class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
  47.         depends-on="lifecycleBeanPostProcessor" />  
  48.     <>< li=""><>
  49.         class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  50.           
  51.   
  52.       
  53.   
  54.   

这里不想说太多,我这里没什么特别的,很多都是用的shiro自己的原有的,只有一个realm是我自己定义的,可能自己定义的会更好用点吧,如果不用自己定义的就用shiro的jdbcrealm,我自定义的也是跟jdbcrealm差不多的,后面我们再说我的自定义realm。另外就是给页面指定过滤器
/login.jsp* = anon /login.do* = anon /index.jsp*= anon /error/noperms.jsp*= anon /*.jsp* = authc /*.do* = authc

Anon:不指定过滤器,不错是这个过滤器是空的,什么都没做,跟没有一样。
Authc:验证,这些页面必须验证后才能访问,也就是我们说的登录后才能访问。
这里还有其他的过滤器,我没用,比如说授权,这个比较重要,但是这个过滤器有个不好的地方,就是要带一个参数,所以如果配在这里就不是很合适,因为每个页面,或是.do的权限不一样,而我们也没法事先知道他需要什么权限。所以这里不配,我们在代码中再授权。这里.do和.jsp后面的*表示参数,比如login.jsp?main这种,是为了匹配这种。好行了,继续往下吧。
验证:
验证我们就弄一个登录页面,然后提交到后台的action
Java代码  
  1. @RequestMapping(params = "main")  
  2.     public ModelAndView login(User user,HttpSession session, HttpServletRequest request) {  
  3.   
  4.         ModelAndView modelView = new ModelAndView();  
  5.         Subject currentUser = SecurityUtils.getSubject();  
  6.         UsernamePasswordToken token = new UsernamePasswordToken(  
  7.                 user.getUsercode(), EncryptUtils.encryptMD5(user.getPassword()));  
  8.         token.setRememberMe(true);  
  9.         try {  
  10.             currentUser.login(token);  
  11.         } catch (AuthenticationException e) {  
  12.             modelView.addObject("message", "login errors");  
  13.             modelView.setViewName("/login");  
  14.             e.printStackTrace();  
  15.               
  16.         }  
  17.         if(currentUser.isAuthenticated()){  
  18.               
  19.             session.setAttribute("userinfo", user);  
  20.             modelView.setViewName("/main");  
  21.         }else{  
  22.             modelView.addObject("message", "login errors");  
  23.             modelView.setViewName("/login");  
  24.         }  
  25.         return modelView;  
  26.     }  

这里我用的是spring MVC,你不用管他用什么mvc,我们只要知道,前台.do登录以后进入这个方法就行
Subject currentUser = SecurityUtils.getSubject()
;就是代表当前的用户。
UsernamePasswordToken token = new UsernamePasswordToken( user.getUsercode(),EncryptUtils.encryptMD5(user.getPassword()));
这里的token大家叫他令牌,也就相当于一张表格,你要去验证,你就得填个表,里面写好用户名密码,交给公安局的同志给你验证。
currentUser.login(token);
这句是提交申请,验证能不能通过,也就是交给公安局同志了。这里会回调reaml里的一个方法
protected AuthenticationInfo doGetAuthenticationInfo()
验证是否通过
if(currentUser.isAuthenticated())
通过则转到你的页面,不通过到login页面并返回错误信息。
现在我们看看我们的reaml类,这是一个自定义的realm,
Java代码 roleNames = new HashSet(); Set permissions = new HashSet(); roleNames.add("admin"); permissions.add("user.do?myjsp"); permissions.add("login.do?main"); permissions.add("login.do?logout"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames); info.setStringPermissions(permissions); return info; } @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { /* è??é????????è?¤èˉ???£? ? */ UsernamePasswordToken token = (UsernamePasswordToken) authcToken;// User user = securityApplication.findby(upToken.getUsername()); User user = new User(); user.setUsercode(token.getUsername()); user.setUserName("admin"); user.setPassword(EncryptUtils.encryptMD5("admin"));// if (user != null) { return new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), getName()); } public void clearCachedAuthorizationInfo(String principal) { SimplePrincipalCollection principals = new SimplePrincipalCollection( principal, getName()); clearCachedAuthorizationInfo(principals); }}" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="z-index: 0;"> 
  1. @Service("monitorRealm")  
  2. public class MonitorRealm extends AuthorizingRealm {  
  3.     /* 
  4.      * @Autowired UserService userService; 
  5.      *  
  6.      * @Autowired RoleService roleService; 
  7.      *  
  8.      * @Autowired LoginLogService loginLogService; 
  9.      */  
  10.   
  11.     public MonitorRealm() {  
  12.         super();  
  13.   
  14.     }  
  15.   
  16.     @Override  
  17.     protected AuthorizationInfo doGetAuthorizationInfo(  
  18.             PrincipalCollection principals) {  
  19.         /* 这里编写授权代码 */  
  20.         Set roleNames = new HashSet();  
  21.         Set permissions = new HashSet();  
  22.         roleNames.add("admin");  
  23.         permissions.add("user.do?myjsp");  
  24.         permissions.add("login.do?main");  
  25.         permissions.add("login.do?logout");  
  26.         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);  
  27.         info.setStringPermissions(permissions);  
  28.         return info;  
  29.     }  
  30.     @Override  
  31.     protected AuthenticationInfo doGetAuthenticationInfo(  
  32.             AuthenticationToken authcToken) throws AuthenticationException {  
  33.         /* 这里编写认证代码 */  
  34.         UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
  35. //      User user = securityApplication.findby(upToken.getUsername());  
  36.         User user = new User();  
  37.         user.setUsercode(token.getUsername());  
  38.         user.setUserName("admin");  
  39.         user.setPassword(EncryptUtils.encryptMD5("admin"));  
  40. //      if (user != null) {  
  41.         return new SimpleAuthenticationInfo(user.getUserName(),  
  42.                 user.getPassword(), getName());  
  43.     }  
  44.     public void clearCachedAuthorizationInfo(String principal) {  
  45.         SimplePrincipalCollection principals = new SimplePrincipalCollection(  
  46.                 principal, getName());  
  47.         clearCachedAuthorizationInfo(principals);  
  48.     }  
  49. }  


这里我没有跟数据库打交道,如果要跟数据库打交道很简单,你调用一个service,service再调dao,根据用户名去打该用户的密码。用户我们可以前面的令牌也就是我说的表格来取的,我们前台提交给公安同志一个表格,里面有用户密码,但需要注意的是,我们在这里并不把表格中的用户密码路数据库中的用户密码进行比较,我们只是根据表格中的用户名把密码查出来,然后把数据库的用户密码放在一个SimpleAuthenticationInfo对象中返回即可,这位公安同志不负责验证,只负责验证的材料。我这里没有查库,伪造了一个用户密码放入了对象。密码是admin。什么时候验证,就是我们前面调currentUser.isAuthenticated()时验证,所有的材料都全了,需要验证的时候就调一下这个方法就可以了。我们前面spring里配了这个
/*.jsp* = authc
/*.do* = authc
你配了authc过滤器,shiro会自动调currentUser.isAuthenticated()这个方法,没有登录的将被返回

配置的页面。
好到这里登录就算是完成了。完成了登录下面就是要授权了,我们已经登录系统,我进入系统总要做点什么吧,比如这个系统就是一个公司的话,我现在已经进入公司了,如果我要进办公室,还得要授权(假如有门禁的话)刷卡。这们就里就是访问某个页面或是某个.do,
授权:
因为前面我们只配了验证过滤器,现在已经登录系统,如果我们请求一个*.do的话就会来到后台的action,我们授权也将在这里授。
Java代码
Java代码  
  1. @Controller  
  2. @RequestMapping(value="user")  
  3. public class UserController {  
  4.       
  5.     /** 
  6.      * 跳转到myjsp页面 
  7.      *  
  8.      * @return 
  9.      */  
  10.     @RequestMapping(params = "myjsp")  
  11.     public String home() {  
  12.         Subject currentUser = SecurityUtils.getSubject();  
  13.         if(currentUser.isPermitted("user.do?myjsp")){  
  14.             return "/my";  
  15.         }else{  
  16.             return "error/noperms";  
  17.         }  
  18.     }  
  19. }  

我一直都说action,其实spring mvc里不再是action了,叫controller,我们这里的home方法的访问路径是user.do?myjsp,也就是我们登录系统后请求一个这个方法user.do?myjsqp,转到home方法后,我要看他有没有权限访问此方法,我就用下面的代码
Subject currentUser = SecurityUtils.getSubject();
currentUser.isPermitted("user.do?myjsp");
首先得到当前的用户,再看此用户是否有权访问user.do?myjsp,参数就是权限,这里后台数据库就会有这么一个权限,权限表中的权限地址就是user.do?myjsp,例如我们一般的系统左边是一棵功能菜单树,树的结点会有一个url链接,这个链接就是在权限表中。当然可能前面还会一个http:\\什么的。反正这里也跟后台的权限表中的地址一致就行了,shiro他是如何授权的。一样的你调用currentUser.isPermitted("user.do?myjsp");此方法后会回调realm中的protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals)方法,这个reaml类是非常重要的。这个类上面已经给出了,我们看看他是如何授权的。因为我没有连数据库,也是伪造了一个权限。如果是连数据库也很简单,用户表,角色表,权限表这三个表是有关联的,我们根据用户名就能查出此用户拥有的角色和所有的权限。
Java代码  
  1. Set roleNames = new HashSet();  
  2.         Set permissions = new HashSet();  
  3.         roleNames.add("admin");  
  4.         permissions.add("user.do?myjsp");  
  5.         permissions.add("login.do?main");  
  6.         permissions.add("login.do?logout");  
  7.         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);  
  8.         info.setStringPermissions(permissions);  
  9.         return info;  
最后构造一个对象并把权限给它就OK拉。如果是数据库查出来的,直接我的字符串替成你查出来的就行了。这样在你的controller中根据权限返回到指定的页面。
Java代码  
  1. if(currentUser.isPermitted("user.do?myjsp")){  
  2.             return "/my";  
  3.         }else{  
  4.             return "error/noperms";  
  5.         }  

没有权限就返回到没有权限的页面。那么整个权限管理系统就算是差不多了,当然还有页面标签没说,这部分不是难点,自己找找资料吧,源码我整整一并奉上。。。。。。 
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
SpringMVC+Apache Shiro+JPA(hibernate)案例教学(二)基于SpringMVC+Shiro的用户登录权限验证
Apache Shiro 使用手册
基于shiro框架实现自动登录(rememberMe)
Spring Boot系列 安全框架Apache Shiro基本功能
在项目中集成shiro权限框架(3)
Apache Shiro 使用手册(五)Shiro 配置说明
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服