FilterInvocationMetadataSource
public class FilterInvocationSecurityMetadataSourceImpl implements
FilterInvocationSecurityMetadataSource {
private final Logger logger = LoggerFactory.getLogger(getClass());
// 默认使用AntUrlPathMatcher
private UrlMatcher urlMatcher;
private boolean stripQueryStringFromUrls;
private static final Set<String> HTTP_METHODS = new HashSet<String>(
Arrays.asList("DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT",
"TRACE"));
/**
* Stores request maps keyed by specific HTTP methods. A null key matches
* any method
*/
private Map<String, Map<Object, Collection<ConfigAttribute>>> httpMethodMap = new HashMap<String, Map<Object, Collection<ConfigAttribute>>>();
@Autowired
public FilterInvocationSecurityMetadataSourceImpl(
SecurityMetadataConverter adapter) {
urlMatcher = new AntUrlPathMatcher();
// LinkedHashMap<RequestKey, Collection<ConfigAttribute>> requestMap = adapter.getRequestMap();
// for (Map.Entry<RequestKey, Collection<ConfigAttribute>> entry : requestMap
// .entrySet()) {
// addSecureUrl(entry.getKey().getUrl(), entry.getKey().getMethod(),
// entry.getValue());
// }
Collection<Config> configs = adapter.configs();
for(Config config:configs){
//logger.info("{}",config.getAttributes());
addSecureUrl(config.getPath(),null,config.getAttributes());
}
}
// ~ Methods
// ========================================================================================================
/**
* Adds a URL,attribute-list pair to the request map, first allowing the
* <tt>UrlMatcher</tt> to process the pattern if required, using its
* <tt>compile</tt> method. The returned object will be used as the key to
* the request map and will be passed back to the <tt>UrlMatcher</tt> when
* iterating through the map to find a match for a particular URL.
*/
private void addSecureUrl(String pattern, String method,
Collection<ConfigAttribute> attrs) {
//
Map<Object, Collection<ConfigAttribute>> mapToUse = getRequestMapForHttpMethod(method);
mapToUse.put(urlMatcher.compile(pattern), attrs);
//attrs.toArray(new ConfigAttribute[] {})[0].getAttribute();
if (logger.isDebugEnabled()) {
logger.debug("Added URL pattern: "
+ pattern
+ "; attributes: "
+ attrs
+ (method == null ? "" : " for HTTP method '" + method
+ "'"));
}
}
/**
* Return the HTTP method specific request map, creating it if it doesn't
* already exist.
*
* @param method
* GET, POST etc
* @return map of URL patterns to <tt>ConfigAttribute</tt>s for this method.
*/
private Map<Object, Collection<ConfigAttribute>> getRequestMapForHttpMethod(
String method) {
if (method != null && !HTTP_METHODS.contains(method)) {
throw new IllegalArgumentException("Unrecognised HTTP method: '"
+ method + "'");
}
// 用Http Method当作key,value是一个Http Url
Map<Object, Collection<ConfigAttribute>> methodRequestMap = httpMethodMap
.get(method);
if (methodRequestMap == null) {
methodRequestMap = new LinkedHashMap<Object, Collection<ConfigAttribute>>();
httpMethodMap.put(method, methodRequestMap);
}
return methodRequestMap;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
for (Map.Entry<String, Map<Object, Collection<ConfigAttribute>>> entry : httpMethodMap
.entrySet()) {
for (Collection<ConfigAttribute> attrs : entry.getValue().values()) {
allAttributes.addAll(attrs);
}
}
return allAttributes;
}
public Collection<ConfigAttribute> getAttributes(Object object) {
if ((object == null) || !this.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);
}
/**
* Performs the actual lookup of the relevant <tt>ConfigAttribute</tt>s for
* the given <code>FilterInvocation</code>.
* <p>
* By default, iterates through the stored URL map and calls the
* {@link UrlMatcher#pathMatchesUrl(Object path, String url)} method until a
* match is found.
*
* @param url
* the URI to retrieve configuration attributes for
* @param method
* the HTTP method (GET, POST, DELETE...), or null for any
* method.
*
* @return the <code>ConfigAttribute</code>s that apply to the specified
* <code>FilterInvocation</code> or null if no match is found
*/
public final Collection<ConfigAttribute> lookupAttributes(String url,
String method) {
if (stripQueryStringFromUrls) {
// Strip anything after a question mark symbol, as per SEC-161. See
// also SEC-321
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 + "'");
}
}
// Obtain the map of request patterns to attributes for this method and
// lookup the url.
Collection<ConfigAttribute> attributes = extractMatchingAttributes(url,
httpMethodMap.get(method));
// If no attributes found in method-specific map, use the general one
// stored under the null key
if (attributes == null) {
attributes = extractMatchingAttributes(url, httpMethodMap.get(null));
}
return attributes;
}
private Collection<ConfigAttribute> extractMatchingAttributes(String url,
Map<Object, Collection<ConfigAttribute>> map) {
if (map == null) {
return null;
}
final boolean debug = logger.isDebugEnabled();
for (Map.Entry<Object, Collection<ConfigAttribute>> entry : map
.entrySet()) {
Object p = entry.getKey();
boolean matched = urlMatcher.pathMatchesUrl(entry.getKey(), url);
if (debug) {
logger.debug("Candidate is: '" + url + "'; pattern is " + p
+ "; matched=" + matched);
}
if (matched) {
return entry.getValue();
}
}
return null;
}
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
protected UrlMatcher getUrlMatcher() {
return urlMatcher;
}
public boolean isConvertUrlToLowercaseBeforeComparison() {
return urlMatcher.requiresLowerCaseUrl();
}
public void setStripQueryStringFromUrls(boolean stripQueryStringFromUrls) {
this.stripQueryStringFromUrls = stripQueryStringFromUrls;
}
}
分享到:
相关推荐
Spring技术内幕:深入解析Spring架构与设计原理(第2版) .pdf
Spring技术内幕:深入解析Spring架构与设计原理 计文柯 编著
Spring技术内幕:深入解析Spring架构与设计原理.pdf
《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》是国内一本系统分析Spring源代码的著作,也是Spring领域的问鼎之作,由业界拥有10余年开发经验的专业Java专家亲自执笔,Java开发者社区和Spring开发者...
《spring技术内幕:深入解析spring架构与计原理(第2版)》是国内唯一一本系统分析spring源代码的著作,也是spring领域的问鼎之作,由业界拥有10余年开发经验的资深java专家亲自执笔,java开发者社区和spring开发者...
spring技术内幕第2版深入解析spring架构框架与设计原理计文柯
Spring技术内幕-深入解析Spring架构与设计原理.pdf
一本spring技术内幕的书,一套spring3.0的jar和源码,还有一个读spring的手顺!其实还有全套的springUML图,和Enterprise Architect的软件,只能传60M,原谅我,在另一个连接里了!
2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。...
Spring的任务执行与调度、Spring Web应用的国际化支持、AJAX和Spring结合的访问模式、利用Spring发 送电子邮件、Spring JMS消息应用编程、教学资源全文检索设计、Java应用的报表打印、网络考试系统设 计、Spring应用...
本书是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自执笔!Java开发者社区和Spring开发者社区一致强烈推荐。 国内第一本基于Spring3.0的著作,从源代码的角度对Spring的内核和各个主要功能...
Spring技术内幕:深入解析Spring架构与设计原理(第2版)].计文柯.扫描版.带书签
Spring技术内幕(第2版) - 计文柯、kindle文档、spring原理解析
本书是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自执笔!Java开发者社区和Spring开发者社区一致强烈推荐。 国内第一本基于Spring3.0的著作,从源代码的角度对Spring的内核和各个主要功能...
Spring技术内幕——深入解析Spring架构与设计 (揭秘系列丛书) - 计文柯.mobi
基于Spring + Spring MVC + Mybatis的销售管理系统.zip 1、该资源内项目代码经过严格调试,下载即用确保可以运行! 2、该资源适合计算机相关专业(如计科、人工智能、大数据、数学、电子信息等)正在做课程设计、期末...
[Spring技术内幕:深入解析Spring架构与设计原理(第2版)].计文柯.扫描版
Spring技术内幕—深入解析Spring架构与设计原理(Java社区和Spring社区一致鼎力推荐!) 著 译 者:计文柯
基于 Spring Cloud Alibaba + Vue ; Element 实现的后台管理系统 + 用户小程序.zip 1、该资源内项目代码经过严格调试,下载即用确保可以运行! 2、该资源适合计算机相关专业(如计科、人工智能、大数据、数学、电子...
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,...