通过shiro认证身份和模拟授权认证

身份认证和授权认证是权限管理中的核心模块。本文讲讲通过安全框架shiro进行身份认证和模拟授权认证,并可以看到授权之后的效果。

 

认证

登录模块,在完成用户名和密码的匹配基础上,查询该用户具有的操作权限,缓存到本地。

该权限系统是基于角色的RBAC模型。所以查询该用户具有的操作权限,其实是根据该用户所具有的角色查询的。

而缓存到本地,是为了提高性能。基于AOP的实现,是在Struts和页面端之间做权限验证,用大帅的话是“在它们之间插一杠子”。每次访问Action之前,判断该用户是否具有这个操作权限,只有具有操作权限才能访问Action。当用户登录时,如果把该用户具有的操作权限全部查询出来,缓存到本地,以后只需要根据这个缓存做判断即可,这样远比每次都到数据库中查询的效率要高得多。

 

用例子来说明

使用admin账号登录


登录时需要做的事情:

1、用户名和密码的匹配

2、查询该用户具有的操作权限,缓存到本地

 

根据权限,显示页面

admin用户,具有admin角色。

admin角色,具有对“用户管理”的“添加”、“删除”、“修改”的权限

所以,admin登录后可看到的页面时这样的


 

使用test账号登录


 

根据权限,显示页面

test用户,具有test角色。

test角色,只有对“用户管理”的“添加”的权限

所以,test登录后可看到的页面时这样的(只能看到添加按钮,并且也只能执行查询和添加操作)


 

由图可看出,权限控制粒度到了页面菜单及页面中按钮。

 

看看是如何实现的

java开源的海洋,我们要做什么,几乎都有现成的东西供我们使用,当然基于AOP实现的权限管理也不例外,比如我们可以使用apache shirospring security。我用的是apacheshiro,如果想学习,可参考之前的系列文章。

 

Authentication认证

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">@Override  
  2. protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)  
  3. throwsAuthenticationException {  
  4.    
  5. //验证 验证码  
  6. //........  
  7.    
  8. //验证 用户名和密码  
  9. UsernamePasswordTokentoken = (UsernamePasswordToken)authcToken;  
  10.    
  11. //从数据库中查询用户用信息  
  12. Useruser = userService.get(token.getUsername());  
  13.    
  14. ShiroUsershiroUser = new ShiroUser(user.getUsername(), user.getRealname());  
  15.    
  16. if(user != null) {  
  17. returnnew SimpleAuthenticationInfo(shiroUser,user.getPassword(),  
  18. ByteSource.Util.bytes(user.getPassword()),getName());  
  19. }</span>  

这相当于对 登录用户信息的匹配过程,只是这个匹配过程交给了shiro去完成。

Authentication认证之后,会进行Authorization认证,进而只能进行自己权限范围内的操作。

 

模拟Authorization认证

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">@Override  
  2. protectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
  3. System.out.println("由于加入了缓存, 此处只会load一次:doGetAuthorizationInfo.................");  
  4.    
  5. //得到doGetAuthenticationInfo 方法中传入的凭证  
  6. ShiroUsershiroUser = (ShiroUser) principals.fromRealm(getName()).iterator().next();  
  7.    
  8. StringuserName = shiroUser.getName();  
  9.    
  10. if(StringUtils.equals("admin",userName)) {  
  11.    
  12. SimpleAuthorizationInfoinfo = new SimpleAuthorizationInfo();  
  13.    
  14. //这个就是页面中<shiro:hasRole>标签的name的值  
  15. info.addRole("admin");  
  16.    
  17. //这个就是页面中<shiro:hasPermission> 标签的name的值  
  18. info.addStringPermission("user:view");  
  19. info.addStringPermission("user:add");  
  20. info.addStringPermission("user:edit");  
  21. info.addStringPermission("user:delete");  
  22.    
  23. returninfo;  
  24.    
  25. } elseif(StringUtils.equals("test", userName)) {  
  26. SimpleAuthorizationInfoinfo = new SimpleAuthorizationInfo();  
  27.    
  28. //这个就是页面中<shiro:hasRole>标签的name的值  
  29. info.addRole("test");  
  30.    
  31. //这个就是页面中<shiro:hasPermission> 标签的name的值  
  32. info.addStringPermission("user:view");  
  33. info.addStringPermission("user:add");  
  34.    
  35. returninfo;  
  36. else{  
  37. returnnull;  
  38. }  
  39. }</span>  


这里的permission字符串就是权限标识,比如useradd”表示对user模块具有add的权限。在shiro标签和shiro注解中,就是通过这个标识来完成验证的。

 

 

shiro标签在页面中的应用

jsp中,通过shiro标签实现对用户管理模块的权限控制

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;"><divclassdivclass="panelBar">  
  2. <ulclassulclass="toolBar">  
  3. <shiro:hasPermission name="user:add">  
  4. <li><aclassaclass="add" href="${contextPath}/user/preAddUser"target="dialog" rel="lookup2organization_add"mask="true" width="530"height="330"><span>添加</span></a></li>  
  5. </shiro:hasPermission>  
  6.    
  7. <shiro:hasPermission name="user:delete">  
  8. <li><atitleatitle="确实要删除这些记录吗?" target="selectedTodo"rel="userIds" href="${contextPath}/user/delManyUser"class="delete"><span>删除</span></a></li>  
  9. </shiro:hasPermission>  
  10.    
  11. <shiro:hasPermission name="user:edit">  
  12. <li><aclassaclass="edit"href="${contextPath}/user/preUpdateUser?userId={sid_user}"rel="lookup2organization_edit" target="dialog"mask="true" warn="请选择一个用户"><span>修改</span></a></li>  
  13. </shiro:hasPermission>  
  14. </ul>  
  15. </div></span>  


 

shiro注解在action中的应用

java代码中,通过shiro注解实现对用户管理模块的权限控制

通过shiro标签,的确可以让用户只看到自己权限范围之内的页面元素,但这并不是很安全,因为页面端的这些输入信息可以别篡改,就像做输入验证一样,在页面通过js验证后,在java代码还需要验证一样。

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">// 添加用户  
  2. @RequiresPermissions("user:add")  
  3. publicvoid  add(){          
  4. Stringmsg;  
  5.    
  6. try {  
  7. userService.save(user);  
  8. msg=AjaxObject.newOk("添加成功").setNavTabId("userListView").toString();  
  9. }catch (ServiceException e) {  
  10. msg =AjaxObject.newError(e.getMessage()).setNavTabId("userListView").setCallbackType("").toString();  
  11. }  
  12. outMsg(msg);  
  13. }</span>  

 

授权认证,这里是使用静态数据来模拟的,如果想得到数据库中的数据,涉及到RoleModulPermissionOrganization模块,而我们项目组正在开发之中。。。后文会有讲解,敬请期待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值