权限系统--通过shiro进行按钮及页面访问url的权限控制
2017-10-14 13:28
851 查看
一:问题的引入
前面虽然基本的功能都有了但是页面按钮的控制与url的控制还是没有处理。这么一个场景,虽然用户只能通过点击菜单进行各个界面的访问,假如用户知道了你的界面的访问url,直接跳过菜单访问的话,正常来说是不应该跳转到对应的界面上的。如果不对其进行控制,也会造成权限混乱的。就像下图这样:可以看出菜单中确实没有权限资源控制这个菜单,按道理是无法进去那个界面的。也做到了权限的控制。但是当我们直接访问url时却又进来对应的界面。这种情况是一定要避免的。
二:问题解决:
这就要说道shiro这个强大的工具了。当面我们每次登录系统时,都会通过我们自己定义的继承AuthorizingRealm的ShiroRealm进行用户账号密码的确认以及拥有权限的查询:
自定义shiroReam
public class ShiroDbRealm extends AuthorizingRealm { @Autowired private UserService userService; @Autowired private SysUserService sysUserService ; @Autowired private SysUserResService sysUserResService ; public ShiroDbRealm() { super(); } /** * 验证登陆 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; SysUser sysUser = sysUserService.getUserByLoginName(token.getUsername()) ; //根据登录名获取用户信息 if (sysUser != null) { return new SimpleAuthenticationInfo(sysUser.getUserNo(), sysUser.getUserPwd(), getName()); } else { throw new AuthenticationException(); } } /** * 登陆成功之后,进行角色和权限验证 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String userNo = (String) getAvailablePrincipal(principals); // 列举此用户所有的权限 //List<Permission> permissions = userService.findUserPermissionByName(username); List<SysUserRes> listRes = sysUserResService.getPermissionByNo(userNo) ; Set<String> strs=new HashSet<String>(); Iterator<SysUserRes> it = listRes.iterator(); while (it.hasNext()) { SysUserRes re=it.next(); strs.add(re.getResUrl()); } SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addStringPermissions(strs); return authorizationInfo; } /** * 清除所有用户授权信息缓存. */ public void clearCachedAuthorizationInfo(String principal) { SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName()); clearCachedAuthorizationInfo(principals); } /** * 清除所有用户授权信息缓存. */ public void clearAllCachedAuthorizationInfo() { Cache<Object, AuthorizationInfo> cache = getAuthorizationCache(); if (cache != null) { for (Object key : cache.keys()) { cache.remove(key); } } } /** * * @Title: clearAuthz * @Description: TODO 清楚缓存的授权信息 * @return void 返回类型 */ public void clearAuthz(){ this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals()); } }
我们在对应位置加上断点:
(1)进行用户账号密码的验证
(2)进行已经拥有权限的查询:
系统会先查询拥有哪些权限。
(3)通过siro进行处理:shiro的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:org/springframework/beans/factory/xml/spring-beans-3.0.xsd http://www.springframework.org/schema/context classpath:org/springframework/context/config/spring-context-3.0.xsd http://www.springframework.org/schema/aop classpath:org/springframework/aop/config/spring-aop-3.0.xsd http://www.springframework.org/schema/tx classpath:org/springframework/transaction/config/spring-tx-3.0.xsd http://www.springframework.org/schema/util classpath:org/springframework/beans/factory/xml/spring-util-3.0.xsd" default-lazy-init="true"> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroDbRealm" /> <property name="cacheManager" ref="shiroCacheManager" /> </bean> <!-- 項目自定义的Realm --> <bean id="shiroDbRealm" class="com.creidtsys.security.realm.ShiroDbRealm"> <!-- <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"/> </bean> </property> --> </bean> <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="/page/login" /> <property name="successUrl" value="/page/index" /> <property name="unauthorizedUrl" value="/page/noPers" /> <!-- <property name="filters"> <util:map> <entry key="authc"> <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/> </entry> </util:map> </property> --> <property name="filterChainDefinitions"> <value> /sysUser/checkLogin = anon /login = anon /index = anon /page/** = anon <!-- 要拦截的url --> <!-- 用户权限拦截 --> /sysUser/list= perms["user:serch"] /sysUser/toAdd = perms["user:add"] /sysUser/toEdit = perms["user:update"] <!-- 角色权限拦截 --> /sysRole/list=perms["role:serch"] /sysUser/toAdd = perms["role:add"] /sysUser/toEdit = perms["role:update"] <!-- 部门权限拦截 --> /sysDept/list = perms["dept:serch"] /sysDept/toAdd = perms["dpt:add"] /sysDept/toEdit = perms["dept:edit"] <!-- 资源权限拦截 --> /sysRes/list = perms["res:serch"] /sysRes/toAdd = perms["res:add"] /sysRest/toEdit = perms["res:edit"] </value> </property> </bean> <!-- 用户授权信息Cache org.apache.shiro.cache.ehcache.EhCacheManager--> <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManager" ref="ehCacheManager" /> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <!-- AOP式方法级权限检查 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> </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的标签就轻而易举的解决了:<div data-options="region:'center'"> <div id="tb" style="padding-bottom: 5px"> <input id="queryName" class="easyui-textbox"/> <a id="querybtn" class="easyui-linkbutton" data-options="iconCls:'icon-search'">查询</a> <shiro:hasPermission name="res:add"> <a id="addbtn" class="easyui-linkbutton" data-options="iconCls:'icon-add'">新增</a> </shiro:hasPermission> <shiro:hasPermission name="res:edit"> <a id="editbtn" class="easyui-linkbutton" data-options="iconCls:'icon-edit'">修改</a> </shiro:hasPermission> <shiro:hasPermission name="res:delete"> <a id="delbtn" class="easyui-linkbutton" data-options="iconCls:'icon-remove'">删除 </a> </shiro:hasPermission> </div>
相关文章推荐
- oa系统禁止用户直接通过url去访问<iframe>的页面
- 获取系统URL访问的前三名(通过Scala方式实现/通过Spark方式实现),Spark将URL访问日志进行分类并通过自定义Partitioner的方式将文件写入到不同分区上
- java项目中普遍存在的一个bug,用户直接可以通过url访问本人没有权限的页面
- yii 通过交易码, 控制页面访问权限
- 您不具备查看该目录或页面的权限,因为访问控制列表 (ACL) 对Web服务器上的该资源进行了配置
- Android如何在app中通过一个按钮直接跳转到的系统的权限设置页面
- 使用shiro进行系统身份验证-权限控制,登录界面乱跳
- 通过request.getHeader("referer")防止用户手动修改URL访问非权限页面
- Android如何在app中通过一个按钮直接跳转到的系统的权限设置页面
- spring mvc怎么加入权限控制,在未登录前,任何访问url都跳转到login页面;登录成功后跳转至先前的url
- 报表系统FineReport通过权限控制数据访问方案
- 您未被授权查看该页 您不具备查看该目录或页面的权限,因为访问控制列表 (ACL) 对 Web 服务器上的该资源进行了配置
- shiro安全框架扩展教程--如何动态控制页面节点元素的权限
- 《Spark商业案例与性能调优实战100课》第13课:商业案例之纯粹通过DataSet进行电商交互式分析系统中特定时段段访问次数TopN
- 通过 lua 进行 nginx redis 访问控制
- redhat6.2通过allow deny实现ssh访问权限控制
- MFC通过按钮控制编辑框是否显示系统时间
- 权限管理系统 页面权限粒度控制设计 GUID在数据库系统的应用
- Jfinal配合Shiro进行权限控制
- SharePoint【用户访问控制】-- sharepoint 判断当前用户在当前页面是否有某项权限