67,538
社区成员
发帖
与我相关
我的任务
分享<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>MySpringSecutityDemo</display-name>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:com/masque/spring/applicationContext-*.xml,
</param-value>
</context-param>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<filter-class>
com.rstco.frame.modules.orm.hibernate.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>excludeSuffixs</param-name>
<param-value>js,css,jpg,gif</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
<filter>
<filter-name>struts2Filter</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.util.IntrospectorCleanupListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<session-config>
<session-timeout>20</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/common/500.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/common/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/common/404.jsp</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/common/403.jsp</location>
</error-page>
<mime-mapping>
<extension>rar</extension>
<mime-type>application/rar</mime-type>
</mime-mapping>
</web-app><?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:security="http://www.springframework.org/schema/security"
xmlns:b="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<b:description>SpringSecurity安全配置</b:description>
<!-- <security:http ></security:http>
<security:http security="none" pattern="/images/**"></security:http>
<security:http security="none" pattern="/js/**"></security:http>
<security:http security="none" pattern="/login.jsp"></security:http> -->
<!-- http安全配置 -->
<security:http auto-config="true">
<security:intercept-url pattern="/css/**" filters="none" />
<security:intercept-url pattern="/images/**" filters="none" />
<security:intercept-url pattern="/js/**" filters="none" />
<security:intercept-url pattern="/login.jsp" filters="none" />
<!--
<intercept-url pattern="/index.jsp" access="ROLE_USER"/>
<intercept-url pattern="/main.jsp" access="ROLE_ADAMIN"/>
-->
<security:form-login login-page="/login.jsp" default-target-url="/index.jsp"
authentication-failure-url="/login.jsp?error=1" />
<!-- 尝试访问没有权限的页面时跳转的页面 -->
<security:access-denied-handler error-page="/common/403.jsp"/>
<security:logout logout-success-url="/login.jsp" /><security:session-management>
<security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</security:session-management>
<!-- 增加一个filter,这点与Acegi是不一样的,不能修改默认的filter了,
这个filter位于FILTER_SECURITY_INTERCEPTOR之前 -->
<security:custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
</security:http>
<!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性,
我们的所有控制将在这三个类中实现,解释详见具体配置 -->
<b:bean id="myFilter" class="com.masque.springsecutity.interceptor.MyFilterSecurityInterceptor">
<b:property name="authenticationManager"
ref="authenticationManager" />
<b:property name="accessDecisionManager"
ref="myAccessDecisionManagerBean" />
<b:property name="securityMetadataSource"
ref="mySecurityMetadataSource" />
</b:bean>
<!-- 验证配置 , 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<!--
<s:password-encoder hash="sha" />
-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 项目实现的用户查询服务,将用户信息查询出来 -->
<b:bean id="userDetailsService" class="com.masque.springsecutity.support.MyUserDetailService" />
<!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->
<b:bean id="myAccessDecisionManagerBean"
class="com.masque.springsecutity.support.MyAccessDecisionManager">
</b:bean>
<!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色访问 -->
<b:bean id="mySecurityMetadataSource"
class="com.masque.springsecutity.support.MyInvocationSecurityMetadataSourceService">
</b:bean>
</b:beans>
package com.masque.springsecutity.support;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;
import org.springframework.security.web.FilterInvocation;
import com.masque.springsecutity.beans.PubAuthorities;
import com.masque.springsecutity.beans.PubResources;
import com.masque.springsecutity.dao.PubAuthoritiesDao;
import com.masque.springsecutity.dao.PubAuthoritiesResourcesDao;
import com.masque.springsecutity.dao.PubResourcesDao;
/*
* select resource_string from Pub_Authorities_Resources,Pub_Resources,Pub_authorities
* where Pub_Authorities_Resources.resource_id=Pub_Resources.resource_id and
* Pub_Authorities_Resources.resource_id=Pub_authorities.authority_id
* and Authority_name="aaa"
* 最核心的地方,就是提供某个资源对应的权限定义,即getAttributes方法返回的结果。
* 注意,我例子中使用的是AntUrlPathMatcher这个path matcher来检查URL是否与资源定义匹配,
* 事实上你还要用正则的方式来匹配,或者自己实现一个matcher。
*
* 此类在初始化时,应该取到所有资源及其对应角色的定义
*
* 说明:对于方法的spring注入,只能在方法和成员变量里注入,
* 如果一个类要进行实例化的时候,不能注入对象和操作对象,
* 所以在构造函数里不能进行操作注入的数据。
*/
@SuppressWarnings("all")
public class MyInvocationSecurityMetadataSourceService implements
FilterInvocationSecurityMetadataSource {
private PubAuthoritiesResourcesDao authoritiesResourcesDao;
private PubAuthoritiesDao authoritiesDao;
private PubResourcesDao resourcesDao;
public void setResourcesDao(PubResourcesDao resourcesDao) {
this.resourcesDao = resourcesDao;
}
public static void setResourceMap(
Map<String, Collection<ConfigAttribute>> resourceMap) {
MyInvocationSecurityMetadataSourceService.resourceMap = resourceMap;
}
public void setAuthoritiesDao(PubAuthoritiesDao authoritiesDao) {
this.authoritiesDao = authoritiesDao;
}
private UrlMatcher urlMatcher = new AntUrlPathMatcher();
private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
public void setAuthoritiesResourcesDao(
PubAuthoritiesResourcesDao authoritiesResourcesDao) {
this.authoritiesResourcesDao = authoritiesResourcesDao;
}
public MyInvocationSecurityMetadataSourceService() throws Exception {
loadResourceDefine();
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
// guess object is a URL.
String url = ((FilterInvocation) object).getRequestUrl();
Iterator<String> ite = resourceMap.keySet().iterator();
while (ite.hasNext()) {
String resURL = ite.next();
if (urlMatcher.pathMatchesUrl(url, resURL)) {
return resourceMap.get(resURL);
}
}
return null;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
/*
* private void loadResourceDefine() { resourceMap = new HashMap<String,
* Collection<ConfigAttribute>>(); Collection<ConfigAttribute> atts = new
* ArrayList<ConfigAttribute>(); ConfigAttribute ca = new
* SecurityConfig("ROLE_ADMIN"); atts.add(ca); resourceMap.put("/index.jsp",
* atts); resourceMap.put("/i.jsp", atts); }
*/
private void loadResourceDefine() throws Exception {
/*
* ApplicationContext context = new ClassPathXmlApplicationContext(
* "applicationContext-*.xml"); SessionFactory sessionFactory =
* (SessionFactory) context .getBean("sessionFactory");
*
* Session session = sessionFactory.openSession();
*/
List<PubAuthorities> list = authoritiesDao.getAllAuthorities();
List<String> query = getAuthorityName(list);
resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
// List<PubAuthorities> auths =session.createQuery(arg0);
// //pubAuthoritiesResourcesDao.findAuthAll();
for (String auth : query) {
ConfigAttribute ca = new SecurityConfig(auth);// "ROLE_ADMIN"
// atts.add(ca);
/*
* List<String> query1 = session .createSQLQuery(
* "select resource_string " +
* "from Pub_Authorities_Resources,Pub_Resources, Pub_authorities "
* +
* "where Pub_Authorities_Resources.resource_id=Pub_Resources.resource_id and "
* +
* " Pub_Authorities_Resources.resource_id=Pub_authorities.authority_id and "
* + " Authority_name='" + auth + "'") .list();
*/
List<PubResources> resourcesList = resourcesDao
.getPubResourcesListByAuthorityName(auth);
List<String> ResourceStringList = getResourceString(resourcesList);
for (String res : ResourceStringList) {
String url = res;
// 判断资源文件和权限的对应关系,如果已经存在,要进行增加
if (resourceMap.containsKey(url)) {
Collection<ConfigAttribute> value = resourceMap.get(url);
value.add(ca);
resourceMap.put(url, value);
// "log.jsp","role_user,role_admin"
} else {
atts.add(ca);
resourceMap.put(url, atts);
}
resourceMap.put(url, atts);
}
}
}
// According to a URL, Find out permission configuration of this URL.
private List<String> getAuthorityName(List<PubAuthorities> list) {
List<String> query = new ArrayList<String>();
for (PubAuthorities authorities : list) {
query.add(authorities.getAuthorityName());
}
return query;
}
private List<String> getResourceString(List<PubResources> list) {
List<String> query = new ArrayList<String>();
for (PubResources resources : list) {
query.add(resources.getResourceString());
}
return query;
}
}
package com.masque.springsecutity.support;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
//In this method, need to compare authentication with configAttributes.
// 1, A object is a URL, a filter was find permission configuration by this URL, and pass to here.
// 2, Check authentication has attribute in permission configuration (configAttributes)
// 3, If not match corresponding authentication, throw a AccessDeniedException.
import org.springframework.security.core.GrantedAuthority;
public class MyAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
if(configAttributes == null) return;
System.out.println(object.toString()); //object is a URL.
Iterator<ConfigAttribute> ite=configAttributes.iterator();
while(ite.hasNext()){
ConfigAttribute ca=ite.next();
String needRole=((SecurityConfig)ca).getAttribute();
for(GrantedAuthority ga:authentication.getAuthorities()){
if(needRole.equals(ga.getAuthority())){ //ga is user's role.
return;
}
}
}
throw new AccessDeniedException("no right");
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
package com.masque.springsecutity.interceptor;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
/**
* 一、 这个过滤器要插入到授权之前。最核心的代码就是invoke方法中的InterceptorStatusToken token =
* super.beforeInvocation
* (fi);这一句,即在执行doFilter之前,进行权限的检查,而具体的实现已经交给accessDecisionManager了
*
* @author Masque 下午6:03:15 2013 MyFilterSecurityInterceptor.java
*/
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor
implements Filter {
private FilterInvocationSecurityMetadataSource securityMetadataSource;
AuthenticationManager authenticationManager;
AccessDecisionManager accessDecisionManager;
//private SecurityMetadataSource securityMetadataSource;
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
/*public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public void setAccessDecisionManager(AccessDecisionManager accessDecisionManager) {
this.accessDecisionManager = accessDecisionManager;
}*/
public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
return this.securityMetadataSource;
}
public Class<? extends Object> getSecureObjectClass() {
return FilterInvocation.class;
}
public void invoke(FilterInvocation fi) throws IOException,
ServletException {
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
public void setSecurityMetadataSource(
FilterInvocationSecurityMetadataSource securityMetadataSource) {
System.out.println("abc=======================edf");
this.securityMetadataSource = securityMetadataSource;
}
public void destroy() {
}
public void init(FilterConfig filterconfig) throws ServletException {
}
}