日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php框架 > 框架設(shè)計 > Spring Security教程(五)

Spring Security教程(五)

來源:程序員人生   發(fā)布時間:2017-02-14 08:45:50 閱讀次數(shù):4984次

在之前的幾篇security教程中,資源和所對應(yīng)的權(quán)限都是在xml中進(jìn)行配置的,也就在http標(biāo)簽中配置intercept-url,試想要是配置的對象不多,那還好,但是平常實(shí)際開發(fā)中都常常是非常多的資源和權(quán)限對應(yīng),而且寫在配置文件里面寫改起來還得該源碼配置文件,這明顯是不好的。因此接下來,將用數(shù)據(jù)庫管理資源和權(quán)限的對應(yīng)關(guān)系。數(shù)據(jù)庫還是接著之前的,用mysql數(shù)據(jù)庫,因此也不用另外引入額外的jar包。

1 數(shù)據(jù)庫表的設(shè)計

數(shù)據(jù)庫要提供給security的數(shù)據(jù)不過就是,資源(說的通俗點(diǎn)就是范圍資源地址)和對應(yīng)的權(quán)限,這里就有兩張表,但是由于他們倆是多對多的關(guān)系,因此還要設(shè)計1張讓這兩張表關(guān)聯(lián)起來的表,除此以外,還有1張用戶表,有由于用戶和角色也是多對多的關(guān)系,還要額外加1張用戶和角色關(guān)聯(lián)的表。這樣總共下來就是5張表。下面就是對應(yīng)的模型圖:

建表和添加數(shù)據(jù)的sql語句:
DROP TABLE IF EXISTS `resc`;
CREATE TABLE `resc` (
  `id` bigint(20) NOT NULL DEFAULT '0',
  `name` varchar(50) DEFAULT NULL,
  `res_type` varchar(50) DEFAULT NULL,
  `res_string` varchar(200) DEFAULT NULL,
  `descn` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of resc
-- ----------------------------
INSERT INTO `resc` VALUES ('1', '', 'URL', '/adminPage.jsp', '管理員頁面');
INSERT INTO `resc` VALUES ('2', '', 'URL', '/index.jsp', '');
INSERT INTO `resc` VALUES ('3', null, 'URL', '/test.jsp', '測試頁面');

-- ----------------------------
-- Table structure for resc_role
-- ----------------------------
DROP TABLE IF EXISTS `resc_role`;
CREATE TABLE `resc_role` (
  `resc_id` bigint(20) NOT NULL DEFAULT '0',
  `role_id` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`resc_id`,`role_id`),
  KEY `fk_resc_role_role` (`role_id`),
  CONSTRAINT `fk_resc_role_role` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
  CONSTRAINT `fk_resc_role_resc` FOREIGN KEY (`resc_id`) REFERENCES `resc` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of resc_role
-- ----------------------------
INSERT INTO `resc_role` VALUES ('1', '1');
INSERT INTO `resc_role` VALUES ('2', '1');
INSERT INTO `resc_role` VALUES ('2', '2');
INSERT INTO `resc_role` VALUES ('3', '3');

-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` bigint(20) NOT NULL DEFAULT '0',
  `name` varchar(50) DEFAULT NULL,
  `descn` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', 'ROLE_ADMIN', '管理員角色');
INSERT INTO `role` VALUES ('2', 'ROLE_USER', '用戶角色');
INSERT INTO `role` VALUES ('3', 'ROLE_TEST', '測試角色');

-- ----------------------------
-- Table structure for t_c3p0
-- ----------------------------
DROP TABLE IF EXISTS `t_c3p0`;
CREATE TABLE `t_c3p0` (
  `a` char(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_c3p0
-- ----------------------------

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL DEFAULT '0',
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `status` int(11) DEFAULT NULL,
  `descn` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', 'admin', '1', '管理員');
INSERT INTO `user` VALUES ('2', 'user', 'user', '1', '用戶');
INSERT INTO `user` VALUES ('3', 'test', 'test', '1', '測試');

-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `user_id` bigint(20) NOT NULL DEFAULT '0',
  `role_id` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`user_id`,`role_id`),
  KEY `fk_user_role_role` (`role_id`),
  CONSTRAINT `fk_user_role_role` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
  CONSTRAINT `fk_user_role_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('1', '1');
INSERT INTO `user_role` VALUES ('1', '2');
INSERT INTO `user_role` VALUES ('2', '2');
INSERT INTO `user_role` VALUES ('3', '3');
user表中包括用戶登陸信息,role角色表中包括授權(quán)信息,resc資源表中包括需要保護(hù)的資源。

2 實(shí)現(xiàn)從數(shù)據(jù)庫中讀取資源信息

Spring Security需要的數(shù)據(jù)不過就是pattern和access類似鍵值對的數(shù)據(jù),就像配置文件中寫的那樣:

<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />1
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />

其實(shí)當(dāng)項(xiàng)目啟動時,Spring Security所做的就是在系統(tǒng)初始化時,將以上XML中的信息轉(zhuǎn)換為特定的數(shù)據(jù)格式,而框架中其他組件可以利用這些特定格式的數(shù)據(jù),用于控制以后的驗(yàn)證操作。現(xiàn)在我們將這些信息存儲在數(shù)據(jù)庫中,因此就要想辦法從數(shù)據(jù)庫中查詢這些數(shù)據(jù),所以根據(jù)security數(shù)據(jù)的需要,只需要以下sql語句就能夠:

select re.res_string,r.name from role r,resc re,resc_role rr where 
		r.id=rr.role_id and re.id=rr.resc_id
在數(shù)據(jù)中履行這條語句做測試,得到以下結(jié)果:


這樣的格式正是security所需要的數(shù)據(jù)。

3 構(gòu)建1個數(shù)據(jù)庫的操作的類

雖然上述的數(shù)據(jù)符合security的需要,但是security將這類數(shù)據(jù)類型進(jìn)行了封裝,把它封裝成Map<RequestMatcher, Collection<ConfigAttribute>>這樣的類型,其中RequestMatcher接口就是我們數(shù)據(jù)庫中的res_string,其實(shí)現(xiàn)類為AntPathRequestMatcher,構(gòu)建1個這樣的對象只要在new的時候傳入res_string就能夠了,Collection<ConfigAttribute>這里對象構(gòu)建起來就也是類似的,構(gòu)建1個ConfigAttribute對象只需要在其實(shí)現(xiàn)類SecurityConfig創(chuàng)建的時候傳入角色的名字就能夠。代碼以下:

package com.zmc.demo;

import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;

import javax.sql.DataSource;


import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntPathRequestMatcher;
import org.springframework.security.web.util.RequestMatcher;


/**
 * @classname JdbcRequestMapBulider
 * @author ZMC
 * @time 2017⑴⑴0
 * 查詢資源和角色,并構(gòu)建RequestMap
 */
public class JdbcRequestMapBulider
    extends JdbcDaoSupport{
	//查詢資源和權(quán)限關(guān)系的sql語句
    private String resourceQuery = "";
    
    public String getResourceQuery() {
		return resourceQuery;
	}

    //查詢資源
    public List<Resource> findResources() {
        ResourceMapping resourceMapping = new ResourceMapping(getDataSource(),
                resourceQuery);
        return resourceMapping.execute();
    }
    
    //拼接RequestMap
    public LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> buildRequestMap() {
        LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<>();
        
        List<Resource> resourceList = this.findResources();
        for (Resource resource : resourceList) {
			RequestMatcher requestMatcher = this.getRequestMatcher(resource.getUrl());
			List<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
			list.add(new SecurityConfig(resource.getRole()));
			requestMap.put(requestMatcher, list);
		}
        return requestMap;
    }
    //通過1個字符串地址構(gòu)建1個AntPathRequestMatcher對象
    protected RequestMatcher getRequestMatcher(String url) {
        return new AntPathRequestMatcher(url);
    }

    public void setResourceQuery(String resourceQuery) {
        this.resourceQuery = resourceQuery;
    }
    
    /**
     * @classname Resource
     * @author ZMC
     * @time 2017⑴⑴0
     * 資源內(nèi)部類
     */
    private class Resource {
        private String url;//資源訪問的地址
        private String role;//所需要的權(quán)限

        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();
        }
        //對結(jié)果集進(jìn)行封裝處理
        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;
        }
    }
   
	
}

說明:

resourceQuery是查詢數(shù)據(jù)的sql語句,該屬性在配置bean的時候傳入便可。

內(nèi)部創(chuàng)建了1個resource來封裝數(shù)據(jù)。

getRequestMatcher方法就是用來創(chuàng)建RequestMatcher對象的

buildRequestMap方法用來最后拼接成LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>共security使用。

4 替換原有功能的切入點(diǎn)

在將這部之前,先得了解大概下security的運(yùn)行進(jìn)程,security實(shí)現(xiàn)控制的功能其實(shí)就是通過1系列的攔截器來實(shí)現(xiàn)的,當(dāng)用戶登陸的時候,會被AuthenticationProcessingFilter攔截,調(diào)用AuthenticationManager的實(shí)現(xiàn)類,同時AuthenticationManager會調(diào)用ProviderManager來獲得用戶驗(yàn)證信息,其中不同的Provider調(diào)用的服務(wù)不同,由于這些信息可以是在數(shù)據(jù)庫上,可以是在LDAP服務(wù)器上,可以是xml配置文件上等,這個例子中就是為數(shù)據(jù)庫;如果驗(yàn)證通過后會將用戶的權(quán)限信息放到spring的全局緩存SecurityContextHolder中,以備后面訪問資源時使用。當(dāng)訪問資源,訪問url時,會通過AbstractSecurityInterceptor攔截器攔截,其中會調(diào)用FilterInvocationSecurityMetadataSource的方法來獲得被攔截url所需的全部權(quán)限,其中FilterInvocationSecurityMetadataSource的經(jīng)常使用的實(shí)現(xiàn)類為DefaultFilterInvocationSecurityMetadataSource,這個類中有個很關(guān)鍵的東西就是requestMap,也就是我們上面所得到的數(shù)據(jù),在調(diào)用授權(quán)管理器AccessDecisionManager,這個授權(quán)管理器會通過spring的全局緩存SecurityContextHolder獲得用戶的權(quán)限信息,還會獲得被攔截的url和被攔截url所需的全部權(quán)限,然后根據(jù)所配的策略,如果權(quán)限足夠,則返回,權(quán)限不夠則報錯并調(diào)用權(quán)限不足頁面。

根據(jù)源碼debug跟蹤得出,其實(shí)資源權(quán)限關(guān)系就放在DefaultFilterInvocationSecurityMetadataSource的requestMap,中的,這個requestMap就是我們JdbcRequestMapBulider.buildRequestMap()方法所需要的數(shù)據(jù)類型,因此,順氣自然就想到了我們自定義1個類繼承FilterInvocationSecurityMetadataSource接口,將數(shù)據(jù)查出的數(shù)據(jù)放到requestMap中去。制定類MyFilterInvocationSecurityMetadataSource繼承FilterInvocationSecurityMetadataSource和InitializingBean接口。

package com.zmc.demo;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.RequestMatcher;


/**
 * @classname MyFilterInvocationSecurityMetadataSource
 * @author ZMC
 * @time 2017⑴⑴0
 */
public class MyFilterInvocationSecurityMetadataSource implements
		FilterInvocationSecurityMetadataSource, InitializingBean {

	private final static List<ConfigAttribute> NULL_CONFIG_ATTRIBUTE = null;
	// 資源權(quán)限集合
	private Map<RequestMatcher, Collection<ConfigAttribute>> requestMap;
	
	//查找數(shù)據(jù)庫權(quán)限和資源關(guān)系
	private JdbcRequestMapBulider builder;
	
	/*
	 * (non-Javadoc)
	 * @see
	 * org.springframework.security.access.SecurityMetadataSource#getAttributes
	 * (java.lang.Object)
	 * 更具訪問資源的地址查找所需要的權(quán)限
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		final HttpServletRequest request = ((FilterInvocation) object)
				.getRequest();

		Collection<ConfigAttribute> attrs = NULL_CONFIG_ATTRIBUTE;
		for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
				.entrySet()) {
			if (entry.getKey().matches(request)) {
				attrs = entry.getValue();
				break;
			}
		}
		return attrs;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.access.SecurityMetadataSource#
	 * getAllConfigAttributes()
	 * 獲得所有的權(quán)限
	 */
	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
		for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
				.entrySet()) {
			allAttributes.addAll(entry.getValue());
		}
		System.out.println("總共有這些權(quán)限:"+allAttributes.toString());
		return allAttributes;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.security.access.SecurityMetadataSource#supports(java
	 * .lang.Class)
	 */
	@Override
	public boolean supports(Class<?> clazz) {
		return FilterInvocation.class.isAssignableFrom(clazz);
	}
	//綁定requestMap
	protected Map<RequestMatcher, Collection<ConfigAttribute>> bindRequestMap() {
		
		return builder.buildRequestMap();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		this.requestMap = this.bindRequestMap();
	}

	public void refreshResuorceMap() {
		this.requestMap = this.bindRequestMap();
	}

	//get方法
	public JdbcRequestMapBulider getBuilder() {
		return builder;
	}
	
	//set方法
	public void setBuilder(JdbcRequestMapBulider builder) {
		this.builder = builder;
	}

}
說明:

requestMap這個屬性就是用來寄存資源權(quán)限的集合

builder為JdbcRequestMapBulider類型,用來查找數(shù)據(jù)庫權(quán)限和資源關(guān)系

其他的代碼中都有詳細(xì)的注釋

4 配置

<?xml version="1.0" encoding="UTF⑻"?>
<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⑶.0.xsd
    					http://www.springframework.org/schema/context
    					http://www.springframework.org/schema/context/spring-context⑶.1.xsd
                		http://www.springframework.org/schema/tx
                		http://www.springframework.org/schema/tx/spring-tx⑶.0.xsd
                		http://www.springframework.org/schema/security
                		http://www.springframework.org/schema/security/spring-security.xsd">
	
	<http pattern="/login.jsp" security="none"></http>
	<http auto-config="false">
		<form-login login-page="/login.jsp" default-target-url="/index.jsp"
			authentication-failure-url="/login.jsp?error=true" />
		<logout invalidate-session="true" logout-success-url="/login.jsp"
			logout-url="/j_spring_security_logout" />
		<!-- 通過配置custom-filter來增加過濾器,before="FILTER_SECURITY_INTERCEPTOR"表示在SpringSecurity默許的過濾器之前履行。 -->
		<custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR" />
	</http>
	
	<!-- 數(shù)據(jù)源 -->
	<beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<!-- 此為c3p0在spring中直接配置datasource c3p0是1個開源的JDBC連接池 -->
		<beans:property name="driverClass" value="com.mysql.jdbc.Driver" />
		<beans:property name="jdbcUrl"
			value="jdbc:mysql://localhost:3306/springsecuritydemo?useUnicode=true&characterEncoding=UTF⑻" />
		<beans:property name="user" value="root" />
		<beans:property name="password" value="" />
		<beans:property name="maxPoolSize" value="50"></beans:property>
		<beans:property name="minPoolSize" value="10"></beans:property>
		<beans:property name="initialPoolSize" value="10"></beans:property>
		<beans:property name="maxIdleTime" value="25000"></beans:property>
		<beans:property name="acquireIncrement" value="1"></beans:property>
		<beans:property name="acquireRetryAttempts" value="30"></beans:property>
		<beans:property name="acquireRetryDelay" value="1000"></beans:property>
		<beans:property name="testConnectionOnCheckin" value="true"></beans:property>
		<beans:property name="idleConnectionTestPeriod" value="18000"></beans:property>
		<beans:property name="checkoutTimeout" value="5000"></beans:property>
		<beans:property name="automaticTestTable" value="t_c3p0"></beans:property>
	</beans:bean>
	


	<beans:bean id="builder" class="com.zmc.demo.JdbcRequestMapBulider"> 
		<beans:property name="dataSource" ref="dataSource" /> 
		<beans:property name="resourceQuery"
		value="select re.res_string,r.name from role r,resc re,resc_role rr where 
		r.id=rr.role_id and re.id=rr.resc_id" /> 
	</beans:bean>

	
	<!-- 認(rèn)證過濾器 -->
	<beans:bean id="filterSecurityInterceptor"
		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
		<!-- 用戶具有的權(quán)限 -->
		<beans:property name="accessDecisionManager" ref="accessDecisionManager" />
		<!-- 用戶是不是具有所要求資源的權(quán)限 -->
		<beans:property name="authenticationManager" ref="authenticationManager" />
		<!-- 資源與權(quán)限對應(yīng)關(guān)系 -->
		<beans:property name="securityMetadataSource" ref="securityMetadataSource" />
	</beans:bean>
	
	<!-- 授權(quán)管理器 -->
	<beans:bean class="com.zmc.demo.MyAccessDecisionManager" id="accessDecisionManager">
	</beans:bean>
	<!--認(rèn)證管理-->
	<authentication-manager alias="authenticationManager">
		<authentication-provider>
			<jdbc-user-service data-source-ref="dataSource" id="usersService"
				users-by-username-query="select username,password,status as enabled from user where username = ?"
				authorities-by-username-query="select user.username,role.name from user,role,user_role 
	   	        					where user.id=user_role.user_id and 
	   	        					user_role.role_id=role.id and user.username=?" />
		</authentication-provider>
	</authentication-manager>
	<!--自定義的切入點(diǎn)-->
	<beans:bean id="securityMetadataSource"
		class="com.zmc.demo.MyFilterInvocationSecurityMetadataSource">
	    <beans:property name="builder" ref="builder"></beans:property>
	</beans:bean>
	
	
</beans:beans>

1.http中的custom-filter是特別要注意的,就是通過這個標(biāo)簽來增加過濾器的,其中before="FILTER_SECURITY_INTERCEPTOR"表示在SpringSecurity默許的過濾器之前履行。
2.在配置builder時候,resourceQuery就是要查詢的sql語句,dataSource為數(shù)據(jù)源。其他的如authenticationManager在之前的博客配置中就有詳細(xì)講授。
3.在配置認(rèn)證過濾器的時候,accessDecisionManager,authenticationManager,securityMetadataSource這3個屬性是必填項(xiàng),若缺失會報錯。其中authenticationManager就是authentication-manager標(biāo)簽,securityMetadataSource
是自定義的MyFilterInvocationSecurityMetadataSource,authenticationManager這里還沒有定義,因此再創(chuàng)建1個類叫MyAccessDecisionManager,代碼以下:
package com.zmc.demo;

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;

/**
 * @classname MyAccessDecisionManager
 * @author ZMC
 * @time 2017⑴⑴0
 * 
 */
public class MyAccessDecisionManager implements AccessDecisionManager  {
	
	
	
	/* (non-Javadoc)
	 * @see org.springframework.security.access.AccessDecisionManager#decide(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection)
	 * 該方法決定該權(quán)限是不是有權(quán)限訪問該資源,其實(shí)object就是1個資源的地址,authentication是當(dāng)前用戶的
	 * 對應(yīng)權(quán)限,如果沒登陸就為游客,登陸了就是該用戶對應(yīng)的權(quán)限
	 */
	@Override
	public void decide(Authentication authentication, Object object,
			Collection<ConfigAttribute> configAttributes)
			throws AccessDeniedException, InsufficientAuthenticationException {
		if(configAttributes == null) {  
            return;
        }  
        //所要求的資源具有的權(quán)限(1個資源對多個權(quán)限)  
        Iterator<ConfigAttribute> iterator = configAttributes.iterator();  
        while(iterator.hasNext()) {  
            ConfigAttribute configAttribute = iterator.next();  
            //訪問所要求資源所需要的權(quán)限  
            String needPermission = configAttribute.getAttribute();  
            System.out.println("訪問"+object.toString()+"需要的權(quán)限是:" + needPermission);  
            //用戶所具有的權(quán)限authentication  
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            for(GrantedAuthority ga : authorities) {  
                if(needPermission.equals(ga.getAuthority())) {  
                    return;
                }  
            }
        }
        //沒有權(quán)限  
        throw new AccessDeniedException(" 沒有權(quán)限訪問! ");  
		
	}

	@Override
	public boolean supports(ConfigAttribute attribute) {
		// TODO Auto-generated method stub
		return true;
	}

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

	

}

5 結(jié)果

用戶對應(yīng)的角色,和角色能訪問的資源


admin能訪問的頁面有adminPage.jsp、index.jsp;user能訪問的有index.jsp;test能訪問的有test.jsp。

先測試admin用戶:

user用戶測試:


test用戶測試:

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 黄色免费一级 | 99riav视频 | 日韩专区av | 在线毛片观看 | 国产精品久久久久久久久久东京 | 美日韩一区 | 中文字字幕在线中文乱码免费 | 中文字幕一区二区三区日韩精品 | 欧美福利一区 | 国产在线视频一区 | 国产黄色精品 | 久久久www成人免费无遮挡大片 | 国产一区视频在线 | 黄色av免费观看 | 黄色欧美视频 | 国产精品久久久久毛片软件 | 久久免费少妇高潮久久精品99 | 九九热在线精品视频 | 日韩精品激情 | 午夜一级 | 中文字幕亚洲精品 | 日韩视频一区二区 | 国产精品久久99 | 91免费国产在线 | 亚洲免费av片 | 国产精品自拍系列 | 欧美视频亚洲视频 | 精品久久久久久久久久久久久久久 | 国产日韩欧美一区 | 欧美日韩不卡 | 99久久99久久 | 男女搞网站 | 麻豆精品 | 黄大片| 美日韩免费视频 | 国产精品免费一区二区三区都可以 | 成人日韩视频 | 国产精品视频久久久 | 在线精品国产 | 欧美日韩在线看 | 精品一级毛片 |