【问题标题】:Wanting a custom ExpressionInterceptURL to dynamically manage access to URLs想要自定义 ExpressionInterceptURL 来动态管理对 URL 的访问
【发布时间】:2018-05-02 05:16:45
【问题描述】:

我们在需要用户访问权限的 URL 上有信息包,布局如下:

  • /InfoPacks/InfoPack1/
  • /InfoPacks/InfoPack2/

用户需要 ROLE_INFOPACK1 才能访问 /InfoPacks/InfoPack1/ 和 ROLE_INFOPACK2 才能访问 /InfoPacks/InfoPack2/ 等。

我们一直在添加包,因此将添加到 WebSecurityConfig() .antMatchers("/InfoPacks/InfoPack1/**/*").hasAuthority("ROLE_INFOPACK1) 并不是一个真正的参与者,因为它意味着每次创建新包时都要修改和重新部署,而安全配置中的配置方法越来越大。

自定义评估器会更好。例如可以调用服务的东西 喜欢:

hasPermission(Authentication auth, String targetURL) {
 // search auth.GrantAuthorities for a match to targetURL
}

我看到了这种与 PreAuthorize 一起使用的自定义权限表达式示例,但似乎不是使用 URL authorizeRequests() 执行此操作的方法。 (至少在版本 4 中)。

非常欢迎任何指点。

【问题讨论】:

    标签: spring-security


    【解决方案1】:

    明白了,感谢http://www.baeldung.com/spring-security-custom-voter。 我的网络安全配置现在看起来像:

            protected void configure(HttpSecurity http) throws Exception {
            http
                    .headers()
    
                    .frameOptions().sameOrigin()
                    .and()
                    .csrf().disable()
                    .exceptionHandling()
                    .and()
                    .authorizeRequests()
                         ....
                    .antMatchers("/Infopacks/**/*").authenticated().accessDecisionManager(accessDecisionManager())
                       ..... etc
    }
    
    
        @SuppressWarnings("unchecked")
        @Bean
        public AccessDecisionManager accessDecisionManager() {
    
            System.out.println("Arrive AccessDecisionManager");
    
            List<AccessDecisionVoter<? extends Object>> decisionVoters 
            = Arrays.asList(
                new WebExpressionVoter(),
                new RoleVoter(),
                new AuthenticatedVoter(),
                new DynamicVoter());
    
            return new UnanimousBased(decisionVoters);
       }
    

    DynamicVoter 的投票方法看起来(在丑陋的第一次测试中 - 我知道它需要工作来堵住漏洞):

        @Override
    public int vote(Authentication a, Object s, Collection clctn) {
        String url = ((FilterInvocation) s).getRequestUrl();
        int vote = ACCESS_ABSTAIN;
        if (url.contains("/Infopack")) {
            vote = ACCESS_DENIED;
            for (GrantedAuthority ga:a.getAuthorities()) {
              if (url.toUpperCase().contains(ga.getAuthority()) ) {
                vote = ACCESS_GRANTED;
                break;
              }
            }
        }
        return vote;
    }
    

    因此,用户授权系统只需添加 infopack 名称作为授予权限,以允许用户访问 infopack 目录。您可以随意添加新的 infopack 目录,而无需更改代码。

    【讨论】:

      猜你喜欢
      • 2014-03-28
      • 2011-02-05
      • 2012-12-06
      • 2013-02-16
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      相关资源
      最近更新 更多