Отключить безопасность для интеграционных тестов Spring security 6

1
9

Я пытаюсь отключить безопасность для интеграционных тестов, но пока ничего не работает.

Это мой pom.xml:

Я пытаюсь протестировать этот контроллер отдыха:< /p>

С этим тестовым классом:

Я пробовал разные вещи, но ни один из них не сработал:

У меня есть SecurityConfig и TestSecurityConfig

Также попробовал это на @BeforeEach:

А также попробовал @WebMvcTest(PatientRestController.class) вместо @SpringBootTest и @MockBean в необходимых зависимостях, но этот подход заставил бы меня высмеивать результат операции в базе данных , что, по моему мнению, противоречит подходу testcontainers.

Я получаю следующую ошибку:

В моем application.yaml у меня есть это:

< p>И в моем application-test-integration.yaml у меня есть это:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.9</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.kaiho</groupId>
    <artifactId>diagnomanager</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>DiagnoManager</name>
    <description>Software de gestion asistencial domiciliaria y hospitalaria</description>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <mapstruct.version>1.6.0.Beta1</mapstruct.version>
        <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
        <org.projectlombok.version>1.18.30</org.projectlombok.version>

        <!-- JaCoCo Properties -->
        <jacoco.version>0.8.6</jacoco.version>
        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
        <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
        <sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
        <sonar.language>java</sonar.language>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.15.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-testcontainers</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency> <!-- This dependency will help us start our docker-compose file when the application starts up.-->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-docker-compose</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>


        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.6</version>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.11.5</version>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.11.5</version>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.11.5</version>
        </dependency>
    </dependencies>

    <build>
        ...
    </build>

</project>
@RestController
@RequestMapping(value = "/api/v1/patients", produces = APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class PatientRestController {

    private final PatientHandler patientHandler;

    @Operation(summary = "Creates a new patient")
    @PostMapping(consumes = APPLICATION_JSON_VALUE)
    @PreAuthorize("hasAuthority('WRITE_PATIENTS')")
    public ResponseEntity<ApiGenericResponse<PatientResponseDto>> createPatient(@RequestBody @Valid ApiGenericRequest
            <PatientRequestDto> request) {
        PatientRequestDto data = request.getData();
        return new ResponseEntity<>(patientHandler.createPatient(data), HttpStatus.CREATED);
    }
}
@SpringBootTest
@Testcontainers
@AutoConfigureMockMvc(addFilters = false)
@ActiveProfiles("test-integration")
@Import({TestSecurityConfig.class})
@TestPropertySource(locations = "classpath:application-test-integration.yaml")
class PatientRestControllerTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:latest");

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private PatientEntityRepository patientEntityRepository;

    @BeforeEach
    void setUp() {
        patientEntityRepository.deleteAll();
    }

    @AfterEach
    public void clearContext() {
        SecurityContextHolder.clearContext();
    }
    @Test
     void shouldCreatePatientAndReturnCreatedStatus() throws Exception {
        // given
        MetaRequest meta = new MetaRequest();
        PatientRequestDto data = new PatientRequestDto(IdType.CC, "987654321", "XXX",
                "YYY", "ZZZ", "AAA",
                LocalDate.of(1993, 5, 18), Gender.FEMALE, BloodType.Aneg, MaritalStatus.SINGLE,
                "123456789", "[email protected]", "05", "005", Zone.URBAN,
                "Random Address", "57", "asdf",
                "BBB", "CCC", "1234567");
        ApiGenericRequest<PatientRequestDto> request = new ApiGenericRequest<>(meta, data);

        // when
        ResultActions perform = mockMvc.perform(post("/api/v1/patients")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(request))
        );

        // then
        perform.andExpect(status().isCreated());

        assertThat(patientEntityRepository.findAll()).hasSize(1);
    }
}
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthFilter jwtAuthFilter;
    private final AuthenticationProvider authenticationProvider;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(
                                "/actuator/prometheus",
                                "/api/v1/auth/**",
                                "/api/v1/patients/**").permitAll()
                                .requestMatchers("/**").hasRole("ADMIN")
                        .anyRequest().authenticated()

                )
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authenticationProvider(authenticationProvider)
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}
@Configuration
@Profile("test-integration")
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = false)
public class TestSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().permitAll()
                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                );
        return http.build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().anyRequest();
    }

    @Bean
    public MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new DenyAllPermissionEvaluator());
        return expressionHandler;
    }

    private static class DenyAllPermissionEvaluator implements PermissionEvaluator {
        @Override
        public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
            return true;
        }

        @Override
        public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
            return true;
        }
}
@BeforeEach
    void setUp() {
        patientEntityRepository.deleteAll();
        SecurityContext securityContext = Mockito.mock(SecurityContext.class);
        Authentication authentication = Mockito.mock(Authentication.class);

        Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
        Mockito.when(authentication.isAuthenticated()).thenReturn(true);
        SecurityContextHolder.setContext(securityContext);
        System.out.println(SecurityContextHolder.getContext());
    }
jakarta.servlet.ServletException: Request processing failed: org.springframework.security.access.AccessDeniedException: Access Denied


Caused by: org.springframework.security.access.AccessDeniedException: Access Denied
    at org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor.attemptAuthorization(AuthorizationManagerBeforeMethodInterceptor.java:256)
    at org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor.invoke(AuthorizationManagerBeforeMethodInterceptor.java:197)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703)
    at com.kaiho.diagnomanager.infrastructure.patient.input.rest.PatientRestController$$SpringCGLIB$$0.createPatient(<generated>)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at ...
spring:
  application:
    name: diagnomanager

  sql:
    init:
      mode: always

  jpa:
    properties:
      hibernate:
        format_sql: true
    hibernate:
      ddl-auto: create-drop
    show-sql: true

logging:
  level:
    org:
      hibernate:
        SQL: DEBUG
        type:
          descriptor:
            sql:
              BasicBinder: TRACE

---

spring:
  config:
    activate:
      on-profile: test-integration

  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

logging:
  level:
    org.springframework.security: TRACE
spring:
  jpa:
    hibernate:
      ddl-auto: create
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
logging:
  level:
    org.springframework.security: TRACE
security:
  ignored: /**
Вячеслав
Вопрос задан22 февраля 2024 г.

1 Ответ

Ваш ответ

Загрузить файл.