权限控制-Shiro

一:问题的引入

前面虽然基本的功能都有了但是页面按钮的控制与url的控制还是没有处理。这么一个场景,虽然用户只能通过点击菜单进行各个界面的访问,假如用户知道了你的界面的访问url,直接跳过菜单访问的话,正常来说是不应该跳转到对应的界面上的。如果不对其进行控制,也会造成权限混乱的。就像下图这样:可以看出菜单中确实没有权限资源控制这个菜单,按道理是无法进去那个界面的。也做到了权限的控制。

但是当我们直接访问url时却又进来对应的界面。这种情况是一定要避免的。

二:问题解决:

这就要说道shiro这个强大的工具了。

当面我们每次登录系统时,都会通过我们自己定义的继承AuthorizingRealm的ShiroRealm进行用户账号密码的确认以及拥有权限的查询:

自定义shiroReam

 
  1. public class ShiroDbRealm extends AuthorizingRealm {

  2.  
  3. @Autowired

  4. private UserService userService;

  5. @Autowired

  6. private SysUserService sysUserService ;

  7. @Autowired

  8. private SysUserResService sysUserResService ;

  9. public ShiroDbRealm() {

  10. super();

  11. }

  12.  
  13. /**

  14. * 验证登陆

  15. */

  16. @Override

  17. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)

  18. throws AuthenticationException {

  19. UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

  20. SysUser sysUser = sysUserService.getUserByLoginName(token.getUsername()) ;

  21. //根据登录名获取用户信息

  22. if (sysUser != null) {

  23. return new SimpleAuthenticationInfo(sysUser.getUserNo(), sysUser.getUserPwd(), getName());

  24. } else {

  25. throw new AuthenticationException();

  26. }

  27. }

  28.  
  29. /**

  30. * 登陆成功之后,进行角色和权限验证

  31. */

  32. @Override

  33. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

  34.  
  35. String userNo = (String) getAvailablePrincipal(principals);

  36. // 列举此用户所有的权限

  37. //List<Permission> permissions = userService.findUserPermissionByName(username);

  38. List<SysUserRes> listRes = sysUserResService.getPermissionByNo(userNo) ;

  39. Set<String> strs=new HashSet<String>();

  40. Iterator<SysUserRes> it = listRes.iterator();

  41. while (it.hasNext()) {

  42. SysUserRes re=it.next();

  43. strs.add(re.getResUrl());

  44. }

  45. SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

  46. authorizationInfo.addStringPermissions(strs);

  47. return authorizationInfo;

  48. }

  49.  
  50. /**

  51. * 清除所有用户授权信息缓存.

  52. */

  53. public void clearCachedAuthorizationInfo(String principal) {

  54. SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());

  55. clearCachedAuthorizationInfo(principals);

  56. }

  57.  
  58. /**

  59. * 清除所有用户授权信息缓存.

  60. */

  61. public void clearAllCachedAuthorizationInfo() {

  62. Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();

  63. if (cache != null) {

  64. for (Object key : cache.keys()) {

  65. cache.remove(key);

  66. }

  67. }

  68. }

  69. /**

  70. *

  71. * @Title: clearAuthz

  72. * @Description: TODO 清楚缓存的授权信息

  73. * @return void 返回类型

  74. */

  75. public void clearAuthz(){

  76. this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());

  77. }

  78. }


我们在对应位置加上断点:

(1)进行用户账号密码的验证

(2)进行已经拥有权限的查询:

系统会先查询拥有哪些权限。

(3)通过siro进行处理:shiro的配置文件

 
  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:util="http://www.springframework.org/schema/util"

  6. xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:org/springframework/beans/factory/xml/spring-beans-3.0.xsd

  7. http://www.springframework.org/schema/context classpath:org/springframework/context/config/spring-context-3.0.xsd

  8. http://www.springframework.org/schema/aop classpath:org/springframework/aop/config/spring-aop-3.0.xsd

  9. http://www.springframework.org/schema/tx classpath:org/springframework/transaction/config/spring-tx-3.0.xsd

  10. http://www.springframework.org/schema/util classpath:org/springframework/beans/factory/xml/spring-util-3.0.xsd"

  11. default-lazy-init="true">

  12.  
  13. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

  14. <property name="realm" ref="shiroDbRealm" />

  15. <property name="cacheManager" ref="shiroCacheManager" />

  16. </bean>

  17.  
  18. <!-- 項目自定义的Realm -->

  19. <bean id="shiroDbRealm" class="com.creidtsys.security.realm.ShiroDbRealm">

  20. <!-- <property name="credentialsMatcher">

  21. <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">

  22. <property name="hashAlgorithmName" value="MD5"/>

  23. </bean>

  24. </property> -->

  25. </bean>

  26.  
  27. <!-- Shiro Filter -->

  28. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

  29. <property name="securityManager" ref="securityManager" />

  30. <property name="loginUrl" value="/page/login" />

  31. <property name="successUrl" value="/page/index" />

  32. <property name="unauthorizedUrl" value="/page/noPers" />

  33. <!-- <property name="filters">

  34. <util:map>

  35. <entry key="authc">

  36. <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>

  37. </entry>

  38. </util:map>

  39. </property> -->

  40. <property name="filterChainDefinitions">

  41. <value>

  42. /sysUser/checkLogin = anon

  43. /login = anon

  44. /index = anon

  45. /page/** = anon

  46. <!-- 要拦截的url -->

  47. <!-- 用户权限拦截 -->

  48. /sysUser/list= perms["user:serch"]

  49. /sysUser/toAdd = perms["user:add"]

  50. /sysUser/toEdit = perms["user:update"]

  51. <!-- 角色权限拦截 -->

  52. /sysRole/list=perms["role:serch"]

  53. /sysUser/toAdd = perms["role:add"]

  54. /sysUser/toEdit = perms["role:update"]

  55. <!-- 部门权限拦截 -->

  56. /sysDept/list = perms["dept:serch"]

  57. /sysDept/toAdd = perms["dpt:add"]

  58. /sysDept/toEdit = perms["dept:edit"]

  59. <!-- 资源权限拦截 -->

  60. /sysRes/list = perms["res:serch"]

  61. /sysRes/toAdd = perms["res:add"]

  62. /sysRest/toEdit = perms["res:edit"]

  63. </value>

  64. </property>

  65. </bean>

  66.  
  67. <!-- 用户授权信息Cache org.apache.shiro.cache.ehcache.EhCacheManager-->

  68.  
  69.  
  70.  
  71. <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">

  72. <property name="cacheManager" ref="ehCacheManager" />

  73. </bean>

  74. <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->

  75. <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

  76.  
  77. <!-- AOP式方法级权限检查 -->

  78. <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"

  79. depends-on="lifecycleBeanPostProcessor">

  80. </bean>

  81.  
  82. <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

  83. <property name="securityManager" ref="securityManager" />

  84. </bean>

  85.  
  86. </beans>


(4)拦截配置说明:

anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数
roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
注:anon,authcBasic,auchc,user是认证过滤器,
perms,roles,ssl,rest,port是授权过滤器

(5)我的配置:

/sysRes/list = perms["res:serch"]
/sysRes/toAdd = perms["res:add"]
/sysRest/toEdit = perms["res:edit"]

如果你想要访问主界面(/sysRes/list)就必修又有["res:serch"]的权限

如果你想要跳转到添加界面(/sysRes/toAdd),就必须拥有["res:add"]的权限

如果你想跳转到修改界面(/sysRest/toEdit),就必须拥有["res:edit"]的权限

这样就出现下面的结果了:

三:按钮权限的控制

按钮权限的控制就显得简单了,只需要通过shiro的标签就轻而易举的解决了:

 
  1. <div data-options="region:'center'">

  2. <div id="tb" style="padding-bottom: 5px">

  3. <input id="queryName" class="easyui-textbox"/>

  4. <a id="querybtn" class="easyui-linkbutton" data-options="iconCls:'icon-search'">查询</a>

  5. <shiro:hasPermission name="res:add">

  6. <a id="addbtn" class="easyui-linkbutton" data-options="iconCls:'icon-add'">新增</a>

  7. </shiro:hasPermission>

  8. <shiro:hasPermission name="res:edit">

  9. <a id="editbtn" class="easyui-linkbutton" data-options="iconCls:'icon-edit'">修改</a>

  10. </shiro:hasPermission>

  11. <shiro:hasPermission name="res:delete">

  12. <a id="delbtn" class="easyui-linkbutton" data-options="iconCls:'icon-remove'">删除 </a>

  13. </shiro:hasPermission>

  14.  
  15. </div>

转自https://blog.csdn.net/J_Bang/article/details/78233724

猜你喜欢

转载自blog.csdn.net/sanyaoxu_2/article/details/81583225