shiro安全框架扩展教程--如何动态修改资源权限不需要重启项目
来源:互联网 发布:高清网络智能机顶盒 编辑:程序博客网 时间:2024/05/17 12:46
大家好,感觉好长时间没有上来更新博客的样子,因为上段时间都忙着泡妞,请见谅,最后妞没泡到,只能继续伤心研究代码,之后的几个文章都是关于shiro框架的,网上关于这个框架的资料都是泛泛而谈,没有跟实际应用结合到一起,然后我把自己的一些应用心得,以及如何扩展该框架适用于我们应用项目的做法,分享给大家...大家贱笑了
不说笑了,言归正传,我不说如何配置基本的架子了,这个大家自行去看吧,网上太多了,我只说关键点...
下面看看我的主过滤器配置
<!-- 过滤链配置 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><property name="loginUrl" value="/" /><property name="successUrl" value="/cms/index.do" /><property name="unauthorizedUrl" value="/" /><property name="filters"><map><entry key="role"><beanclass="com.silvery.security.shiro.filter.RoleAuthorizationFilter" /></entry><entry key="authc"><beanclass="com.silvery.security.shiro.filter.SimpleFormAuthenticationFilter" /></entry></map></property></bean><!-- 权限资源配置 --><bean id="filterChainDefinitionsService"class="com.silvery.security.shiro.service.impl.SimpleFilterChainDefinitionsService"><property name="definitions"><value>/static/** = anon/admin/user/login.do = anon/test/** = role[user,admin]/abc/** = authc</value></property></bean>
可以看到我没有在主过滤器上配置资源,而是自己独立写的一个服务类来配置资源,为何这样做呢,下面看看我设计的这个实现类
/** * * 加载第三方角色资源配置服务类 * * @author shadow * */public class SimpleFilterChainDefinitionsService extends AbstractFilterChainDefinitionsService {@Overridepublic Map<String, String> initOtherPermission() {// extend to load other permissionreturn new HashMap<String, String>();}}
很明显看到我写的方法说明,这是加载第三方资源的方法,比如说这里加载数据库资源,或者是其他文件上的配置资源,只要把资源读取出来拼成一个map返回即可,因为我们都知道shiro最终需要的是一个键值对形式的资源
既然这里是加载第三方资源的,如果没有第三方资源那直接返回一个空集合即可,那他是如何加载原始的配置资源?因为我们实际项目都知道一部分的固定资源都会写在主过滤器那里,所以考虑到的是,必须要加载一次原始的配置资源,还要再加载一次第三方资源,双管齐下即可;下面看看我的父级抽象类
/** * * 安全框架角色资源配置服务类 * * @author shadow * */public abstract class AbstractFilterChainDefinitionsService implements FilterChainDefinitionsService {private final static Logger log = LoggerFactory.getLogger(AbstractFilterChainDefinitionsService.class);private String definitions = "";@Autowiredprivate ShiroFilterFactoryBean shiroFilterFactoryBean;@PostConstructpublic void intiPermission() {shiroFilterFactoryBean.setFilterChainDefinitionMap(obtainPermission());log.debug("initialize shiro permission success...");}public void updatePermission() {synchronized (shiroFilterFactoryBean) {AbstractShiroFilter shiroFilter = null;try {shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();} catch (Exception e) {log.error(e.getMessage());}// 获取过滤管理器PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();// 清空初始权限配置manager.getFilterChains().clear();shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();// 重新构建生成shiroFilterFactoryBean.setFilterChainDefinitions(definitions);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);}log.debug("update shiro permission success...");}}/** 读取配置资源 */private Section obtainPermission() {Ini ini = new Ini();ini.load(definitions); // 加载资源文件节点串Section section = ini.getSection("urls"); // 使用默认节点if (CollectionUtils.isEmpty(section)) {section = ini.getSection(Ini.DEFAULT_SECTION_NAME); // 如不存在默认节点切割,则使用空字符转换}Map<String, String> permissionMap = initOtherPermission();if (permissionMap != null && !permissionMap.isEmpty()) {section.putAll(permissionMap);}return section;}public abstract Map<String, String> initOtherPermission();public String getDefinitions() {return definitions;}public void setDefinitions(String definitions) {this.definitions = definitions;}}
很明显看到为何我没有在主过滤器上配置资源,但是依然会加载资源,是由于我是手动调用了shiroFilterFactoryBean.setFilterChainDefinitionMap(obtainPermission());这个方法自动把资源设置进去;而且obtainPermission()方法中也会调用抽象接口方法加载第三方资源,所以这样就实现了我的加载原生配置,又能加载第三方资源,这样设计我觉得比较灵活
下面是另外一个重点,如何更新资源,可参考我写的updatePermission()方法,主要是清空DefaultFilterChainManager里面的FilterChains,还有shiroFilterFactoryBean里面的FilterChainDefinitions;我在网上看了好多关于这个清空资源,但是都不理想,其实是清空这两个地方,然后重新调用DefaultFilterChainManager的createChain方法,把资源重新设置进去即可,这里注意下线程安全即可
最后我把接口抽象出来,看看我的顶层接口
public interface FilterChainDefinitionsService {public static final String PREMISSION_STRING = "perms[{0}]"; // 资源结构格式public static final String ROLE_STRING = "role[{0}]"; // 角色结构格式/** 初始化框架权限资源配置 */public abstract void intiPermission();/** 重新加载框架权限资源配置 (强制线程同步) */public abstract void updatePermission();/** 初始化第三方权限资源配置 */public abstract Map<String, String> initOtherPermission();}
最后在应用里的某个地方,从spring中获取这个接口的实例,然后调用update方法就可以动态更新配置资源
我的shiro框架心得第一个要点分享完了,谢谢大家的香蕉皮,鸡蛋壳,如需继续拍砖,敬请期待下个文章...
- shiro安全框架扩展教程--如何动态修改资源权限不需要重启项目
- shiro 动态修改资源权限不需要重启项目或者重新登录用户
- shiro安全框架扩展教程--如何动态控制页面节点元素的权限
- shiro安全框架扩展教程--如何动态控制页面节点元素的权限
- shiro安全框架扩展教程--如何自定义适合项目的过滤器
- shiro安全框架扩展教程--如何扩展realm桥接器并退出自动清空角色资源缓存
- shiro框架不需要重启动态更新权限资源
- shiro安全框架扩展教程--如何扩展异步(ajax)请求认证失败处理
- shiro安全框架扩展教程--如何扩展实现集中式session管理
- shiro安全框架扩展教程--如何扩展实现集中式session管理(redis,memcached等)
- shiro安全框架扩展教程--如何扩展异步(ajax)请求认证失败处理
- shiro安全框架扩展教程--上传文件的安全控制
- shiro安全框架扩展教程--如何防止可执行文件的入侵攻击
- shiro安全框架扩展教程--设计数据对象校验器,如何防止xss以及csrf攻击
- Shiro动态修改权限
- shiro安全框架扩展教程--如何扩展实现我们的缓存机制(第三方容器redis,memcached)
- shiro安全框架扩展教程--如何扩展实现我们的缓存机制(第三方容器redis,memcached)
- shiro安全框架扩展教程--如何扩展实现我们的缓存机制(第三方容器redis,memcached)
- uploadify 在chrome浏览器下不能打开选择文件浏览框而在ff和ie下能正常打开
- 用二进制处理学生成绩
- Java 博客索引
- 数据结构——回文字符串
- 苹果App Store审核指南中文翻译(2014.9.1更新)
- shiro安全框架扩展教程--如何动态修改资源权限不需要重启项目
- 通过 ffmpeg 无损剪切/拼接视频
- 学校小型的实验室局域网络的搭建
- Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)的用法
- Android_json
- Android:文件下载和写入SD卡学习小结
- 程序员常去的14个顶级开发社区
- Tomcat负载均衡原理详解及配置(Apache2.2.19+Tomcat7.0.12) mod_proxy_blancer方式已经成功实现
- 6410 wicne6.0R3 IE浏览器显示问题