4

我希望我的 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
    }
}

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

有人有魔法酱吗?

4

2 回答 2

2

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

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

于 2014-06-22T09:45:12.293 回答
0

来自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; }
}
于 2021-11-19T15:23:38.337 回答