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; } }