Spring Boot에서 @WebMvcTest의 Spring Security 설정 클래스를 비활성화합니다.
최근 다음 클래스를 사용하여 스프링 부츠 프로젝트에 스프링 보안을 추가했습니다.
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig {
}
그 결과 디폴트로는 모든 URL이 인증과 자동 생성된 비밀번호로 보호됩니다.
문제는 컨트롤러 유닛 테스트에 사용한@WebMvcTest 클래스의 모든 테스트가 다음과 같습니다.
@RunWith(SpringRunner.class)
@WebMvcTest(SomeController.class)
public class SomeControllerTest {...}
허가 부족으로 인해 모든 곳에서 실패하고 있습니다.
질문: 이전과 같이 계속 성공하도록 @Test 메서드에 인증을 무시하도록 지시할 수 있습니까?
특정 @WebMvcTest 유닛 테스트클래스에서 @EnableWebSecurity 설정 클래스가 선택되지 않도록 하려면 어떻게 해야 합니까?
이미 실시되고 있는 테스트를 계속해, 나중에 개별적으로 인증 기능을 테스트할 수 있도록 하고 싶습니다.
지금까지 보안 설정을 제외하기 위해 테스트클래스에서 네스트된 설정 클래스를 사용하려고 했습니다.
@RunWith(SpringRunner.class)
@WebMvcTest(SomeController.class)
public class SomeControllerTest {
@Configuration
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class})
static class ContextConfiguration { }
....}
효과가 없는 것 같아요.
메모: Spring Boot 1.5.8을 사용하고 있습니다.
Spring Boot 2.2.4(JUnit5)에서는 아래가 동작하여 보안 필터를 바이패스한 것 같습니다.
@ExtendWith(SpringExtension.class)
@WebMvcTest(SomeController.class)
@AutoConfigureMockMvc(addFilters = false)
public class SomeControllerTest {
...
주의: Spring Security 설정의 필터는 비활성화됩니다.보안 기능이 완전히 해제되지는 않을 겁니다.즉, 필터를 로드하지 않고 부트스트랩보안을 계속 유지합니다.
@WebMvcTest annoation에서 secure=false를 설정할 수 있습니다.테스트에서 스프링 보안 MockMvc 자동 구성을 건너뜁니다.
@WebMvcTest(controllers = SomeController.class, secure = false)
public class SomeControllerTest {
작성자의 주의사항:2021년 현재, 이 답변은 몇 년 동안 사용되지 않고 있으며, 고객님께는 효과가 없을 것입니다.
Spring Boot 2.2.6에서는 @WebMvcTest에 org.springframework.boot.autoconfigure를 자동 설정하는 @AutoConfigureWebMvc가 메타 주석을 붙입니다.security.servlet.보안.spring-boot-test-autoconfigure.jar의 spring.factories에서 볼 수 있는 AutoConfiguration
따라서 보안은 제외하면 됩니다.스프링 보안을 비활성화하기 위한 테스트의 자동 설정:
@WebMvcTest(excludeAutoConfiguration = SecurityAutoConfiguration.class)
Spring Boot 2.4에서는 둘 다secure
플래그가 제거되었고 여기 있는 답변 중 실제로 작동하는 것이 없습니다.
결국 모든 보안을 배제하고 커스텀 주석으로 둘러쌌습니다.
import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration;
import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@WebMvcTest(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = WebSecurityConfigurer.class)},
excludeAutoConfiguration = {SecurityAutoConfiguration.class,
SecurityFilterAutoConfiguration.class,
OAuth2ClientAutoConfiguration.class,
OAuth2ResourceServerAutoConfiguration.class})
public @interface UnsecuredWebMvcTest {
@AliasFor(annotation = WebMvcTest.class, attribute = "controllers")
Class<?>[] value() default {};
@AliasFor(annotation = WebMvcTest.class, attribute = "controllers")
Class<?>[] controllers() default {};
}
Spring Security 4+에서는@WithMockUser
매우 편리하도록 주석을 달 수 있습니다.@@PreAuthorize에을 단 모의 및 합니다.한을부부 부부부다다을 달기만 .@WithMockUser
의 기본 은 용용음음음 음음음음 음음음음 음 . . . . . . . . . . . . 。USER
사용자 수 기본 사용자 이름과 역할도 덮어쓸 수 있습니다.
//default
@Test
@WithMockUser
public void getProfile() {
//your test here
}
//with username and roles
@Test
@WithMockUser(username = "john", roles={"ADMIN"})
public void getProfile() {
//your test here
}
메모: 이 주석은 클래스에 사용할 수 있습니다.
@WithMockUser(username = "john", roles={"ADMIN"})
public class UsersAdminSecurityTest {
}
이것은 스프링 부츠 2.3.1을 사용하여 동작했습니다.
@ExtendWith(SpringExtension.class)
@WebMvcTest(SomeController.class)
@AutoConfigureMockMvc(addFilters = false)
public class SomeControllerTest {
}
Spring Boot 1.5 에한에에 。OAuth2 시큐어 컨트롤러 유닛의 테스트를 정상적으로 실행하기 위해서, 다음의 순서를 적용했습니다.스프링 부츠 2.2.6, Gradle 5.x it JUnit 5 、 Spring Boot 2.2.6은 폐지된 .@AutoConfigureMockMvc(secure = false)
★★★★★★★★★★★★★★★★★」@WebMvcTest(controllers = SomeController.class, secure = false)
이는 Microsoft의 Azure Active Directory를 사용하여 보호된(OAuth2) REST API 프로젝트를 위한 것이지만 기본적으로 이 테스트 전략은 모든 OIDC, OAuth2 구성에 적용됩니다.
이 방법에서는 컨트롤러 테스트파일에 @WebMvcTest 주석을 달아 주석을 붙이는데 다음 파라미터가 필요합니다.
@WebMvcTest(
value = YourController.class
// this disables loading up the WebSecurityConfig.java file, otherwise it fails on start up
, useDefaultFilters = false
// this one indicates the specific filter to be used, in this case
// related to the GreetController we want to test
, includeFilters = {
@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
value = YourController.class
)
}
)
여기서 테스트를 정상적으로 실행하는 구성을 보여 줍니다.
build.gradle
plugins {
id 'org.springframework.boot' version '2.2.6.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.grailscoder'
version = '0.0.1-SNAPSHOT'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
ext {
set('azureVersion', "2.2.4")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'com.microsoft.azure:azure-active-directory-spring-boot-starter'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.5.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
}
dependencyManagement {
imports {
mavenBom "com.microsoft.azure:azure-spring-boot-bom:${azureVersion}"
}
}
test {
useJUnitPlatform()
}
GreetController.java
package com.grailscoder.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@RestController
public class GreetController {
@GetMapping("/greets")
@PreAuthorize("hasRole('ROLE_USER')") // This is validating against Active Directory's User role granted to the
// current user.
@ResponseStatus(HttpStatus.OK)
public String getGreetMessage() {
return "Greets from secret controller";
}
}
Web Security Config.java
package com.grailscoder.config;
import com.microsoft.azure.spring.autoconfigure.aad.AADAppRoleStatelessAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@RequiredArgsConstructor
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final AADAppRoleStatelessAuthenticationFilter aadAuthFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
http.authorizeRequests()
.antMatchers("/", "/index.html", "/public").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(aadAuthFilter, UsernamePasswordAuthenticationFilter.class);
}
}
application.properties
azure.activedirectory.client-id=xxxxx-AD-client-id-goes-here
azure.activedirectory.session-stateless=true
Greet Controller Test.java
package com.grailscoder.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(
value = GreetController.class
// this disables loading up the WebSecurityConfig.java file, otherwise it fails on start up
, useDefaultFilters = false
// this one indicates the specific filter to be used, in this case
// related to the GreetController we want to test
, includeFilters = {
@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
value = GreetController.class
)
}
)
class GreetControllerTest {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@BeforeEach
void setUp() {
// add setup stuff here
}
@Test
@WithMockUser
void testGreet() throws Exception {
ResultActions result = mockMvc.perform(get("/greets"))
.andExpect(status().isOk());
System.out.println(result.andReturn().getResponse().getContentAsString());
}
}
완전히 다른 접근방식을 기반으로 한 유사한 테스트 JUnit 4를 실시하기 위해 다음 테스트를 참고용으로 사용할 수 있습니다(단, 아직 시도하지 않았습니다).https://github.com/spring-projects/spring-security/blob/master/samples/boot/oauth2resourceserver/src/test/java/sample/OAuth2ResourceServerControllerTests.java
부트버전 '스프링 부트'의 입니다.2.5.4
, Jwt 보안을 , Jwt로 설정합니다.useDefaultFilters = false
@WebMvcTest
@WebMvcTest(controllers = YourController.class, useDefaultFilters = false)
public class YourControllerTest {
// Test cases
}
@AutoConfigureMockMvc(addFilters = false)
addFilters = false를 추가하는 것만으로 이 문제가 해결되었습니다.
다음 주석과 속성을 사용하여 문제를 해결했습니다.
@WebMvcTest(controllers =
SomeController.class,
excludeAutoConfiguration = {
MySecurityConfig.class,
ManagementWebSecurityAutoConfiguration.class,
SecurityAutoConfiguration.class
}
)
@ContextConfiguration(classes = SomeController.class)
public class SomeControllerTest {
}
2.하고 있기 「 」: 「 」2.6.6 「 」secure=false
★★★★★★★★★★★★★★★★★★★★★★★!
@AutoConfigureMockMvc(secure = false)
동작하지 않는 이유는secure
되지 않습니다.
기능:
@AutoConfigureMockMvc(addFilters = false)
스프링 보안을 완전히 해제하지 않고 필터 체인을 바이패스합니다.
또는
@WebMvcTest(excludeAutoConfiguration = {SecurityAutoConfiguration.class})
(스프링 부트 액튜에이터를 사용하는 경우:
@WebMvcTest(excludeAutoConfiguration = {SecurityAutoConfiguration.class,
ManagementWebSecurityAutoConfiguration.class})
)
언급URL : https://stackoverflow.com/questions/47593537/disable-spring-security-config-class-for-webmvctest-in-spring-boot
'programing' 카테고리의 다른 글
WooCommerce에서 PHP를 사용하여 ID로 제품 삭제 (0) | 2023.03.22 |
---|---|
어레이 맵을 사용하여 조건부로 결과 필터링 (0) | 2023.03.22 |
관계형 데이터베이스에 비해 MongoDB와 같은 스키마가 없는 데이터베이스를 사용하는 장점은 무엇입니까? (0) | 2023.03.22 |
단일 제품 페이지를 비활성화/숨기는 방법 (0) | 2023.03.22 |
AngularJS 수동으로 컨트롤러 및 템플릿 렌더링 (0) | 2023.03.17 |