【问题标题】:How to configure Spring MVC (spring boot) with authorization that is deny by default allow by annotation如何使用默认拒绝的授权配置 Spring MVC (spring boot) 通过注释允许
【发布时间】:2014-08-11 21:45:53
【问题描述】:

我希望我的 Spring-HATEOAS API 应用程序(基于 Spring-Boot 和 Spring-MVC 构建)配置安全性,以便默认情况下拒绝所有端点/控制器方法,并且只能通过方法注释显式授予访问权限。

我已经能够得到它,所以注释控制所有访问,但如果开发人员忘记添加注释,匿名用户可以访问该方法。我希望开发人员必须显式注释(或执行一些其他显式开发操作)该方法以允许匿名访问。

也许我需要编写一个自定义的 AccessDecisionManager,但我认为有理由怀疑默认情况下拒绝行为已被烘焙...我只需要转动正确的旋钮。

我一直在徒劳地尝试用这样的东西来做到这一点:

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http        
        .authorizeRequests()
        .anyRequest()
        .hasRole("NOONEHASIT")
        ;
    }
}

还有一个控制器:

@Controller
public class RootController {

    @RequestMapping("/")
    @PreAuthorize("hasRole('DEFAULT') or isAnonymous()")
    public HttpEntity<RootResource> root(){
        //stuff
    }
}

认为没有人有这个角色,但这只是否认每个人。

有人拿到魔法酱了吗?

【问题讨论】:

    标签: spring-mvc spring-security spring-boot spring-data-rest spring-hateoas


    【解决方案1】:

    如果不明确允许您想要注释的路径,我想不出有什么方法可以做到这一点。因此,您需要另一个具有较低Order 的过滤器链(即另一个WebSecurityConfigurerAdapter),它明确允许访问您需要保护的所有路径。您也许可以自动执行该操作,例如用@PreAuthorize 寻找@RequestMappings,但这会很麻烦,我不确定是否值得。

    注意我认为你不需要在你的包罗万象的过滤器中扮演一个不存在的角色:你可以denyAll()

    【讨论】:

    • 没有办法创建一个默认拒绝的访问决策管理器吗?像我在示例中使用的那样使用 WebSecurityConfigurerAdapter 并不是必需的……这只是我要走的路
    • 哦,我想我现在明白了。 http 安全性根本不考虑注释......检查是在管道后面通过 MethodInvocation 东西完成的。所以你必须允许尝试甚至到达 MethodInvocation 的东西。
    • 是的,简而言之就是这样。 HTTP 安全性是在评估任何方法安全性之前应用的过滤器,因此在该级别拒绝所有都没有意义。
    • 无论如何都要让方法调用默认拒绝控制器方法(似乎不太可能)
    • 您可能可以使用@RequestMapping 方法做一些事情,在没有@PreAuthorize 的情况下使用它们来定义切入点。就像我说的,繁琐。
    【解决方案2】:

    来自https://www.baeldung.com/spring-deny-access的解决方案:

    @Configuration 
    @EnableWebSecurity 
    @EnableGlobalMethodSecurity(prePostEnabled = true) 
    public class DenyMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
        @Override
        protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
            return new CustomPermissionAllowedMethodSecurityMetadataSource();
        }
        ...
    }
    
    public class CustomPermissionAllowedMethodSecurityMetadataSource 
      extends AbstractFallbackMethodSecurityMetadataSource {
        @Override
        protected Collection findAttributes(Class<?> clazz) { return null; }
    
        @Override
        protected Collection findAttributes(Method method, Class<?> targetClass) {
            Annotation[] annotations = AnnotationUtils.getAnnotations(method);
            List attributes = new ArrayList<>();
    
            // if the class is annotated as @Controller we should by default deny access to all methods
            if (AnnotationUtils.findAnnotation(targetClass, Controller.class) != null) {
                attributes.add(DENY_ALL_ATTRIBUTE);
            }
    
            if (annotations != null) {
                for (Annotation a : annotations) {
                    // but not if the method has at least a PreAuthorize or PostAuthorize annotation
                    if (a instanceof PreAuthorize || a instanceof PostAuthorize) {
                        return null;
                    }
                }
            }
            return attributes;
        }
    
        @Override
        public Collection getAllConfigAttributes() { return null; }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-20
      • 1970-01-01
      • 2015-04-28
      • 2020-11-14
      • 1970-01-01
      • 2020-12-12
      • 2016-06-06
      • 1970-01-01
      • 2017-09-15
      相关资源
      最近更新 更多