`

关于spring security的URL路径验证问题

阅读更多
在前一篇文章中,还是有些地方没讲清楚,但那篇文章已经有点长了,所以还是另外单独讲一下吧。见SecureResourceFilterInvocationDefinitionSource代码:

/**
 * RegexUrlPathMatcher默认不进行小写转换,而AntUrlPathMatcher默认要进行小写转换
 */
    public void afterPropertiesSet() throws Exception {
        
        // default url matcher will be RegexUrlPathMatcher
        this.urlMatcher = new RegexUrlPathMatcher();
        
        if (useAntPath) {  // change the implementation if required
            this.urlMatcher = new AntUrlPathMatcher();
        }
        
        // Only change from the defaults if the attribute has been set
        if ("true".equals(lowercaseComparisons)) {
            if (!this.useAntPath) {
                ((RegexUrlPathMatcher) this.urlMatcher).setRequiresLowerCaseUrl(true);
            }
        } else if ("false".equals(lowercaseComparisons)) {
            if (this.useAntPath) {
            	//是否对URL全部转换成小写格式
                ((AntUrlPathMatcher) this.urlMatcher).setRequiresLowerCaseUrl(false);
            }
        }
        
    }

//这个方法主要会在FilterSecurityInterceptor->AbstractSecurityInterceptor->beforeInvocation中用到
    public ConfigAttributeDefinition getAttributes(Object filter) throws IllegalArgumentException {
        
        FilterInvocation filterInvocation = (FilterInvocation) filter;
        String requestURI = filterInvocation.getRequestUrl();
        Map<String, String> urlAuthorities = this.getUrlAuthorities(filterInvocation);
        
        String grantedAuthorities = null;
        for(Iterator<Map.Entry<String, String>> iter = urlAuthorities.entrySet().iterator(); iter.hasNext();) {
            Map.Entry<String, String> entry = iter.next();
            
            //url表示从资源表取出的值,在这里代表的是相应的URL
            String url = entry.getKey();
            
            //这段代码表示数据库内的需要验证的资源URL与当前请求的URL相匹配时进行验证
            if(urlMatcher.pathMatchesUrl(url, requestURI)) {
            	//grantedAuthorities表示每个资源对应的角色,如果有多个角色,则以','隔开
                grantedAuthorities = entry.getValue();
                break;
            }
        }
        
        if(grantedAuthorities != null) {
            ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
            configAttrEditor.setAsText(grantedAuthorities);
            return (ConfigAttributeDefinition) configAttrEditor.getValue();
        }
        
        //返回null表示不会验证
        return null;
    }


这个方法的主要作用是从数据库的resource表加载出所有的资源URL值,通过它与request请求的URL相比较,而比较器一般采用AntUrlPathMatcher,如果需要更加灵活的方式,可以使用RegexUrlPathMatcher,先介绍一下上面的getAttributes是怎么通过URL进行验证的。从上面的for循环可以看出,首先遍历资源URL的列表,如果发现有与当前request请求URL相匹配的,就进行验证,如果当前用户拥有的角色与此资源URL对应的角色相同,则通过验证,否则禁止访问。见下图:



上面一张简单的图,基本能说明意思,需要说明的是只要发现有与当前请求路径相匹配的,就会进行验证,而且只验证一次,没有通过验证也不会再检查是否匹配第二个资源URL,的当然如果请求的URL与第一个资源URL不匹配,就会继续向下查找,直到找到与请求URL匹配的资源URL为止,如果遍历完以后,还是没有查到,就到弃权处理,至于所有投票者都弃权以后,该怎么处理,前一篇博客有介绍的。由此可知,这个资源的URL路径的顺序就比较重要了。如果遍历出来的第一个资源URL为/**,而普通用户角色对应的资源URL没有它,那么即使普通角色拥有其它的资源URL权限也是不能访问到相应的页面的。但是如果普通用户有/**的权限,而/**是匹配所有路径的,如/admin/index.jsp也是会匹配的,这样就相当于普通用户拥有任何路径的权限,这也是不行的。所以遍历出来的资源URL顺序很重要。

在基于XML的方式授权时就是把/**放在最后面的,如:

<intercept-url pattern="/secure/extreme/**" access="ROLE_SUPERVISOR"/>
        <intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_REMEMBERED" />
        <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />


也就是说,这个路径放的顺序很重要,在数据库里存放URL时也要遵循这样的规则,如上面的XML放在数据库里应该这样:



这里需要多做的一个步骤是,取出来后不要改变取数据库记录的顺序。在SecurityManagerSupport中的代码:

public Map<String, String> loadUrlAuthorities() {
        Map<String, String> urlAuthorities = new LinkedHashMap<String, String>();
        
        @SuppressWarnings("unchecked")
        List<Resource> urlResources = getHibernateTemplate().find("FROM Resource resource WHERE resource.type = ?", "URL");
        for(Resource resource : urlResources) {
            urlAuthorities.put(resource.getValue(), resource.getRoleAuthorities());
        }
        return urlAuthorities;
    }


要保持取出的数据的顺序不改变,需要使用LinkedHashMap,这样SecureResourceFilterInvocationDefinitionSource在验证URL的顺序就与数据库里面存的顺序一致了,表面上看的确有些不灵活,而实际上,在使用中时资源URL是固定的,用户不能改变的,所以这也没什么影响。

关于AntUrlPathMatcher的匹配规则也很简单,文档中有说明:

 * <li>? matches one character</li>
 * <li>* matches zero or more characters</li>
 * <li>** matches zero or more 'directories' in a path</li>

  • 大小: 21.4 KB
  • 大小: 9.7 KB
分享到:
评论

相关推荐

    spring security 参考手册中文版

    Spring Security 参考 1 第一部分前言 15 1.入门 16 2.介绍 17 2.1什么是Spring Security? 17 2.2历史 19 2.3版本编号 20 2.4获得Spring安全 21 2.4.1使用Maven 21 Maven仓库 21 Spring框架 22 2.4.2 Gradle 23 ...

    java开发短信验证源码-account-security-quickstart-spring:使用Java和Spring的TwilioAcc

    如果您在使用示例时遇到任何问题,请打开一个问题,我们会尽力帮助您。 关于 网站的简单 Java、Spring 和 AngularJS 实现,该网站使用 Twilio Authy 通过双因素身份验证保护文件夹中的所有资产。 此外,它还显示了...

    SpringShiro分布式缓存版

    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"&gt; &lt;!-- end --&gt; --修改了过滤链 &lt;!-- 过滤链定义 --&gt; //简单的讲就是把需要特别处理的路径写到前面,越特殊写...

    ResumeBuilder:该Web应用程序允许用户创建可编辑的可共享HTML简历。

    Spring Security连接到db,获取用户信息并对其进行身份验证。 用户的简历配置文件信息也是基于JPA的,并写入数据库。 应用程序在不同的URL之间导航-HomeController提供请求路径和处理程序方法之间的映射。 登录的...

    shiro注解版

    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"&gt; &lt;!-- end --&gt; --修改了过滤链 &lt;!-- 过滤链定义 --&gt; //简单的讲就是把需要特别处理的路径写到前面,越特殊写...

    asp.net知识库

    一完美的关于请求的目录不存在而需要url重写的解决方案! 在C#中实现MSN消息框的功能 XmlHttp实现无刷新三联动ListBox 鼠标放在一个连接上,会显示图片(类似tooltip) 使用microsoft.web.ui.webcontrols的TabStrip与...

    java开源包1

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包11

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包2

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包3

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包6

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包5

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包10

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包4

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包8

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包7

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包9

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    java开源包101

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    Java资源包01

    Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java...

    JAVA上百实例源码以及开源项目源代码

    关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥...

Global site tag (gtag.js) - Google Analytics