<?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.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> <!-- org.springframework.security.providers.dao.cache.EhCacheBasedUserCache --> <beans:bean id="userCache" class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache"> <beans:property name="cache" ref="userEhCache" /> </beans:bean> <beans:bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> <beans:bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <beans:property name="cacheManager" ref="cacheManager" /> <beans:property name="cacheName" value="userCache" /> </beans:bean> <!-- jsp 资源保护 --> <http auto-config="true" access-denied-page="/common/403.jsp" session-fixation-protection="none"> <!-- intercept-url pattern="/admin.jsp" requires-channel="https"/ --> <!-- <intercept-url pattern="/" filters="none" />限制匿名登陆 --> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/" /> <logout logout-success-url="/login.jsp" /> <port-mappings> <port-mapping http="8080" https="9443" /> </port-mappings> <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true" /> <!-- 匿名身份:Guest --> <anonymous username="Guest" /> </http> <!-- 用户 合法性认证 --> <authentication-provider> <password-encoder hash="md5" /> <jdbc-user-service data-source-ref="dataSource" users-by-username-query="SELECT userinfo_name,userinfo_pwd,1 AS 'enabled' FROM up_userinfo WHERE userinfo_name = ? " authorities-by-username-query="SELECT up_userinfo.userinfo_name,('ROLE_'+LTRIM(str(up_role.role_id))) as 'role' FROM up_userrole inner join up_userinfo on up_userrole.userinfo_id=up_userinfo.userinfo_id inner join up_role on up_role.role_id=up_userrole.role_id WHERE up_userinfo.userinfo_name = ? " cache-ref="userCache" /> </authentication-provider> <beans:bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor" autowire="byType"> <custom-filter before="FILTER_SECURITY_INTERCEPTOR" /> <beans:property name="objectDefinitionSource" ref="filterInvocationDefinitionSource" /> </beans:bean> <!-- 根据数据库中的内容自动为用户授权 --> <beans:bean id="filterInvocationDefinitionSource" class="org.springframework.security.SecureFilter.MySecureResourceFilter"> <beans:property name="dataSource" ref="dataSource" /> <beans:property name="resourceQuery" value="select distinct _source.resource_link, ('ROLE_'+LTRIM(str(_role.role_id))) as ROLE ,_role.role_name from up_role _role JOIN up_privilege _pri ON _role.role_id=_pri.role_id JOIN up_resource _source ON _pri.resource_id=_source.resource_id WHERE _source.resource_link not like ''" /> </beans:bean> <!-- 数据源 --> <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <beans:property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" /> <beans:property name="url" value="jdbc:jtds:sqlserver://localhost:1433;DatabaseName=eBuilder_egov;useLOBs=false" /> <beans:property name="username" value="sa" /> <beans:property name="password" value="sa1" /> </beans:bean> <!-- logger debug listener --> <beans:bean id="loggerListener" class="org.springframework.security.event.authentication.LogListener" /> </beans:beans>
需要些什么包呢:
Web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class> org.springframework.web.filter.DelegatingFilterProxy </filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <listener> <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class> </listener> </web-app>
自定义的一个加载权限和角色对应的类
MySecureResourceFilter.java
package org.springframework.security.SecureFilter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor;
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.AntUrlPathMatcher;
import org.springframework.security.util.UrlMatcher;
/**
* SS(Spring Security) 根据Web.xml指定的xml配置文件(在其中配置好resourceQuery)自动授权
* @author 杨伦亮
* Dec 14, 2010
*/
public class MySecureResourceFilter extends JdbcDaoSupport implements FactoryBean {
private String resourceQuery;
private final Log log=LogFactory.getLog(MySecureResourceFilter.class);
public boolean isSingleton() {
return true;
}
public Class getObjectType() {
return FilterInvocationDefinitionSource.class;
}
/**
* 我扩展的功能: urlMatcher和requestMap创建DefaultFilterInvocationDefinitionSource。
*/
public Object getObject() {
return new DefaultFilterInvocationDefinitionSource(this.getUrlMatcher(), this
.buildRequestMap());
}
/**
* 方法获得所有资源信息。<br>默认的情况是从XML配置文件中读取此信息即类似URL与ROLE_ADMIN信息。现在改为自定义地去查找数据库中的信息并与之对应
* @return Map
*/
protected Map<String, String> findResources() {
//获得DataSource
ResourceMapping resourceMapping = new ResourceMapping(getDataSource(), resourceQuery);
Map<String, String> resourceMap = new LinkedHashMap<String, String>();
String url,role,value;
//execute()方法获得所有资源信息。
Log log=LogFactory.getLog(MySecureResourceFilter.class);
for(Resource resource : (List<Resource>) resourceMapping.execute()){
url = resource.getUrl();
role = resource.getRole();
if(resourceMap.containsKey(url)){
value = resourceMap.get(url);
log.info(url+"\t授权:"+value+","+role+"\n");
resourceMap.put(url, value +"," +role);
}else{
log.info(url+"\t授权:"+role+"\n");
resourceMap.put(url, role);
}
}
return resourceMap;
}
/**
* 使用获得的资源信息组装requestMap。
* @return LinkedHashMap
*/
protected LinkedHashMap<RequestKey, ConfigAttributeDefinition> buildRequestMap() {
LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = null;
requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>();
ConfigAttributeEditor editor = new ConfigAttributeEditor();
Map<String, String> resourceMap = this.findResources();
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 UrlMatcher getUrlMatcher() {
return new AntUrlPathMatcher();
}
public void setResourceQuery(String resourceQuery) {
log.info("setResourceQuery()\t"+resourceQuery);
this.resourceQuery = resourceQuery;
}
/**
* 资源属性<br>链接地址及角色名
* @author 杨伦亮
* Dec 15, 2010
*/
private class Resource {
private String url;
private String role;
public Resource(String url, String role) {
this.url = url;
this.role = role;
}
public String getUrl() {
return url;
}
public String getRole() {
return role;
}
}
private class ResourceMapping extends MappingSqlQuery {
protected ResourceMapping(DataSource dataSource, String resourceQuery) {
super(dataSource, resourceQuery);
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
String url = rs.getString(1);
String role = rs.getString(2);
Resource resource = new Resource(url, role);
return resource;
}
}
}
下面来测试一下配置信息是否对
admin.jsp
<%@ page language="java"
import="java.util.*,org.springframework.security.*,org.springframework.security.userdetails.*,org.springframework.security.context.*"
pageEncoding="UTF-8"%>
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body >
<h3>
<a href="index.jsp">Home</a> |
<a href="admin.jsp" target=_blank>试试访问受保护的jsp(403表示无权限访问)</a> |
<a href="button_admin.jsp">只保护jsp中的按钮</a> | 当前用户
<a href="j_spring_security_logout">重新登陆</a>
:
<sec:authentication property="name"></sec:authentication>[${authentication.username }]
<input type="button" value='<sec:authentication property="name" />' />
</h3>
<p>
权限列表:
</p>
<%
try{
//当前登陆对象
SecurityContext sec = SecurityContextHolder.getContext();
UserDetails userDetails = (UserDetails) sec.getAuthentication().getPrincipal();
out.print("["+userDetails.getUsername()+"]<br>");
//取得权限列表
GrantedAuthority[] authorities = userDetails.getAuthorities();
for(int size = authorities.length, i = 0; i <size; i++){
if(authorities[i] ==null)
break;
out.print("<br><font color=green>" +authorities[i] ==null ? "" : authorities[i].toString()+"</font>");
}
}catch(Exception e){
out.print("<script>document.write('<font color=ffffff>Exception:!!!" +e.getMessage()
+"</font>');</script>");
}
%>
<font color=ffffff>
<sec:authentication property="authorities" />
</font>
<br>
<hr><h3>Session:</h3>
<%
Enumeration<String> s=session.getAttributeNames();
try{
//UserDetails userdetails=(UserDetails)session.getAttribute();
while(s.hasMoreElements()){
String key=s.nextElement();
out.println("<font color=red>"+key+"</font> <font color=green>"+session.getAttribute(key)+"</font><br>");
//这里的s.nextElement()就对应了每一个键名 通过他取值就可以了
}
}catch(java.util.NoSuchElementException e){
out.println("认证失败"+e.getMessage());
}
%>
</body>
</html>