Spring_Security源码分析.doc_第1页
Spring_Security源码分析.doc_第2页
Spring_Security源码分析.doc_第3页
Spring_Security源码分析.doc_第4页
Spring_Security源码分析.doc_第5页
免费预览已结束,剩余69页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Spring Security源码分析:1、 ConfigAttributeDefinition和ConfigAttributeEditorConfigAttributeDefinition的对象中保存有了一组配置属性(ConfigAttributes),配置信息都以集合的方式存储在对象中。作用:信息的载体 源码:import java.util.Iterator;import java.util.List;import org.springframework.util.Assert;public class ConfigAttributeDefinition implements Serializable public static final ConfigAttributeDefinition NO_ATTRIBUTES = new ConfigAttributeDefinition(); private List configAttributes; private ConfigAttributeDefinition() this.configAttributes = Collections.EMPTY_LIST; public ConfigAttributeDefinition(String attribute) this.configAttributes = new ArrayList(1); this.configAttributes.add(new SecurityConfig(attribute); this.configAttributes = Collections.unmodifiableList(this.configAttributes); public ConfigAttributeDefinition(ConfigAttribute attribute) this.configAttributes = new ArrayList(1); this.configAttributes.add(attribute); this.configAttributes = Collections.unmodifiableList(this.configAttributes); public ConfigAttributeDefinition(String attributeTokens) this.configAttributes = new ArrayList(attributeTokens.length); for (int i = 0; i attributeTokens.length; +i) this.configAttributes.add(new SecurityConfig(attributeTokensi.trim(); this.configAttributes = Collections.unmodifiableList(this.configAttributes); public ConfigAttributeDefinition(List configAttributes) Iterator attributes = configAttributes.iterator(); while (attributes.hasNext() Assert.isInstanceOf(ConfigAttribute.class, attributes.next(), List entries must be of type ConfigAttribute); this.configAttributes = Collections.unmodifiableList(new ArrayList(configAttributes); public static ConfigAttributeDefinition createFiltered(Collection unfilteredInput) if (unfilteredInput = null) return null; List configAttributes = new ArrayList(); Iterator i = unfilteredInput.iterator(); while (i.hasNext() Object element = i.next(); if (element instanceof ConfigAttribute) configAttributes.add(element); if (configAttributes.size() = 0) return null; return new ConfigAttributeDefinition(configAttributes); public boolean contains(ConfigAttribute configAttribute) return this.configAttributes.contains(configAttribute); public boolean equals(Object obj) if (!(obj instanceof ConfigAttributeDefinition) return false; ConfigAttributeDefinition test = (ConfigAttributeDefinition)obj; return this.configAttributes.equals(test.configAttributes); public Collection getConfigAttributes() return this.configAttributes; public String toString() return this.configAttributes.toString(); 作用:生成ConfigAttributeDefinition对象ConfigAttributeEditor类的源码package org.springframework.security;import java.beans.PropertyEditorSupport;import org.springframework.util.StringUtils;public class ConfigAttributeEditor extends PropertyEditorSupport public void setAsText(String s) throws IllegalArgumentException if (StringUtils.hasText(s) super.setValue(new ConfigAttributeDefinition(StringUmaDelimitedListToStringArray(s); else super.setValue(null); 从源码我们可以看出ConfigAttributeEditor通过setAsText(String s)的方法创建了一个ConfigAttributeDefinition对象,而ConfigAttributeDefinition对象中有一个List类型的configAttributes属性,configAttributes中保存的是ConfigAttribute类型的SecurityCofig对象,这样信息就保存在了ConfigAttributeDefinition对象中。 从数据中查询的信息,实际上最终是以String方式存放的。2、 DefaultFilterInvocationDefinitionSource、FilterInvocationDefinitonSource和ObjectDefinitionSourceDefaultFilterInvocationDefinitionSource的源码:package ercept.web;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import javax.servlet.http.HttpServletRequest;import mons.logging.Log;import mons.logging.LogFactory;import org.springframework.security.ConfigAttributeDefinition;import org.springframework.security.util.UrlMatcher;public class DefaultFilterInvocationDefinitionSource implements FilterInvocationDefinitionSource private static final Set HTTP_METHODS = new HashSet(Arrays.asList(new String DELETE, GET, HEAD, OPTIONS, POST, PUT, TRACE ); protected final Log logger; private Map requestMap; private Map httpMethodMap; private UrlMatcher urlMatcher; private boolean stripQueryStringFromUrls; DefaultFilterInvocationDefinitionSource(UrlMatcher urlMatcher) this.logger = LogFactory.getLog(super.getClass(); this.requestMap = new LinkedHashMap(); this.httpMethodMap = new HashMap(); this.urlMatcher = urlMatcher; public DefaultFilterInvocationDefinitionSource(UrlMatcher urlMatcher, LinkedHashMap requestMap) this.logger = LogFactory.getLog(super.getClass(); this.requestMap = new LinkedHashMap(); this.httpMethodMap = new HashMap(); this.urlMatcher = urlMatcher; Iterator iterator = requestMap.entrySet().iterator(); while (iterator.hasNext() Map.Entry entry = (Map.Entry)iterator.next(); RequestKey reqKey = (RequestKey)entry.getKey(); addSecureUrl(reqKey.getUrl(), reqKey.getMethod(), (ConfigAttributeDefinition)entry.getValue(); void addSecureUrl(String pattern, ConfigAttributeDefinition attr) addSecureUrl(pattern, null, attr); void addSecureUrl(String pattern, String method, ConfigAttributeDefinition attr) Map mapToUse = getRequestMapForHttpMethod(method); mapToUse.put(this.urlMpile(pattern), attr); if (this.logger.isDebugEnabled() this.logger.debug(Added URL pattern: + pattern + ; attributes: + attr + (method = null) ? : new StringBuffer().append( for HTTP method ).append(method).append().toString(); private Map getRequestMapForHttpMethod(String method) if (method = null) return this.requestMap; if (!(HTTP_METHODS.contains(method) throw new IllegalArgumentException(Unrecognised HTTP method: + method + ); Map methodRequestmap = (Map)this.httpMethodMap.get(method); if (methodRequestmap = null) methodRequestmap = new LinkedHashMap(); this.httpMethodMap.put(method, methodRequestmap); return methodRequestmap; public Collection getConfigAttributeDefinitions() return Collections.unmodifiableCollection(getRequestMap().values(); public ConfigAttributeDefinition getAttributes(Object object) throws IllegalArgumentException if (object = null) | (!(supports(object.getClass() throw new IllegalArgumentException(Object must be a FilterInvocation); String url = (FilterInvocation)object).getRequestUrl(); String method = (FilterInvocation)object).getHttpRequest().getMethod(); return lookupAttributes(url, method); protected ConfigAttributeDefinition lookupAttributes(String url) return lookupAttributes(url, null); public ConfigAttributeDefinition lookupAttributes(String url, String method) if (this.stripQueryStringFromUrls) int firstQuestionMarkIndex = url.indexOf(?); if (firstQuestionMarkIndex != -1) url = url.substring(0, firstQuestionMarkIndex); if (this.urlMatcher.requiresLowerCaseUrl() url = url.toLowerCase(); if (this.logger.isDebugEnabled() this.logger.debug(Converted URL to lowercase, from: + url + ; to: + url + ); ConfigAttributeDefinition attributes = null; Map methodSpecificMap = (Map)this.httpMethodMap.get(method); if (methodSpecificMap != null) attributes = lookupUrlInMap(methodSpecificMap, url); if (attributes = null) attributes = lookupUrlInMap(this.requestMap, url); return attributes; private ConfigAttributeDefinition lookupUrlInMap(Map requestMap, String url) Iterator entries = requestMap.entrySet().iterator(); while (entries.hasNext() Map.Entry entry = (Map.Entry)entries.next(); Object p = entry.getKey(); boolean matched = this.urlMatcher.pathMatchesUrl(p, url); if (this.logger.isDebugEnabled() this.logger.debug(Candidate is: + url + ; pattern is + p + ; matched= + matched); if (matched) return (ConfigAttributeDefinition)entry.getValue(); return null; public boolean supports(Class clazz) return FilterInvocation.class.isAssignableFrom(clazz); public int getMapSize() return this.requestMap.size(); Map getRequestMap() return this.requestMap; protected UrlMatcher getUrlMatcher() return this.urlMatcher; public boolean isConvertUrlToLowercaseBeforeComparison() return this.urlMatcher.requiresLowerCaseUrl(); public void setStripQueryStringFromUrls(boolean stripQueryStringFromUrls) this.stripQueryStringFromUrls = stripQueryStringFromUrls; FilterInvocationDefinitionSource源码:package ercept.web;import ercept.ObjectDefinitionSource;public abstract interface FilterInvocationDefinitionSource implements ObjectDefinitionSourceObjectDefinitionSource源码:package ercept;import java.util.Collection;import org.springframework.security.ConfigAttributeDefinition;public abstract interface ObjectDefinitionSource public abstract ConfigAttributeDefinition getAttributes(Object paramObject) throws IllegalArgumentException; public abstract Collection getConfigAttributeDefinitions(); public abstract boolean supports(Class paramClass);三者的关系:DefaultFilterInvocationDefinitionSource实现了FilterInvocationDefinitionSource接口;而FilterInvocationDefinitionSource实现了ObjectDefinitionSource接口。再看ObjectDefinitionSource接口,我们发现其中有一个抽象的方法,它可以返回ConfigAttributeDefinition对象,也就是存储信息的对象,这样通过实现ObjectDefinitionSource接口,我们就可以获得ConfigAttributeDefinition对象,从而获取信息。FilterInvocationDefinitionSource接口无实际意思。下面我们来重点分析一下DefaultFilterInvocationDefinitionSource首先我们来看一下类中的属性:private static final Set HTTP_METHODS = new HashSet(Arrays.asList(new String DELETE, GET, HEAD, OPTIONS, POST, PUT, TRACE ); protected final Log logger; private Map requestMap; private Map httpMethodMap; private UrlMatcher urlMatcher; private boolean stripQueryStringFromUrls;我们来看一下其中的一个重要的构造方法:public DefaultFilterInvocationDefinitionSource(UrlMatcher urlMatcher, LinkedHashMap requestMap) logger = LogFactory.getLog(getClass(); this.requestMap = new LinkedHashMap(); httpMethodMap = new HashMap(); this.urlMatcher = urlMatcher; java.util.Map.Entry entry; RequestKey reqKey; for(Iterator iterator = requestMap.entrySet().iterator(); iterator.hasNext(); addSecureUrl(reqKey.getUrl(), reqKey.getMethod(), (ConfigAttributeDefinition)entry.getValue() entry = (java.util.Map.Entry)iterator.next(); reqKey = (RequestKey)entry.getKey(); 通过构造方法可以给DefaultFilterInvocationDefinitions传入一个Url匹配器和数据库或配置文件中所对应的信息,比如说这样的一种处理:public Object getObject() throws Exception return new DefaultFilterInvocationDefinitionSource(this.getUrlMatcher(), this.buildRequestMap();protected LinkedHashMap buildRequestMap() throws Exception LinkedHashMap resultMap = new LinkedHashMap();ConfigAttributeEditor configAttributeEditor = new ConfigAttributeEditor();Map resourceMap = this.getResourceMap();for (Map.Entry entry : resourceMap.entrySet() RequestKey key = new RequestKey(entry.getKey(), null);configAttributeEditor.setAsText(entry.getValue();resultMap.put(key, (ConfigAttributeDefinition) configAttributeEditor.getValue();return resultMap;它生存了一个LinkedHashMap,Map中装的是ConfigAttributeDefinition对象,这里的key其实是配置信息中的URL,它把这个URL做了包装,不管怎样只要知道通过DefaultFilterInvocationDefinitionSource的构造函数把Url匹配器和权限之类的信息传给了DefaultFilterInvocationDefinitionSource对象。这里的Url匹配器就是一种匹配原则,我这里例子中用的是AntUrlPathMatcher,可以参考其他资料查看具体的介绍,这里就不说了。接着看:public ConfigAttributeDefinition getAttributes(Object object) throws IllegalArgumentException if(object = null | !supports(object.getClass() throw new IllegalArgumentException(Object must be a FilterInvocation); else String url = (FilterInvocation)object).getRequestUrl(); String method = (FilterInvocation)object).getHttpRequest().getMethod(); return lookupAttributes(url, method); 这个方法就是ObjectDefinitionSource中的方法,DefaultFilterInvocationDefinitionSource中实现了,我们来看这里的两句话:String url = (FilterInvocation)object).getRequestUrl(); String method = (FilterInvocation)object).getHttpRequest().getMethod();从这里可以看出给这个方法传递了一个FilterInvocation对象,这个对象是什么这里先放一下,虽然我们现在不知道这个对象是什么,但是我们可以知道通过这个对象我们可以获取请求的URL以及请求方法。接着来看lookupAttributes(url,method)方法:public ConfigAttributeDefinition lookupAttributes(String url, String method) if(stripQueryStringFromUrls) int firstQuestionMarkIndex = url.indexOf(?); if(firstQuestionMarkIndex != -1) url = url.substring(0, firstQuestionMarkIndex); if(urlMatcher.requiresLowerCaseUrl() url = url.toLowerCase(); if(logger.isDebugEnabled() logger.debug(Converted URL to lowercase, from: + url + ; to: + url + ); ConfigAttributeDefinition attributes = null; Map methodSpecificMap = (Map)httpMethodMap.get(method); if(methodSpecificMap != null) attributes = lookupUrlInMap(methodSpecificMap, url); if(attributes = null) attributes = lookupUrlInMap(requestMap, url); return attributes; 这个方法就是对url和method做了一些处理。这里简单的看一下这个逻辑:if(stripQueryStringFromUrls) int firstQuestionMarkIndex = url.indexOf(?); if(firstQuestionMarkIndex != -1) url = url.substring(0, firstQuestionMarkIndex); 这里有一个stripQueryStringFromUrls的boolean型参数,这个参数关系到怎么对url处理,如果stringQueryStringFromUrls为真的话,那么对于带参数的url,它都会将后面的参数去掉,比如:http:/localhost:8080/myproject/add.jsp?id=1;http:/localhost:8080/myproject/add.jsp?id=2;它都会当成http:/localhost:8080/myproject/add.jsp来看待现在来看一下lookupUrlInMap(requestMap, url);这个方法:private ConfigAttributeDefinition lookupUrlInMap(Map requestMap, String url) for(Iterator entries = requestMap.entrySet().iterator(); entries.hasNext();) java.util.Map.Entry entry = (java.util.Map.Entry)entries.next(); Object p = entry.getKey(); boolean matched = urlMatcher.pathMatchesUrl(p, url); if(logger.isDebugEnabled() logger.debug(Candidate is: + url + ; pattern is + p + ; matched= + matched); if(matched) return (ConfigAttributeDefinition)entry.getValue(); return null; 从这里可以看出,是拿请求URL和KEY进行比较,我们在上面已经讲到了,在我们开发的时候我们是配置了权限信息的,无论怎么配最终都是变成了以Map形式存储,这也是我们可以预料到的。好了对DefaultFilterInvocationDefinitionSource进行总结一下: 其实也就做了一件事,你给它传递一个FilterInvocation的对象,然后它通过getAttributes方法去查找是否有ConfigAttributeDefinition对象,也就是是否有配置信息存在。3、 FilterInvocation 我们看类的属性和构造方法:private FilterChain chain; private ServletRequest request;private ServletResponse response;public FilterInvocation(ServletRequest request, ServletResponse response, FilterChain chain) if(request = null | response = null | chain = null) throw new IllegalArgumentException(Cannot pass null values to constructor); if(!(request instanceof HttpServletRequest) throw new IllegalArgumentException(Can only process HttpServletRequest); if(!(response instanceof HttpServletResponse) throw new IllegalArgumentException(Can only process HttpServletResponse); else this.request = request; this.response = response; this.chain = chain; return; 这个类其实很简单,从名字就可以看出它是Filter的调用类,对Filter进行处理的。4、FilterSecurityInterceptor和AbstractSecurityInterceptorFilterSecurityInterceptor.java/*jadclipse*/ Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.package ercept.web;import java.io.IOException;import javax.servlet.*;import org.springframework.core.Ordered;import ercept.AbstractSecurityInterceptor;import ercept.ObjectDefinitionSource;import org.springframework.security.ui.FilterChainOrder;/ Referenced classes of package ercept.web:/ FilterInvocation, FilterInvocationDefinition

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论