【问题标题】:How to use both GlobalMethodSecurityConfiguration and a WebSecurityConfigurerAdapter in a Spring application如何在 Spring 应用程序中同时使用 GlobalMethodSecurityConfiguration 和 WebSecurityConfigurerAdapter
【发布时间】:2021-03-10 06:32:11
【问题描述】:

我有一些 API,一些资源应该可供所有人使用,其余的则供用户使用。

为了保护资源,我实现了一个扩展 WebSecurityConfigurerAdapter 的类,如下所示:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(final HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
            .anyRequest()
                .authenticated()
            .and()
            .oauth2ResourceServer()
                .authenticationManagerResolver((request) -> http.getSharedObject(AuthenticationManager.class))
            .and().oauth2Login()
            .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and().cors();
    }
}

然后我尝试关注https://www.baeldung.com/spring-deny-access 以让每个人都可以访问一些资源

所以我按照this example做了

GlobalMethodSecurityConfiguration & WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
    prePostEnabled = true,
    securedEnabled = true,
    jsr250Enabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration
{
    @Override
    protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
        return new CustomPermissionAllowedMethodSecurityMetadataSource();
    }

    @Configuration
    public static class WebSecurityConfig extends WebSecurityConfigurerAdapter
    {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .oauth2ResourceServer()
                .authenticationManagerResolver((request) -> http.getSharedObject(AuthenticationManager.class))
                .and().oauth2Login()
                .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .and().cors();
        }
    }
}

以及CustomPermissionAllowedMethodSecurityMetadataSource的实现

public class CustomPermissionAllowedMethodSecurityMetadataSource extends AbstractFallbackMethodSecurityMetadataSource
{

    @Override
    protected Collection<ConfigAttribute> 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
    protected Collection<ConfigAttribute> findAttributes(Class<?> clazz)
    {
        return null;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes()
    {
        return null;
    }
}

最后,我在 rest 控制器中添加了端点:

@PreAuthorize("permitAll()")

很遗憾,没有用户,我无法访问此端点。

我是否使用了 GlobalMethodSecurityConfiguration 和 WebSecurityConfigurerAdapter 错误?

这是实现我在开头提到的正确方法(一些端点受保护,一些没有)?

【问题讨论】:

  • 您确定没有GlobalMethodSecurityConfiguration 的第一个配置让未经身份验证的请求访问您的控制器吗?因为你的配置是:.anyRequest().authenticated()

标签: java spring spring-boot spring-security


【解决方案1】:

您必须了解Method SecurityHttp Security 之间的区别。

Method security 是如何保护内部方法不被调用。这通常用于客户端应用程序、桌面应用程序等。在这里,您可以在特定的method 上放置一个注释,并保护它不被内部调用。

HttpSecurity 是一个处理如何保护 http api 端点的实现。这通常是在 Spring Boot 中使用预先实现的过滤器完成的,这是您应该查看的内容,而不是 method security

您当前已实现 method security 并尝试使用它来保护 http 端点。

我建议你从官方文档中的spring security hello world java configuration部分开始学习如何在spring boot中实现HttpSecurity。或者这里是另一个tutorial

这是一个例子

@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1").password(passwordEncoder().encode("user1Pass"))
          .authorities("ROLE_USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/securityNone").permitAll()
          .anyRequest().authenticated()
          .and()
          .httpBasic();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

此配置允许对/securityNone 的所有请求,并将所有其他端点设置为需要身份验证。

【讨论】:

    猜你喜欢
    • 2014-04-25
    • 2016-01-24
    • 1970-01-01
    • 2018-02-25
    • 2021-09-04
    • 2014-11-24
    • 1970-01-01
    • 2018-03-26
    • 2017-09-19
    相关资源
    最近更新 更多