修改spring security源码实现动态授权
2009-02-08 17:46
411 查看
spring security 安全框架都是通过xml配置文件在容器启动时把资源和角色之间的许可信息加载到内存中,可往往我们需要通过在数据库中配置资源和角色的许可管理来实现动态授权,下面介绍一些通过修改springsecurity源代码的方法来实现动态授权。
首先下载spring security的源代码找到org.springframework.security.intercept.web.FilterSecurityInterceptor类,找到obtainObjectDefinitionSource方法,我们就是要通过修改该方法实现动态授权
private static FilterInvocationDefinitionSource s = null;
private ScRoleResDAO scRoleResDAO;
private ScResourceDAO scResourceDAO;
public ObjectDefinitionSource obtainObjectDefinitionSource() {
if (s == null){
UrlMatcher urlMatcher = new AntUrlPathMatcher(true);
LinkedHashMap requestMap = new LinkedHashMap();
// ApplicationContext context = new ClassPathXmlApplicationContext(
// "spring/dataAccess.xml"
// );
// ScRoleResDAO scRoleResDAO = (ScRoleResDAO)context.getBean("ScRoleResDAO");
// ScResourceDAO scResourceDAO = (ScResourceDAO)context.getBean("ScResourceDAO");
/* 一下这段代码可以忽视,因为每个人的实现方式都不同,
* 这段代码主要是从数据库中取得资源和角色信息的,
* 大家取出来的信息格式可能多种多样,关键是要把这些信息整理成统一的格式
* 参照下面第二段标注为关键代码的部分*/
Map<ScResource, List<ScRoleRes>> map = new TreeMap<ScResource, List<ScRoleRes>>();
ScResourceExample e = new ScResourceExample();
e.setOrderByClause("ORDER_NUM");
List<ScResource> resList = scResourceDAO.selectByExample(e);
ScRoleResExample example = null;
String url = "";
List<ScRoleRes> list = null;
for (ScResource resource : resList) {
url = resource.getUrl();
example = new ScRoleResExample();
example.createCriteria().andUrlEqualTo(url);
list = scRoleResDAO.selectByExample(example);
if (list != null){
map.put(resource, list);
}
}
/**************** 以下是关键代码 *********************/
/*
* 这段代码的重点是生成 requestMap
* requestMap 的 key 的类型为 RequestKey ,需要包含资源的url
* requestMap 的 value 的类型为 ConfigAttributeDefinition ,它需要包含该资源可访问的角色列表信息
* 最后生成 DefaultFilterInvocationDefinitionSource 返回就可以了,
* 当然需要把这个结果保存在内存中,要不然画面上每次刷新都要从数据库中取得信息,资源消耗太大了
* 提供一个刷内存的方法,当数据库中的权限信息改变时要刷新内存中的旧的信息*/
Iterator iterator = map.entrySet().iterator();
ScResource key = null;
List<ScRoleRes> list1 = null;
List<ConfigAttribute> roles = null;
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
key = (ScResource)entry.getKey();
RequestKey reqKey = new RequestKey(key.getUrl());
list1 = (List<ScRoleRes>)entry.getValue();
roles = new ArrayList<ConfigAttribute>();
for (ScRoleRes res : list1) {
roles.add(new SecurityConfig(res.getRole()));
}
requestMap.put(reqKey, new ConfigAttributeDefinition(roles));
}
s = new DefaultFilterInvocationDefinitionSource(urlMatcher,requestMap);
/**************** 以上是关键代码 *********************/
}
return s;
}
/**
* 提供一个刷新内存的静态方法
*/
public static void refresh() {
s = null;
修改启动加载的xml文件,如果此文件是通过命名空间配置的,需要加入
<beans:bean id="_filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor"
p:authenticationManager-ref="_authenticationManager"
p:accessDecisionManager-ref="accessDecisionManager">
<beans:property name="objectDefinitionSource">
<beans:value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=ROLE_SUPERVISOR
]]></beans:value>
</beans:property>
<beans:property name="scRoleResDAO" ref="ScRoleResDAO"/>
<beans:property name="scResourceDAO" ref="ScResourceDAO"/>
</beans:bean>
其中objectDefinitionSource并没有实际意义,因为我们已经修改了源代码,如果不想注入这个,把FilterSecurityInterceptor类中的objectDefinitionSource变量去掉应该就可以了,不过没有试过
另外两个DAO是我根据我的代码注入的,大家换成自己的DAO就可以了。
可能说的不清楚,不明白的给我邮件cyoubunketu@126.com
}
首先下载spring security的源代码找到org.springframework.security.intercept.web.FilterSecurityInterceptor类,找到obtainObjectDefinitionSource方法,我们就是要通过修改该方法实现动态授权
private static FilterInvocationDefinitionSource s = null;
private ScRoleResDAO scRoleResDAO;
private ScResourceDAO scResourceDAO;
public ObjectDefinitionSource obtainObjectDefinitionSource() {
if (s == null){
UrlMatcher urlMatcher = new AntUrlPathMatcher(true);
LinkedHashMap requestMap = new LinkedHashMap();
// ApplicationContext context = new ClassPathXmlApplicationContext(
// "spring/dataAccess.xml"
// );
// ScRoleResDAO scRoleResDAO = (ScRoleResDAO)context.getBean("ScRoleResDAO");
// ScResourceDAO scResourceDAO = (ScResourceDAO)context.getBean("ScResourceDAO");
/* 一下这段代码可以忽视,因为每个人的实现方式都不同,
* 这段代码主要是从数据库中取得资源和角色信息的,
* 大家取出来的信息格式可能多种多样,关键是要把这些信息整理成统一的格式
* 参照下面第二段标注为关键代码的部分*/
Map<ScResource, List<ScRoleRes>> map = new TreeMap<ScResource, List<ScRoleRes>>();
ScResourceExample e = new ScResourceExample();
e.setOrderByClause("ORDER_NUM");
List<ScResource> resList = scResourceDAO.selectByExample(e);
ScRoleResExample example = null;
String url = "";
List<ScRoleRes> list = null;
for (ScResource resource : resList) {
url = resource.getUrl();
example = new ScRoleResExample();
example.createCriteria().andUrlEqualTo(url);
list = scRoleResDAO.selectByExample(example);
if (list != null){
map.put(resource, list);
}
}
/**************** 以下是关键代码 *********************/
/*
* 这段代码的重点是生成 requestMap
* requestMap 的 key 的类型为 RequestKey ,需要包含资源的url
* requestMap 的 value 的类型为 ConfigAttributeDefinition ,它需要包含该资源可访问的角色列表信息
* 最后生成 DefaultFilterInvocationDefinitionSource 返回就可以了,
* 当然需要把这个结果保存在内存中,要不然画面上每次刷新都要从数据库中取得信息,资源消耗太大了
* 提供一个刷内存的方法,当数据库中的权限信息改变时要刷新内存中的旧的信息*/
Iterator iterator = map.entrySet().iterator();
ScResource key = null;
List<ScRoleRes> list1 = null;
List<ConfigAttribute> roles = null;
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
key = (ScResource)entry.getKey();
RequestKey reqKey = new RequestKey(key.getUrl());
list1 = (List<ScRoleRes>)entry.getValue();
roles = new ArrayList<ConfigAttribute>();
for (ScRoleRes res : list1) {
roles.add(new SecurityConfig(res.getRole()));
}
requestMap.put(reqKey, new ConfigAttributeDefinition(roles));
}
s = new DefaultFilterInvocationDefinitionSource(urlMatcher,requestMap);
/**************** 以上是关键代码 *********************/
}
return s;
}
/**
* 提供一个刷新内存的静态方法
*/
public static void refresh() {
s = null;
修改启动加载的xml文件,如果此文件是通过命名空间配置的,需要加入
<beans:bean id="_filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor"
p:authenticationManager-ref="_authenticationManager"
p:accessDecisionManager-ref="accessDecisionManager">
<beans:property name="objectDefinitionSource">
<beans:value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=ROLE_SUPERVISOR
]]></beans:value>
</beans:property>
<beans:property name="scRoleResDAO" ref="ScRoleResDAO"/>
<beans:property name="scResourceDAO" ref="ScResourceDAO"/>
</beans:bean>
其中objectDefinitionSource并没有实际意义,因为我们已经修改了源代码,如果不想注入这个,把FilterSecurityInterceptor类中的objectDefinitionSource变量去掉应该就可以了,不过没有试过
另外两个DAO是我根据我的代码注入的,大家换成自己的DAO就可以了。
可能说的不清楚,不明白的给我邮件cyoubunketu@126.com
}
相关文章推荐
- Android 4.2 通过修改FrameWork源码实现动态隐藏导航栏,实现全屏
- (六)SSO之CAS框架扩展 修改CAS源码实现与ESS动态密码验证对接
- Android 4.2 通过修改FrameWork源码实现动态隐藏导航栏,实现全屏
- 【iOS-Cocos2d游戏开发之十五】详解CCProgressTimer 进度条并修改cocos2d源码实现“理想”游戏进度条!
- 修改Zend引擎实现PHP源码加密的原理及实践
- Spring Boot 定时任务实现后台管理动态配置(动态添加修改删除定时任务)
- java应用(非web应用)中log4j.properties动态修改配置文件,无需重启,就能立即生效,如何实现?
- 修改mybatis-generate源码实现实体类加上字段注释
- java用DFA实现脏词过滤以及用FileAlterationListenerAdaptor实现对资源文件修改的动态监听
- Java动态代理详解,以及底层JDK源码实现分析(基于Java8)。
- easyui修改源码实现combobox的真正模糊查询
- spring security 3.1中基于数据库自定义验证授权功能实现
- Spring Security源码分析十二:Spring Security OAuth2基于JWT实现单点登录
- Flume NG源码分析(二)支持运行时动态修改配置的配置模块
- android后台截屏实现(2)--screencap源码修改
- Spring 3整合Quartz 2实现定时任务三:动态暂停 恢复 修改和删除任务
- 通过JS来动态的修改url,实现对url的增删查改
- 基于cglib实现的动态代理原理与源码解析
- Android Apk资源加载机制源码分析以及资源动态加载实现系列文章
- 从UGUI源码中想到的UI动态”挖洞”效果的实现(蒙版过滤)