java—如何在spring应用程序中同时使用GlobalMethodSecurity配置和WebSecurity配置适配器

j1dl9f46  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(327)

我有一些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 允许每个人都可以访问某些资源
所以我按照这个例子做了 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 controller中添加了端点:

@PreAuthorize("permitAll()")

不幸的是,没有用户,我无法访问此端点。
我是否使用了全局方法安全配置和Web安全配置适配器错误?
这是实现我在开头提到的目标的正确方法吗(有些端点受保护,有些没有)?

iezvtpos

iezvtpos1#

你必须明白 Method Security 以及 Http Security . Method security 是如何在内部保护方法不被调用。这通常用于客户端应用程序、桌面应用程序等。在这里,您可以在特定的 method 保护它不被内部调用。 HttpSecurity 是一个处理如何保护httpapi端点的实现。这通常是通过springboot中预先实现的过滤器来完成的,这是您应该看到的,而不是 method security .
您当前已实现 method security 并尝试使用它来保护http端点。
我建议您从官方文档中的springsecurity helloworld java配置部分开始学习如何实现 HttpSecurity 在Spring Boot里。或者这里是另一个教程。
这是一个例子

@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 并将所有其他端点设置为需要身份验证。

相关问题