spring-secrity

一部分是自己项目中使用到的,一些是看网上大神写的,自己以前虽然用但是没有人家写的注释的那么详细。

所以都贴出来。以后如果发现又新的东西再继续添加。

这个是 spring-secrity 配置文件。 自己项目的配置

<?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-3.0.xsd  
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">


	<global-method-security pre-post-annotations="enabled" />
	<!-- HTTP安全配置 -->
	<http auto-config="false" entry-point-ref="authenticationEntryPoint">
		<intercept-url pattern="/login.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/index.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/m/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/commons/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/upload/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/cms/**" access="ROLE_USER"/>
        <intercept-url pattern="/adminIndex.html" access="ROLE_USER"/>
        <intercept-url pattern="/backstage/*.html" access="ROLE_USER"/>
		<!-- <form-login login-page="/login.html" 
		    default-target-url="/adminIndex.html" authentication-failure-url="/login.html?error=true" /> -->
        <logout logout-success-url="/login.html" logout-url="/j_spring_security_logout"/>
		<custom-filter ref="mySecurityFilter" before="FILTER_SECURITY_INTERCEPTOR" />
		<!-- //需要替换的Filter顺序,配置自定义custom-filter时必须蔣auto-config="false",不然会报已经存在同样的过滤器错误   -->
        <custom-filter ref="myLoginFilter" position="FORM_LOGIN_FILTER" /> 
	</http>
	
	<beans:bean id="myLoginFilter" class="com.base.filter.MyUsernamePasswordAuthenticationFilter">  
        <beans:property name="authenticationManager" ref="myAuthenticationManager"/>  
        <beans:property name="authenticationFailureHandler" ref="failureHandler"/>  
        <beans:property name="authenticationSuccessHandler" ref="successHandler"/>
    </beans:bean>
    
	<beans:bean id="authenticationEntryPoint"  
        class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
        <beans:property name="loginFormUrl" value="/login.html" />  
    </beans:bean>
    
	<!-- //成功登录后   -->
    <beans:bean id="successHandler" class="com.base.filter.MySavedRequestAwareAuthenticationSuccessHandler">  
        <beans:property name="defaultTargetUrl" value="/adminIndex.html"/>  
    </beans:bean>  
    <!-- //登录失败   -->
    <beans:bean id="failureHandler" class="com.base.filter.MySimpleUrlAuthenticationFailureHandler">  
        <beans:property name="defaultFailureUrl" value="/login.html?error=true"/>  
    </beans:bean> 
	
	<!-- 1.URL过滤器或方法拦截器:用来拦截URL或者方法资源对其进行验证,其抽象基类为AbstractSecurityInterceptor 
		2.资源权限获取器:用来取得访问某个URL或者方法所需要的权限,接口为SecurityMetadataSource 3.访问决策器:用来决定用户是否拥有访问权限的关键类,其接口为AccessDecisionManager 
		调用顺序为:AbstractSecurityInterceptor调用SecurityMetadataSource取得资源的所有可访问权限, 然后再调用AccessDecisionManager来实现决策,确定用户是否有权限访问该资源。 -->
	<!-- 自定义的filter, 必须包含authenticationManager, accessDecisionManager, securityMetadataSource三个属性   qingbaosouji-->
	<beans:bean id="mySecurityFilter" class="com.xa3ti.qingbaosouji.base.security.XaFilterSecurityInterceptor">
		<beans:property name="authenticationManager" ref="myAuthenticationManager" />
		<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
		<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
	</beans:bean>

	<!-- 取HTTP配置中的authenticationManager 设置alias别名 -->
	<authentication-manager alias="myAuthenticationManager">
		<authentication-provider user-service-ref="userDetailsManager">
            <password-encoder hash="md5"/>
		</authentication-provider>
	</authentication-manager>


	<!-- 用户详细信息管理:数据源、用户缓存(通过数据库管理用户、角色、权限、资源) -->
	<beans:bean id="userDetailsManager" class="com.base.security.XaUserDetailsService">
	</beans:bean>


	<!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源。 -->
	<beans:bean id="myAccessDecisionManager"
		class="com.base.security.XaAccessDecisionManagerService" />


	<!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色去访问。 -->
	<beans:bean id="mySecurityMetadataSource" init-method="loadResourceDefine"
		class="com.base.security.XaSecurityMetadataSourceService">
	</beans:bean>

</beans:beans>



这个是大神的配置

<?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-3.0.xsd  
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">


	<global-method-security pre-post-annotations="enabled" />
	<!-- HTTP安全配置 -->
	<http auto-config="false" entry-point-ref="authenticationEntryPoint">
		<intercept-url pattern="/login.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/index.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/m/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/commons/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
		<intercept-url pattern="/upload/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/cms/**" access="ROLE_USER"/>
        <intercept-url pattern="/adminIndex.html" access="ROLE_USER"/>
        <intercept-url pattern="/backstage/*.html" access="ROLE_USER"/>
		<!-- <form-login login-page="/login.html" 
		    default-target-url="/adminIndex.html" authentication-failure-url="/login.html?error=true" /> -->
        <logout logout-success-url="/login.html" logout-url="/j_spring_security_logout"/>
		<custom-filter ref="mySecurityFilter" before="FILTER_SECURITY_INTERCEPTOR" />
		<!-- //需要替换的Filter顺序,配置自定义custom-filter时必须蔣auto-config="false",不然会报已经存在同样的过滤器错误   -->
        <custom-filter ref="myLoginFilter" position="FORM_LOGIN_FILTER" /> 
	</http>
	
	<beans:bean id="myLoginFilter" class="com.xa3ti.qingbaosouji.base.filter.MyUsernamePasswordAuthenticationFilter">  
        <beans:property name="authenticationManager" ref="myAuthenticationManager"/>  
        <beans:property name="authenticationFailureHandler" ref="failureHandler"/>  
        <beans:property name="authenticationSuccessHandler" ref="successHandler"/>
    </beans:bean>
    
	<beans:bean id="authenticationEntryPoint"  
        class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
        <beans:property name="loginFormUrl" value="/login.html" />  
    </beans:bean>
    
	<!-- //成功登录后   -->
    <beans:bean id="successHandler" class="com.xa3ti.qingbaosouji.base.filter.MySavedRequestAwareAuthenticationSuccessHandler">  
        <beans:property name="defaultTargetUrl" value="/adminIndex.html"/>  
    </beans:bean>  
    <!-- //登录失败   -->
    <beans:bean id="failureHandler" class="com.xa3ti.qingbaosouji.base.filter.MySimpleUrlAuthenticationFailureHandler">  
        <beans:property name="defaultFailureUrl" value="/login.html?error=true"/>  
    </beans:bean> 
	
	<!-- 1.URL过滤器或方法拦截器:用来拦截URL或者方法资源对其进行验证,其抽象基类为AbstractSecurityInterceptor 
		2.资源权限获取器:用来取得访问某个URL或者方法所需要的权限,接口为SecurityMetadataSource 3.访问决策器:用来决定用户是否拥有访问权限的关键类,其接口为AccessDecisionManager 
		调用顺序为:AbstractSecurityInterceptor调用SecurityMetadataSource取得资源的所有可访问权限, 然后再调用AccessDecisionManager来实现决策,确定用户是否有权限访问该资源。 -->
	<!-- 自定义的filter, 必须包含authenticationManager, accessDecisionManager, securityMetadataSource三个属性   qingbaosouji-->
	<beans:bean id="mySecurityFilter" class="com.xa3ti.qingbaosouji.base.security.XaFilterSecurityInterceptor">
		<beans:property name="authenticationManager" ref="myAuthenticationManager" />
		<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
		<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
	</beans:bean>

	<!-- 取HTTP配置中的authenticationManager 设置alias别名 -->
	<authentication-manager alias="myAuthenticationManager">
		<authentication-provider user-service-ref="userDetailsManager">
            <password-encoder hash="md5"/>
		</authentication-provider>
	</authentication-manager>


	<!-- 用户详细信息管理:数据源、用户缓存(通过数据库管理用户、角色、权限、资源) -->
	<beans:bean id="userDetailsManager" class="com.xa3ti.qingbaosouji.base.security.XaUserDetailsService">
	</beans:bean>


	<!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源。 -->
	<beans:bean id="myAccessDecisionManager"
		class="com.xa3ti.qingbaosouji.base.security.XaAccessDecisionManagerService" />


	<!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色去访问。 -->
	<beans:bean id="mySecurityMetadataSource" init-method="loadResourceDefine"
		class="com.xa3ti.qingbaosouji.base.security.XaSecurityMetadataSourceService">
	</beans:bean>

</beans:beans>




然后是  <beans:bean id="mySecurityFilter" class=" com.base.security.XaFilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
</beans:bean>

下面是红色文件的内容。 这个基本使用 内容都是一样。大神的注释比较代码。这个文件一般不用修改,直接使用就好。因为大神的内容所以 文件名不一样

package com.nuoke;  
  
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.SecurityMetadataSource;  
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;  
import org.springframework.security.access.intercept.InterceptorStatusToken;  
import org.springframework.security.web.FilterInvocation;  
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
   
/* 
 * 继承AbstractSecurityInterceptor、实现Filter是必须的。 
      首先,登陆后,每次访问资源都会被这个拦截器拦截,会执行doFilter这个方法, 
      这个方法调用了invoke方法,其中fi断点显示是一个url(可能重写了toString方法吧,但是里面还有一些方法的),最重要的是beforeInvocation这个方法, 
      它首先会调用MyInvocationSecurityMetadataSource类的getAttributes方法获取被拦截url所需的权限, 
  then调用MyAccessDecisionManager类decide方法判断用户是否够权限。弄完这一切就会执行下一个拦截器. 
 */  
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor  implements Filter {    
    //配置文件注入  
    private FilterInvocationSecurityMetadataSource securityMetadataSource;  
       
    //登陆后,每次访问资源都通过这个拦截器拦截  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)   
            throws IOException, ServletException {  
        FilterInvocation fi = new FilterInvocation(request, response, chain);   
        invoke(fi);    
    }  
       
    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {    
        return this.securityMetadataSource;    
    }     
       
    @Override  
    public Class<? extends Object> getSecureObjectClass() {  
        return FilterInvocation.class;  
    }     
       
    public void invoke(FilterInvocation fi) throws IOException, ServletException {  
        //fi里面有一个被拦截的url  
        //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限  
        //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够  
        InterceptorStatusToken token = super.beforeInvocation(fi);  
        try {  
            //执行下一个拦截器  
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());     
        } finally {   
            super.afterInvocation(token, null);    
        }    
    }  
      
    public SecurityMetadataSource obtainSecurityMetadataSource() {   
        return this.securityMetadataSource;     
    }  
      
    public void setSecurityMetadataSource(  
            FilterInvocationSecurityMetadataSource newSource)  
    {   
        this.securityMetadataSource = newSource;   
    }  
      
    public void destroy() {    
           
    }  
      
    public void init(FilterConfig arg0) throws ServletException {   
    }  
}  

 <beans:bean id="mySecurityFilter" class=" com.base.security.XaFilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
</beans:bean>
然后是绿色部分的代码。我项目中使用。
首先是  ref 配置
<!-- 取HTTP配置中的authenticationManager 设置alias别名 -->
	<authentication-manager alias="myAuthenticationManager">
		<authentication-provider user-service-ref="userDetailsManager">
            <password-encoder hash="md5"/>
		</authentication-provider>
	</authentication-manager>
<!-- 用户详细信息管理:数据源、用户缓存(通过数据库管理用户、角色、权限、资源) -->
	<beans:bean id="userDetailsManager" class="com.base.security.XaUserDetailsService">
	</beans:bean>
package com.base.security;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.base.constant.XaConstant;
import com.base.entity.XaCmsUser;
import com.base.exception.LoginLockException;
import com.base.repository.XaCmsUserRepository;
import com.base.util.DateProcessUtil;

/**
 * 登录权限验证service
 * @author zj
 *
 */
@Service("MsUserDetailsService")
public class XaUserDetailsService implements UserDetailsService {
    protected static final String ROLE_PREFIX = "ROLE_";
    protected static final GrantedAuthority DEFAULT_USER_ROLE = new SimpleGrantedAuthority(ROLE_PREFIX + "USER");

	@Autowired
	XaCmsUserRepository xaCmsUserRepository;
	

	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		XaUserDetails msUserDetails = new XaUserDetails();
		try {
			XaCmsUser user;
			List<XaCmsUser> userList = xaCmsUserRepository.findByUserName(new String(username.getBytes("ISO-8859-1"),"UTF-8"));
			if(userList.size() > 0 && userList.get(0).getStatus() == XaConstant.UserStatus.status_lock){
				throw new LoginLockException("您输入的账号已被锁定");
			}
			/*if(userList.size() > 0 && userList.get(0).getIsAdmin() != 1){
				throw new LoginAdminException("您的账号不是管理员");
			}*/
			if(userList.size() > 0 && userList.get(0) != null){
				user = userList.get(0);
				user.setLastLoginDate(DateProcessUtil.getToday(DateProcessUtil.YYYYMMDDHHMMSS));
				xaCmsUserRepository.save(user);
				
				msUserDetails.setUsername(user.getUserName());
				msUserDetails.setPassword(user.getPassword());
				List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
				GrantedAuthority authority = new SimpleGrantedAuthority(user.getRole().getRoleName());
				authorities.add(authority);
				//设置用户oauth通过token访问的权限
				authorities.add(DEFAULT_USER_ROLE);
				authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + "UNITY"));
				authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + "MOBILE"));
				msUserDetails.setAuthorities(authorities);
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return msUserDetails;
	}
	
	
}
然后是<beans:bean id="mySecurityFilter" class="com.xa3ti.qingbaosouji.base.security.XaFilterSecurityInterceptor">
		<beans:property name="authenticationManager" ref="myAuthenticationManager" />
		<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
		<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
	</beans:bean>
<!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源。 -->
<beans:bean id="myAccessDecisionManager"
class="com.base.security.XaAccessDecisionManagerService" />

package com.base.security;

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.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("MsAccessDecisionManagerService")
@Transactional(readOnly = true)
public class XaAccessDecisionManagerService implements AccessDecisionManager {
	
    
    
  1. //检查用户是否够权限访问资源  
  2. //参数authentication是从spring的全局缓存SecurityContextHolder中拿到的,里面是用户的权限信息  
  3. //参数object是url  
  4. //参数configAttributes所需的权限  
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if (configAttributes == null) { return; } Iterator<ConfigAttribute> iterator = configAttributes.iterator(); while (iterator.hasNext()) { ConfigAttribute configAttribute = iterator.next(); String needPermission = configAttribute.getAttribute(); for (GrantedAuthority ga : authentication.getAuthorities()) { if (needPermission.equals(ga.getAuthority())) { return; } } } throw new AccessDeniedException("没有权限访问"); } public boolean supports(ConfigAttribute attribute) { // TODO Auto-generated method stub return true; } public boolean supports(Class<?> clazz) { // TODO Auto-generated method stub return true; } }

<beans:bean id="mySecurityFilter" class="com.xa3ti.qingbaosouji.base.security.XaFilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
</beans:bean>

<!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色去访问。 -->
	<beans:bean id="mySecurityMetadataSource" init-method="loadResourceDefine"
		class="com.base.security.XaSecurityMetadataSourceService">
	</beans:bean>


package com.base.security;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import com.base.constant.XaConstant;
import com.base.entity.XaCmsRole;
import com.base.repository.XaCmsResourceRepository;
import com.base.repository.XaCmsRoleRepository;
import com.base.util.XaUtil;


@Service("MsSecurityMetadataSourceService")
@Transactional(readOnly = true)
public class XaSecurityMetadataSourceService implements
FilterInvocationSecurityMetadataSource {


@Autowired
XaCmsResourceRepository msCmsResourceRepository;


@Autowired
XaCmsRoleRepository msCmsRoleRepository;


private static Map<String, Collection<ConfigAttribute>> roleMap = null;


public void loadResourceDefine() {


if (roleMap == null) {
roleMap = new LinkedHashMap<String, Collection<ConfigAttribute>>();
}


// Iterator<XaCmsRole> iterator = msCmsRoleRepository.findAll().iterator();
Iterator<XaCmsRole> iterator = msCmsRoleRepository.findAllXaCmsRole(XaConstant.RoleStatus.status_normal).iterator();
while (iterator.hasNext()) {
XaCmsRole mcr = iterator.next();
List<String> urlList = msCmsResourceRepository
.findResourceByRoleId(mcr.getRoleId());
for (String url : urlList) {
if (XaUtil.isNotEmpty(url)) {
if (XaUtil.isNotEmpty(mcr.getRoleName())) {
ConfigAttribute configAttribute = new SecurityConfig(
mcr.getRoleName());
Collection<ConfigAttribute> configAttributes = null;
if (roleMap.containsKey(url)) {
configAttributes = roleMap.get(url);
} else {
configAttributes = new ArrayList<ConfigAttribute>();
}
configAttributes.add(configAttribute);
roleMap.put(url, configAttributes);
}
}
}


}
}


public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
String url = ((FilterInvocation) object).getRequestUrl();
int firstQuestionMarkIndex = url.indexOf("?");
if (firstQuestionMarkIndex != -1) {
url = url.substring(0, firstQuestionMarkIndex);
}
if (roleMap == null) {
loadResourceDefine();
}
return roleMap.get(url);
}


public Collection<ConfigAttribute> getAllConfigAttributes() {
// TODO Auto-generated method stub
return null;
}


public boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
return true;
}

public static void reset(){
roleMap = null;
}


}

同时也帖下大神的的代码

  1. package com.nuoke;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.HashMap;  
  6. import java.util.Iterator;  
  7. import java.util.Map;  
  8.   
  9. import org.springframework.security.access.ConfigAttribute;  
  10. import org.springframework.security.access.SecurityConfig;  
  11. import org.springframework.security.web.FilterInvocation;  
  12. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  13.    
  14. public class MyInvocationSecurityMetadataSource   
  15.     implements FilterInvocationSecurityMetadataSource {   
  16.     private UrlMatcher urlMatcher = new AntUrlPathMatcher();   
  17.     private static Map<String, Collection<ConfigAttribute>> resourceMap = null;  
  18.        
  19.     //tomcat启动时实例化一次  
  20.     public MyInvocationSecurityMetadataSource() {  
  21.         //这个类的实例化只在web服务器启动时调用一次,那就是说loadResourceDefine方法只会调用一次  
  22.         //所以只适合页面的权限不再更改的情况。  
  23.         loadResourceDefine();    
  24.     }  
  25.       
  26.     //tomcat开启时加载一次,加载所有url和权限(或角色)的对应关系  
  27.     private void loadResourceDefine() {  
  28.         resourceMap = new HashMap<String, Collection<ConfigAttribute>>();   
  29.   
  30.         //需要ROLE_USER角色登录后才能访问的页面。  
  31.         Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();   
  32.         ConfigAttribute ca = new SecurityConfig("ROLE_USER");  
  33.         atts.add(ca);   
  34.         resourceMap.put("/index.jsp", atts);  
  35.         resourceMap.put("/admin.jsp", atts);  
  36.           
  37.         //任何用户都没有进入/other.jsp权限  
  38.         Collection<ConfigAttribute> attsno =new ArrayList<ConfigAttribute>();  
  39.         ConfigAttribute cano = new SecurityConfig("ROLE_NO");  
  40.         attsno.add(cano);  
  41.         resourceMap.put("/accessDenied.jsp", attsno);  
  42.           
  43.         //当url有交集时,就有可能漏掉一些角色  
  44.     }    
  45.        
  46.     //参数是要访问的url,返回这个url对于的所有权限(或角色)  
  47.     public Collection<ConfigAttribute> getAttributes(Object object)   
  48.             throws IllegalArgumentException {   
  49.         // 将参数转为url      
  50.         String url = ((FilterInvocation)object).getRequestUrl();     
  51.         Iterator<String> ite = resourceMap.keySet().iterator();   
  52.         while (ite.hasNext()) {           
  53.             String resURL = ite.next();    
  54.             if (urlMatcher.pathMatchesUrl(resURL, url)) {   
  55.                 return resourceMap.get(resURL);  
  56.             }         
  57.         }   
  58.         return null;      
  59.     }    
  60.       
  61.     @Override  
  62.     public boolean supports(Class<?> arg0) {  
  63.         return true;  
  64.     }  
  65.   
  66.     public Collection<ConfigAttribute> getAllConfigAttributes() {  
  67.         return null;    
  68.     }  
  69. }  
// 下面的内容是 自定义登录,这部分是我写的.当时的目的是 为了在登录的时候记录 登录日志。
<!-- 紫色的部分,看字面意思:就是入口。就是登录的入口 -->

<http auto-config="false" entry-point-ref="authenticationEntryPoint">
<intercept-url pattern="/login.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/index.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/m/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/commons/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/upload/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/cms/**" access="ROLE_USER"/>
        <intercept-url pattern="/adminIndex.html" access="ROLE_USER"/>
        <intercept-url pattern="/backstage/*.html" access="ROLE_USER"/>
<!-- <form-login login-page="/login.html" 
   default-target-url="/adminIndex.html" authentication-failure-url="/login.html?error=true" /> -->
        <logout logout-success-url="/login.html" logout-url="/j_spring_security_logout"/>
<custom-filter ref="mySecurityFilter" before="FILTER_SECURITY_INTERCEPTOR" />
<!-- //需要替换的Filter顺序,配置自定义custom-filter时必须蔣auto-config="false",不然会报已经存在同样的过滤器错误   -->
        <custom-filter ref="myLoginFilter" position="FORM_LOGIN_FILTER" /> 
</http>

<beans:bean id="myLoginFilter" class="com.xa3ti.qingbaosouji.base.filter.MyUsernamePasswordAuthenticationFilter">  
        <beans:property name="authenticationManager" ref="myAuthenticationManager"/>  <!-- 登录认证 上面的部分讲到了-->
        <beans:property name="authenticationFailureHandler" ref="failureHandler"/>  <!-- 登录失败 -->
        <beans:property name="authenticationSuccessHandler" ref="successHandler"/> <!-- 登录成功 -->
    </beans:bean>

<beans:bean id="authenticationEntryPoint"  
        class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
        <beans:property name="loginFormUrl" value="/login.html" />  
    </beans:bean>
    
<!-- //成功登录后   -->
    <beans:bean id="successHandler" class="com.xa3ti.qingbaosouji.base.filter.MySavedRequestAwareAuthenticationSuccessHandler">  
        <beans:property name="defaultTargetUrl" value="/adminIndex.html"/>  
    </beans:bean>  
    <!-- //登录失败   -->
    <beans:bean id="failureHandler" class="com.xa3ti.qingbaosouji.base.filter.MySimpleUrlAuthenticationFailureHandler">  
        <beans:property name="defaultFailureUrl" value="/login.html?error=true"/>  
    </beans:bean>




package com.base.filter;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.base.entity.XaCmsUser;
import com.business.entity.RoleLogger;
import com.business.service.RoleLoggerService;

public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{  
    
	@Autowired
	private RoleLoggerService roleLoggerService;
 
       /* (non-Javadoc)
	 * @see org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)
	 */
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		// TODO Auto-generated method stub
		//记录登录日志
		saveLoginInfo(request,authentication);
		super.onAuthenticationSuccess(request, response, authentication);
	}
	
	@Transactional(readOnly=false)  
    public void saveLoginInfo(HttpServletRequest request,Authentication authentication){
        //XaCmsUser user = (XaCmsUser)authentication.getPrincipal(); 
        Object ob = authentication.getPrincipal();  
        try { 
            //String ip = this.getIpAddress(request);
        	RoleLogger rl = new RoleLogger();
        	rl.setRoleId(SecurityContextHolder.getContext().getAuthentication().getName());
            rl.setHandleType("登录");  
            roleLoggerService.createRoleLogger(null, rl);
        } catch (Exception e) {  
            if(logger.isWarnEnabled()){  
                logger.info("无法更新用户登录信息至数据库");  
            }  
        }  
    }
	
	public String getIpAddress(HttpServletRequest request){    
        String ip = request.getHeader("x-forwarded-for");    
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {    
            ip = request.getHeader("Proxy-Client-IP");    
        }    
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {    
            ip = request.getHeader("WL-Proxy-Client-IP");    
        }    
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {    
            ip = request.getHeader("HTTP_CLIENT_IP");    
        }    
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {    
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");    
        }    
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {    
            ip = request.getRemoteAddr();    
        }    
        return ip;    
    } 
	
	private RequestCache requestCache = new HttpSessionRequestCache();  
 
      
}  










package com.base.filter;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

public class MySimpleUrlAuthenticationFailureHandler implements AuthenticationFailureHandler{  
  
    private String defaultFailureUrl;  
    private boolean forwardToDestination = false;  
    private boolean allowSessionCreation = true;  
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();  
   /* @Value(value = "${local.service.url}")  
    private String LOCAL_SERVER_URL;  */
      
    public MySimpleUrlAuthenticationFailureHandler() {  
    }  
  
    public MySimpleUrlAuthenticationFailureHandler(String defaultFailureUrl) {  
        setDefaultFailureUrl(defaultFailureUrl);  
    }  
  
    /** 
     * Performs the redirect or forward to the {@code defaultFailureUrl} if set, otherwise returns a 401 error code. 
     * <p> 
     * If redirecting or forwarding, {@code saveException} will be called to cache the exception for use in 
     * the target view. 
     */  
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,  
            AuthenticationException exception) throws IOException, ServletException {  
        //认证失败区别前后台:LOGIN URL  
        if(request.getParameter("spring-security-redirect") != null){  
              request.getSession().setAttribute("callUrlFailure", request.getParameter("spring-security-redirect"));  
        }  
        //若有loginUrl 则重定向到后台登录界面  
        if(request.getParameter("loginUrl") != null && !"".equals(request.getParameter("loginUrl"))){  
            //defaultFailureUrl = LOCAL_SERVER_URL+"/backlogin.html?validated=false";
            defaultFailureUrl = "/login.html?error=true";  
        }  
        //defaultFailureUrl 默认的认证失败回调URL
        if (defaultFailureUrl == null) {  
            //logger.debug("No failure URL set, sending 401 Unauthorized error");  
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + exception.getMessage());  
        } else {  
            saveException(request, exception);  
            if (forwardToDestination) {  
                //logger.debug("Forwarding to " + defaultFailureUrl);  
                request.getRequestDispatcher(defaultFailureUrl).forward(request, response);  
            } else {  
                //logger.debug("Redirecting to " + defaultFailureUrl);  
                redirectStrategy.sendRedirect(request, response, defaultFailureUrl);  
            }  
        }  
    }  
  
    /** 
     * Caches the {@code AuthenticationException} for use in view rendering. 
     * <p> 
     * If {@code forwardToDestination} is set to true, request scope will be used, otherwise it will attempt to store 
     * the exception in the session. If there is no session and {@code allowSessionCreation} is {@code true} a session 
     * will be created. Otherwise the exception will not be stored. 
     */  
    protected final void saveException(HttpServletRequest request, AuthenticationException exception) {  
        if (forwardToDestination) {  
            request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);  
        } else {  
            HttpSession session = request.getSession(false);  
  
            if (session != null || allowSessionCreation) {  
                request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);  
            }  
        }  
    }  
  
    /** 
     * The URL which will be used as the failure destination. 
     * 
     * @param defaultFailureUrl the failure URL, for example "/loginFailed.jsp". 
     */  
    public void setDefaultFailureUrl(String defaultFailureUrl) {  
        this.defaultFailureUrl = defaultFailureUrl;  
    }  
  
    protected boolean isUseForward() {  
        return forwardToDestination;  
    }  
  
    /** 
     * If set to <tt>true</tt>, performs a forward to the failure destination URL instead of a redirect. Defaults to 
     * <tt>false</tt>. 
     */  
    public void setUseForward(boolean forwardToDestination) {  
        this.forwardToDestination = forwardToDestination;  
    }  
  
    /** 
     * Allows overriding of the behaviour when redirecting to a target URL. 
     */  
    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {  
        this.redirectStrategy = redirectStrategy;  
    }  
  
    protected RedirectStrategy getRedirectStrategy() {  
        return redirectStrategy;  
    }  
  
    protected boolean isAllowSessionCreation() {  
        return allowSessionCreation;  
    }  
  
    public void setAllowSessionCreation(boolean allowSessionCreation) {  
        this.allowSessionCreation = allowSessionCreation;  
    }  
  
}



 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值