Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Spring Security进行Spring引导测试。如何启动备用安全配置?_Java_Spring_Spring Mvc_Spring Security_Spring Boot - Fatal编程技术网

Java 使用Spring Security进行Spring引导测试。如何启动备用安全配置?

Java 使用Spring Security进行Spring引导测试。如何启动备用安全配置?,java,spring,spring-mvc,spring-security,spring-boot,Java,Spring,Spring Mvc,Spring Security,Spring Boot,我的spring启动应用程序有一个应用程序类。当我运行它(作为一个应用程序)时,它会在一个嵌入式servlet容器(在我的例子中是Tomcat)中启动自己。不知何故(我想是通过应用程序的@annotations),同一个包中的WebSecurityConfigureAdapter(扩展WebSecurityConfigureAdapter)被加载了 WebSecurity配置包含两个重要的配置信息块: @Configuration @Order(SecurityProperties.ACCESS

我的spring启动应用程序有一个应用程序类。当我运行它(作为一个应用程序)时,它会在一个嵌入式servlet容器(在我的例子中是Tomcat)中启动自己。不知何故(我想是通过应用程序的@annotations),同一个包中的WebSecurityConfigureAdapter(扩展WebSecurityConfigureAdapter)被加载了

WebSecurity配置包含两个重要的配置信息块:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(prePostEnabled = true) // enables method-level role-checking
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
      auth
         .ldapAuthentication()
         .userSearchBase("CN=Users,DC=some,DC=domain,DC=com")   
         .userSearchFilter("(sAMAccountName={0})")
         .groupSearchBase("OU=Groups,DC=some,DC=domain,DC=com")                 
         .groupSearchFilter("(member={0})")
         .contextSource()
            .managerDn("cn=ad-bind,cn=users,dc=some,dc=domain,dc=com")
            .managerPassword("APASSWORD!") 
            .url("ldaps://some.domain.com:636");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
         System.out.println("***************** WebSecurityConfig.configure *************************");
         http.csrf().disable();

         http
            .headers()
                .frameOptions()
                    .disable();

         http
                .authorizeRequests()
                    .antMatchers("/resources/images/*", "/me", "/products", "/product/**", "/offerings", "/offering/**", "/client/**")
                            .permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/login").defaultSuccessUrl("/me")
                    .permitAll()
                    .and()
                    .logout()
                    .permitAll();

         http.logout().logoutSuccessUrl("/me");
    }
}
configureGlobal()包含我们内部LDAP系统的配置,它工作正常

configure()指定哪些URL是公共的,哪些仅向登录用户显示,以及在用户登录时向哪些相对URL发送

现在我正在进行集成测试,并编写了一些方法来测试不需要身份验证的控制器。这些测试按预期进行。应用程序类启动,并对其执行测试

但现在我想测试确实需要身份验证的控制器方法。我认为这是通过告诉测试类启动一个替代应用程序类(在我的例子中是TestApplication)和创建虚拟用户的WebSecurity配置来实现的:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class) // fires up with TestApplication.class instead of Application.class
@WebAppConfiguration
public class ProductControllerTests {
    // test methods here, this time with username/password included
}

@Configuration
@EnableAutoConfiguration
public class TestApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(applicationClass, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(applicationClass);
    }

    private static Class<TestApplication> applicationClass = TestApplication.class;

}

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
      auth.inMemoryAuthentication().withUser("testuser").password("userpass").roles("USER");
      auth.inMemoryAuthentication().withUser("testadmin").password("adminpass").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
         System.out.println("***************** WebSecurityConfig.configure *************************");
         http.csrf().disable();

         http
            .headers()
                .frameOptions()
                    .disable();

         http
                .authorizeRequests()
                    .antMatchers("/resources/images/*", "/me", "/products", "/product/**", "/offerings", "/offering/**", "/client/**")
                            .permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/login").defaultSuccessUrl("/me")
                    .permitAll()
                    .and()
                    .logout()
                    .permitAll();

         http.logout().logoutSuccessUrl("/me");
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes=TestApplication.class)//使用TestApplication.class而不是Application.class激发
@WebAppConfiguration
公共类ProductControllerTests{
//这里的测试方法,这次包括用户名/密码
}
@配置
@启用自动配置
公共类测试应用程序扩展了SpringBootServletInitializer{
公共静态void main(字符串[]args){
run(applicationClass,args);
}
@凌驾
受保护的SpringApplicationBuilder配置(SpringApplicationBuilder应用程序){
返回application.sources(applicationClass);
}
私有静态类applicationClass=TestApplication.Class;
}
@配置
@顺序(SecurityProperty.ACCESS\u OVERRIDE\u顺序)
@EnableGlobalMethodSecurity(Prespenabled=true)
公共类WebSecurityConfig扩展了WebSecurityConfigureAdapter{
@自动连线
public void configureGlobal(AuthenticationManagerBuilder auth)引发异常{
auth.inMemoryAuthentication().withUser(“testuser”).password(“userpass”).roles(“USER”);
auth.inMemoryAuthentication().withUser(“testadmin”).password(“adminpass”).roles(“ADMIN”);
}
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
System.out.println(“****************************Web安全配置****************************”);
http.csrf().disable();
http
.headers()
.frameOptions()
.disable();
http
.授权请求()
.antMatchers(“/resources/images/*”、“/me”、“/products”、“/products/**”、“/products/**”、“/products/**”、“/client/**”)
.permitAll()
.anyRequest().authenticated()
.及()
.formLogin()
.loginPage(“/login”).defaultSuccessUrl(“/me”)
.permitAll()
.及()
.logout()
.permitAll();
http.logout().logoutSuccessUrl(“/me”);
}
}

所以我的问题是:当我执行单元测试类时,我相信TestApplication正在启动。但是,它没有选择替代的WebSecurityConfig类及其auth.inMemoryAuthentication()测试用户如何强制我的应用程序在正常运行应用程序时使用一个WebSecurity配置,而在运行单元测试时使用另一个WebSecurity配置?

您可以配置
测试应用程序
以仅包括要测试的bean。换句话说,确保您的
WebSecurityConfig
不是测试配置的一部分。如果阅读,您会注意到它是一个由注释(以及其他注释)组成的复合注释。因此,您的
应用程序
测试应用程序
将从类所在的包执行递归扫描。Spring参考文档中有一章专门介绍


或者,如果您使用的是Spring Security version 4或更高版本,您可能会发现添加的内容非常有趣。

在您的安全配置类中,添加@Profile注释以在单元测试概要中禁用。比如:

@Configuration
@Profile("!" + Constants.SPRING_PROFILE_UNITTEST)
public class WebSecurityConfig { ....}

在test dir中为测试设置另一个安全配置。

是的,我找到了答案,回来写了一个答案,但你也解决了。谢谢你帮我省事。