我昨天晚上在用spring security开发的时候写了下面主要的文件的代码
[code=Java]package a;public interface MessageService {
String adminMessage(); String adminDate(); String userMessage(); String userDate();
}
package a;public class MessageServiceImpl implements MessageService {
public String adminMessage() {
return "admin message";
} public String adminDate() {
return "admin " + System.currentTimeMillis();
} public String userMessage() {
return "user message";
} public String userDate() {
return "user " + System.currentTimeMillis();
}
}
[code=Java]package a;public interface MessageService {
String adminMessage(); String adminDate(); String userMessage(); String userDate();
}
package a;public class MessageServiceImpl implements MessageService {
public String adminMessage() {
return "admin message";
} public String adminDate() {
return "admin " + System.currentTimeMillis();
} public String userMessage() {
return "user message";
} public String userDate() {
return "user " + System.currentTimeMillis();
}
}
private String name;
private String role; public ResourceDetails() {
} public ResourceDetails(String name, String role) {
this.name = name;
this.role = role;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
}
}
package a;import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;import javax.sql.DataSource;import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor;
import org.springframework.security.intercept.method.MapBasedMethodDefinitionSource;
import org.springframework.security.intercept.method.MethodDefinitionSource;
import org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.RequestKey;
import org.springframework.security.util.UrlMatcher;
public class ResourceDetailsBuilder {
private DataSource dataSource; public ResourceDetailsBuilder(DataSource dataSource) {
this.dataSource = dataSource;
} public FilterInvocationDefinitionSource createUrlSource(String query,
UrlMatcher urlMatcher) {
return new DefaultFilterInvocationDefinitionSource(urlMatcher,
this.buildRequestMap(query));
} public MethodDefinitionSource createMethodSource(String query) {
return new MapBasedMethodDefinitionSource(this.buildMethodMap(
query));
} protected LinkedHashMap<RequestKey, ConfigAttributeDefinition> buildRequestMap(
String query) {
LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = null;
requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>(); ConfigAttributeEditor editor = new ConfigAttributeEditor(); Map<String, String> resourceMap = this.findResources(query); for (Map.Entry<String, String> entry : resourceMap.entrySet()) {
RequestKey key = new RequestKey(entry.getKey(), null);
editor.setAsText(entry.getValue());
requestMap.put(key,
(ConfigAttributeDefinition) editor.getValue());
} return requestMap;
} protected Map<String, ConfigAttributeDefinition> buildMethodMap(
String query) {
Map<String, ConfigAttributeDefinition> methodMap = null;
methodMap = new LinkedHashMap<String, ConfigAttributeDefinition>(); ConfigAttributeEditor editor = new ConfigAttributeEditor();
Map<String, String> resourceMap = this.findResources(query); for (Map.Entry<String, String> entry : resourceMap.entrySet()) {
editor.setAsText(entry.getValue());
methodMap.put(entry.getKey(),
(ConfigAttributeDefinition) editor.getValue());
System.out.println("=========================");
System.out.println(entry.getKey());
}
return methodMap;
} protected Map<String, String> findResources(String query) {
ResourceDetailsMapping resourceDetailsMapping = new ResourceDetailsMapping(dataSource,
query); Map<String, String> resourceMap = new LinkedHashMap<String, String>();
List<ResourceDetails> resources = resourceDetailsMapping.execute(); for (ResourceDetails resourceDetails : resources) {
String name = resourceDetails.getName();
String role = resourceDetails.getRole(); if (resourceMap.containsKey(name)) {
String value = resourceMap.get(name);
resourceMap.put(name, value + "," + role);
} else {
resourceMap.put(name, role);
}
} return resourceMap;
}
}
import java.sql.SQLException;import javax.sql.DataSource;import org.springframework.jdbc.object.MappingSqlQuery;
public class ResourceDetailsMapping extends MappingSqlQuery {
protected ResourceDetailsMapping(DataSource dataSource,
String resourceQuery) {
super(dataSource, resourceQuery);
compile();
} protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String name = rs.getString(1);
String role = rs.getString(2);
ResourceDetails resourceDetails = new ResourceDetails(name, role); return resourceDetails;
}
}package a;import java.util.ArrayList;
import java.util.List;import javax.sql.DataSource;import org.springframework.beans.factory.InitializingBean;import org.springframework.security.intercept.method.DelegatingMethodDefinitionSource;
import org.springframework.security.intercept.method.MethodDefinitionSource;
import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
import org.springframework.security.intercept.method.aspectj.AspectJSecurityInterceptor;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.FilterSecurityInterceptor;
import org.springframework.security.util.AntUrlPathMatcher;
import org.springframework.security.util.UrlMatcher;
public class ResourceDetailsMonitor implements InitializingBean {
private String queryUrl = "select re.res_string,r.name"
+ " from role r"
+ " join resc_role rr"
+ " on r.id=rr.role_id"
+ " join resc re"
+ " on re.id=rr.resc_id"
+ " where re.res_type='URL'"
+ " order by re.priority";
private String queryMethod = "select re.res_string,r.name"
+ " from role r"
+ " join resc_role rr"
+ " on r.id=rr.role_id"
+ " join resc re"
+ " on re.id=rr.resc_id"
+ " where re.res_type='METHOD'"
+ " order by re.priority";
private DataSource dataSource;
private FilterSecurityInterceptor filterSecurityInterceptor;
private DelegatingMethodDefinitionSource delegatingMethodDefinitionSource;
private ResourceDetailsBuilder resourceDetailsBuilder; public void setQueryUrl(String queryUrl) {
this.queryUrl = queryUrl;
} public void setQueryMethod(String queryMethod) {
this.queryMethod = queryMethod;
} public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
} public void setFilterSecurityInterceptor(
FilterSecurityInterceptor filterSecurityInterceptor) {
this.filterSecurityInterceptor = filterSecurityInterceptor;
} public void setDelegatingMethodDefinitionSource(
DelegatingMethodDefinitionSource delegatingMethodDefinitionSource) {
this.delegatingMethodDefinitionSource = delegatingMethodDefinitionSource;
} protected UrlMatcher getUrlMatcher() {
return new AntUrlPathMatcher();
} public void afterPropertiesSet() {
resourceDetailsBuilder = new ResourceDetailsBuilder(dataSource);
refresh();
} public void refresh() {
if (filterSecurityInterceptor != null) {
FilterInvocationDefinitionSource source = resourceDetailsBuilder
.createUrlSource(queryUrl, getUrlMatcher());
filterSecurityInterceptor.setObjectDefinitionSource(source);
} if (delegatingMethodDefinitionSource != null) {
MethodDefinitionSource source = resourceDetailsBuilder
.createMethodSource(queryMethod);
List<MethodDefinitionSource> sources = new ArrayList<MethodDefinitionSource>();
sources.add(source);
delegatingMethodDefinitionSource.setMethodDefinitionSources(sources);
}
}
}
[/code]
下面是我配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<http auto-config="true"/> <authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,password,status as enabled
from user
where username=?"
authorities-by-username-query="select u.username,r.name as authority
from user u
join user_role ur
on u.id=ur.user_id
join role r
on r.id=ur.role_id
where u.username=?"/>
</authentication-provider> <global-method-security/>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<beans:property name="url" value="jdbc:mysql://localhost:3306/tests"/>
<beans:property name="username" value="root"/>
<beans:property name="password" value="root"/>
</beans:bean>
<beans:bean id="resourceDetailsMonitor" class="a.ResourceDetailsMonitor">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="filterSecurityInterceptor" ref="_filterSecurityInterceptor" />
<beans:property name="delegatingMethodDefinitionSource" ref="_delegatingMethodDefinitionSource" />
</beans:bean>
<beans:bean id="messageService" class="a.MessageServiceImpl"/>
</beans:beans>
我用是spring2.5 和security2.05开发主要是将要受限制的方法存入数据实现动态管理。开始怎么改都不行MessageService中的方法始终得不到保护,于是就换了spring2.0和security2.04还是不行,就睡觉了,今天开机打开昨天的页面。页面居然显示受保护,我又将tomcat里的数据全删除了换成spring2.5 和security2.05重新部署,居然可以受保护,你说奇怪不奇怪啊。大家有没有遇到过这种情况啊。
我的是一开始受保护,自定义后不受保护,再还原回一开始的配置文件后还是不受保护,而后某一次突然又受保护,最后重新自定义以后直到现在仍然受保护。
唉,好像绕口令,可是完全不知道哪里做错了。
猜想可能和tomcat的会话保存有关。重启tomcat不会导致会话立即失效,会话会在正常关闭tomcat的时候保存下来并在下一次启动tomcat时恢复。而Spring Security自行管理会话,它到底如何使用会话的,我们不得而知,还需要研究很久才能清楚。不过会话的超时还是正常的,所以过几十分钟不发送请求,就失效了。猜想,Spring Security会不会把一些东西放在会话里了?
是IE缓存?Java缓存? 还是其他?
换成 spring2.0.8 就好用