当前位置: 首页 > 面试题库 >

Java配置和Spring Security 3.2的安全方法注释

滕无尘
2023-03-14
问题内容

我在使用由@EnableGlobalMethodSecurityServlet 3.0样式初始化控制的方法级别注释来设置我的应用程序时遇到一些问题

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(MultiSecurityConfig.class);
    }
}

我尝试了两种不同的方法来初始化AuthenticationManager各自的问题。请注意,
使用会@EnableGlobalMethodSecurity导致服务器启动成功,并且所有表单安全性都将按预期执行。我在控制器上添加@EnableGlobalMethodSecurity@PreAuthorize("hasRole('ROLE_USER')")注释时出现问题。

我试图独立设置基于表单和基于api的安全性。基于方法的注释仅需要用于api安全性。

以下是一种配置。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class MultiSecurityConfig {

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**").httpBasic();
        }

        protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                .withUser("user").password("password").roles("USER").and()
                .withUser("admin").password("password").roles("USER", "ADMIN");
        }
    }

    @Configuration
    public static class FormWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/static/**","/status");
        }

        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().hasRole("USER").and()
                .formLogin().loginPage("/login").permitAll();
        }

        protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                .withUser("user").password("password").roles("USER").and()
                .withUser("admin").password("password").roles("USER", "ADMIN");
        }
    }

}

这不是理想的,因为我真的只希望对身份验证机制进行一次注册,但是主要问题是它导致以下异常:

java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found []

据我所知@EnableGlobalMethodSecurity,它是自己设置的,AuthenticationManager所以我不确定这是什么问题。

第二种配置如下。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class MultiSecurityConfig {

    @Bean
    protected AuthenticationManager authenticationManager() throws Exception {
        return new AuthenticationManagerBuilder(ObjectPostProcessor.QUIESCENT_POSTPROCESSOR)
                .inMemoryAuthentication()
                    .withUser("user").password("password").roles("USER").and()
                    .withUser("admin").password("password").roles("USER", "ADMIN").and()
                    .and()
                .build();
    }

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Override protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**").httpBasic();
        }
    }

    @Configuration
    public static class FormWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/static/**","/status");
        }

        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().hasRole("USER").and()
                .formLogin().loginPage("/login").permitAll();
        }
    }

}

该配置实际上成功启动,但有一个例外

java.lang.IllegalArgumentException: A parent AuthenticationManager or a list of AuthenticationProviders is required
at org.springframework.security.authentication.ProviderManager.checkState(ProviderManager.java:117)
at org.springframework.security.authentication.ProviderManager.<init>(ProviderManager.java:106)
at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.performBuild(AuthenticationManagerBuilder.java:221)

当我测试时发现安全性不起作用。

我已经研究了几天,甚至在深入研究Spring Security实现代码后,我似乎也找不到我的配置出了什么问题。

我正在使用spring-security-3.2.0.RC1和spring-framework-3.2.3.RELEASE。


问题答案:

当您使用protected registerAuthentication的方法WebSecurityConfigurerAdapter是范围界定身份验证到WebSecurityConfigurerAdapter如此EnableGlobalMethodSecurity无法找到它。如果您考虑一下……这是有道理的,因为该方法受到保护。

您看到的错误实际上是一个调试语句(请注意级别为DEBUG)。原因是Spring Security将尝试几种不同的方法来自动连接Global Method
Security。具体来说,EnableGlobalMethodSecurity将尝试以下方法来尝试获取AuthenticationManager

  • 如果您扩展GlobalMethodSecurityConfiguration并覆盖,registerAuthentication它将使用AuthenticationManagerBuilder传入的。这允许AuthenticationManager您以与WebSecurityConfigurerAdapter
  • 尝试从的全局共享实例进行构建AuthenticationManagerBuilder,如果失败,它将记录您所看到的错误消息(请注意,日志还指出“目前还可以,我们将尝试直接使用AuthenticationManager”)
  • 尝试使用AuthenticationManager暴露为Bean的。

对于您的代码,最好使用以下代码:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class MultiSecurityConfig {
    // Since MultiSecurityConfig does not extend GlobalMethodSecurityConfiguration and
    // define an AuthenticationManager, it will try using the globally defined
    // AuthenticationManagerBuilder to create one

    // The @Enable*Security annotations create a global AuthenticationManagerBuilder 
    // that can optionally be used for creating an AuthenticationManager that is shared
    // The key to using it is to use the @Autowired annotation
    @Autowired
    public void registerSharedAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER").and()
                .withUser("admin").password("password").roles("USER", "ADMIN");
    }

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        // Since we didn't specify an AuthenticationManager for this class,
        // the global instance is used


        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/api/**")
                .httpBasic();
        }
    }

    @Configuration
    public static class FormWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
        // Since we didn't specify an AuthenticationManager for this class,
        // the global instance is used

        public void configure(WebSecurity web) throws Exception {
            web
                .ignoring()
                    .antMatchers("/static/**","/status");
        }

        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .anyRequest().hasRole("USER")
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll();
        }
    }

}

注意:有关此问题的更多文档将在未来几天内添加到参考中。



 类似资料:
  • 从2.0开始Spring Security对服务层的方法的安全有了实质性的改善。他提供对JSR-250的注解安全支持象框架原生的@Secured注解一样好。从3.0开始你也可以使用新的基于表达式的注解。你可以应用安全到单独的bean,使用拦截方法元素去装饰Bean声明,或者你可以在整个服务层使用AspectJ风格的切入点保护多个bean。 EnableGlobalMethodSecurity 我们

  • 从2.0版本开始Spring Security 改进了对服务层方法的安全支持,它提供了对JSR-250注解安全支持以及框架的原生@Secured注解的支持。从3.0开始你也可以使用新的基于表达式的注解。你可以将安全应用到单个bean.使用intercept-methods元素装饰Bean的声明。或者你可以在使用AspectJ风格的切入点应用安全到整个服务层的多个Bean类。 <global-met

  • 第一步是创建我们的Java配置。这个配置在你的应用程序中创建一个springSecurityFilterChain 的Servlet的过滤器,负责所有安全(例如 保护应用程序的URL,验证提交的用户名和密码,重定向到登陆的表单等等)。你可以在下面找到大部分Java配置项的例子: import org.springframework.beans.factory.annotation.Autowire

  • 在创建服务器实例之前,你需要在该实例上添加安全组规则,这样服务器实例的用户才能ping这个主机或者通过SSH连接这个实例。安全组是IP过滤的规则组,它决定了网络的连通性,适用于一个Project内的所有实例。配置安全组有两种方式:要么是在默认的安全组中添加规则,要么新建一个安全组,然后把规则写在新的安全组里。 密钥对是SSH的证书,在实例启动时被注入进系统里。如欲使用密钥对注入,镜像中的系统上必须

  • 一、简介 此配置,可设置后台登陆最大失败次数,以防密码被试出。 其它配置相对简单不在详述。 二、功能演示 如图:

  • 本文向大家介绍详解spring 配置的两种方式:JAVA配置和注解配置,包括了详解spring 配置的两种方式:JAVA配置和注解配置的使用技巧和注意事项,需要的朋友参考一下 众所周知,spring自从3.0开始以后,就全面推荐使用配置的方式进行代码编写了,这种方式确实可以避免了之前一个项目里面一大堆XML的情况,毕竟XML的可读性实在不怎么样,而且一会写JAVA,一会写XML,确实还是蛮麻烦的