Shiro + SSM(框架) + Freemarker(jsp)讲解的权限控制Demo,还不赶快去下载?
Shiro 是一个很完美的权限控制框架,一般我们会采用 shiro 的标签,在页面判断,从而来判断一些Button ,Link Tag 的显示与否,但是仅仅这样判断是不够的,如果用户知道链接,这就一点用都没有。所以我们后台还要有一层判断。这样才安全。今天来说说 Shiro 后台判断的这点事。
shiro标签讲解:
Freemarker 使用Shiro 标签的介绍:http://www.sojson.com/blog/143.html
JSP 使用Shiro 标签的介绍:http://www.sojson.com/blog/144.html
shiro一般是这样配置。
<property name="filterChainDefinitions" > <value> /** = anon /page/login.jsp = anon /page/register/* = anon /page/index.jsp = authc /page/addItem* = authc,roles[数据管理员] /page/file* = authc,roleOR[普通用户,数据管理员] /page/listItems* = authc,roleOR[数据管理员,普通用户] /page/showItem* = authc,roleOR[数据管理员,普通用户] /page/updateItem*=authc,roles[数据管理员] </value></property>
这样配置有什么问题?
shiro 加载配置,或者说校验配置,是从上而下的,也就是向上面的配置,其实是有问题的。可能不仔细看你没看出来,/** = anon ,如果把这个配置在第一行,其实下面的配置都没用。因为是从上往下去匹配,只要匹配中了,就不匹配了,这个是重点,所以要有序。
其次,我们知道,这样配置有一个问题,就是维护起来费劲,它不如单独的配置文件,比如我们常用properties 配置文件来配置一些经常修改的值。如:jdbc.properties 会配置一些数据库的链接,帐号、密码等。
说到这里,有的同学就会想,那么我们就用 properties ?
properties 我们来看看有什么问题?
用 properties 配置,其实是没问题,问题就出在读取 properties 配置上。我们一般读取,或者说常用读取properties 配置文件,都是用相对应的 Java JDK 自带提供java.util.Properties 工具类,我们可以看到这个工具类的情况。
public class Properties extends Hashtable<Object,Object> { //Do some thing}
它继承了 Hashtable ,这就是出现了一个问题,Hashtable 是无序的。这就是关键点。
Shiro 权限拦截动态配置方案
1.重写java.util.Properties 工具类 ,继承 LinkedHashMap<K, V>() ,LinkedHashMap() 是有序的。
</k, v>
2.自己写一个读取文件的工具类也可以解决。
我的实现是用ini配置文件,自己写了一个读取的工具类,已经封装好,欲知详情或者下载请点击:http://www.sojson.com/blog/139.html
里面有工具类的下载,本站的实现,以及本站发布的开源Demo项目:SpringMVC + Mybatis + Shiro + Redis 。
这个 Demo 里的配置文件:
[base_auth]/u/**=anon/user/**=simple,login/js/**=anon/css/**=anon /open/**=anon#不用校验地址是否有权限/permission/selectPermissionById.shtml=simple,login/member/onlineDetails/**=simple,login/role/mypermission.shtml=simple,login/role/getPermissionTree.shtml=simple,login/role/selectRoleByUserId.shtml=simple,login#需要根据地址校验有无权限/permission/**=simple,login,permission/role/**=simple,login,permission/member/**=simple,login,permission/**=simple,login
配置文件加载类:
package com.sojson.core.shiro.service.impl;import java.io.IOException;import java.util.Map;import java.util.Set;import javax.annotation.Resource;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;import org.apache.shiro.web.servlet.AbstractShiroFilter;import org.springframework.core.io.ClassPathResource;import com.sojson.common.utils.LoggerUtils;import com.sojson.core.config.INI4j;import com.sojson.core.shiro.service.ShiroManager;/** * * 开发公司:SOJSON在线工具 <p> * 版权所有:© www.sojson.com<p> * 博客地址:http://www.sojson.com/blog/ <p> * <p> * * 动态加载权限 Service * * <p> * * 区分 责任人 日期 说明<br/> * 创建 周柏成 2016年6月2日 <br/> * * @author zhou-baicheng * @email so@sojson.com * @version 1.0,2016年6月2日 <br/> * */public class ShiroManagerImpl implements ShiroManager { // 注意/r/n前不能有空格 private static final String CRLF = "\r\n"; @Resource private ShiroFilterFactoryBean shiroFilterFactoryBean; @Override public String loadFilterChainDefinitions() { StringBuffer sb = new StringBuffer(); sb.append(getFixedAuthRule());//固定权限,采用读取配置文件 return sb.toString(); } /** * 从配额文件获取固定权限验证规则串 */ private String getFixedAuthRule(){ String fileName = "shiro_base_auth.ini"; ClassPathResource cp = new ClassPathResource(fileName); INI4j ini = null; try { ini = new INI4j(cp.getFile()); } catch (IOException e) { LoggerUtils.fmtError(getClass(), e, "加载文件出错。file:[%s]", fileName); } String section = "base_auth"; Set<String> keys = ini.get(section).keySet(); StringBuffer sb = new StringBuffer(); for (String key : keys) { String value = ini.get(section, key); sb.append(key).append(" = ") .append(value).append(CRLF); } return sb.toString(); } // 此方法加同步锁 @Override public synchronized void reCreateFilterChains() {// ShiroFilterFactoryBean shiroFilterFactoryBean = (ShiroFilterFactoryBean) SpringContextUtil.getBean("shiroFilterFactoryBean"); AbstractShiroFilter shiroFilter = null; try { shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject(); } catch (Exception e) { LoggerUtils.error(getClass(),"getShiroFilter from shiroFilterFactoryBean error!", e); throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!"); } PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter .getFilterChainResolver(); DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver .getFilterChainManager(); // 清空老的权限控制 manager.getFilterChains().clear(); shiroFilterFactoryBean.getFilterChainDefinitionMap().clear(); shiroFilterFactoryBean.setFilterChainDefinitions(loadFilterChainDefinitions()); // 重新构建生成 Map<String, String> chains = shiroFilterFactoryBean .getFilterChainDefinitionMap(); for (Map.Entry<String, String> entry : chains.entrySet()) { String url = entry.getKey(); String chainDefinition = entry.getValue().trim().replace(" ", ""); manager.createChain(url, chainDefinition); } } public void setShiroFilterFactoryBean( ShiroFilterFactoryBean shiroFilterFactoryBean) { this.shiroFilterFactoryBean = shiroFilterFactoryBean; }}
具体请查看:
本站发布的开源Demo项目:SpringMVC + Mybatis + Shiro + Redis 。
Github下载:https://github.com/baichengzhou/SpringMVC-Mybatis-shiro
本文详细介绍了Shiro框架结合SSM进行权限控制的方法,并探讨了如何优化配置过程以提高安全性及灵活性。通过使用Freemarker模板引擎,展示了如何在前后端进行有效的权限验证。

2463

被折叠的 条评论
为什么被折叠?



