Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot with WebFlux always throw 403 status in tests

Great thx for viewing my question) I have some strange subject: my spring boot tests don't work. They start successfully but always throwing 403 HTTP status when making the requests to any controller I have some project with next dependencies:

buildscript {
    ext.kotlin_version = '1.3.71'

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.71"
        classpath "org.springframework.boot:spring-boot-gradle-plugin:2.2.1.RELEASE"
        classpath "com.google.cloud.tools.jib:com.google.cloud.tools.jib.gradle.plugin:1.8.0"
    }
}

plugins {
    id "org.springframework.boot" version "2.2.5.RELEASE"
    id "io.spring.dependency-management" version "1.0.9.RELEASE"
    id "com.google.cloud.tools.jib" version "1.8.0"
    id "org.jetbrains.kotlin.jvm" version "1.3.71"
    id "org.jetbrains.kotlin.plugin.spring" version "1.3.71"
    id "org.jetbrains.kotlin.plugin.jpa" version "1.3.71"
}

apply plugin: 'kotlin'

configurations {
    developmentOnly
    runtimeClasspath {
        extendsFrom developmentOnly
    }
}

repositories {
    maven {
        url "https://plugins.gradle.org/m2/"
    }
    maven {
        url "http://oss.jfrog.org/artifactory/oss-snapshot-local/"
    }
    mavenCentral()
}

kotlin {
    sourceSets {
        main.kotlin.srcDirs += 'src/main/myKotlin'
    }
}

dependencies {
    implementation "joda-time:joda-time:2.10.5"
    implementation "org.springframework.boot:spring-boot-starter-security"
    implementation "org.springframework.boot:spring-boot-starter-actuator"
    implementation "org.springframework.boot:spring-boot-starter-batch"
    implementation "org.springframework.boot:spring-boot-starter-jdbc"
    implementation "org.springframework.boot:spring-boot-starter-data-jpa"
    implementation "org.springframework.boot:spring-boot-starter-data-mongodb-reactive"
    implementation "org.springframework.boot:spring-boot-starter-mail"
    implementation "org.springframework.boot:spring-boot-starter-quartz"
    implementation "org.springframework.boot:spring-boot-starter-webflux"
    implementation "com.fasterxml.jackson.module:jackson-module-kotlin"
    implementation "io.springfox:springfox-swagger2:3.0.0-SNAPSHOT"
    implementation "io.springfox:springfox-swagger-ui:3.0.0-SNAPSHOT"
    implementation "io.springfox:springfox-spring-webflux:3.0.0-SNAPSHOT"
    implementation "org.flywaydb:flyway-core"
    implementation "org.jetbrains.kotlin:kotlin-reflect"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-reactor"
    developmentOnly "org.springframework.boot:spring-boot-devtools"
    runtimeOnly "org.postgresql:postgresql"
    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude group: "org.junit.vintage", module: "junit-vintage-engine"
    }
    testImplementation("de.flapdoodle.embed:de.flapdoodle.embed.mongo")
    testImplementation("io.projectreactor:reactor-test")
    testImplementation("org.springframework.batch:spring-batch-test")
    testImplementation("com.ninja-squad:springmockk:2.0.0")
    testImplementation('com.h2database:h2')
}

test {
    useJUnitPlatform()
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}

I implemented some functionality, and then I began coverage it with tests. But, then I start them, spring always throws exception with 403 response status. Here is the reports:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.5.RELEASE)

2020-03-26 11:24:23.345  INFO 38406 --- [    Test worker] r.m.b.web.signin.SignInControllerTest    : Starting SignInControllerTest on MacBook-Pro-Apple with PID 38406 (started by alexscrobot in /Users/alexscrobot/development/backends/medissima)
2020-03-26 11:24:23.347  INFO 38406 --- [    Test worker] r.m.b.web.signin.SignInControllerTest    : No active profile set, falling back to default profiles: default
2020-03-26 11:24:26.418  INFO 38406 --- [    Test worker] ctiveUserDetailsServiceAutoConfiguration : 

Using generated security password: 499ec504-7b25-484f-87b3-d6b6d2f7cc06

2020-03-26 11:24:26.553 DEBUG 38406 --- [    Test worker] s.w.r.r.m.a.RequestMappingHandlerMapping : 1 mappings in 'requestMappingHandlerMapping'
2020-03-26 11:24:26.671 DEBUG 38406 --- [    Test worker] o.s.w.r.handler.SimpleUrlHandlerMapping  : Patterns [/swagger-ui.html**, /webjars/**] in 'resourceHandlerMapping'
2020-03-26 11:24:26.765 DEBUG 38406 --- [    Test worker] o.s.w.r.r.m.a.ControllerMethodResolver   : ControllerAdvice beans: none
2020-03-26 11:24:27.338 DEBUG 38406 --- [    Test worker] o.s.w.s.adapter.HttpWebHandlerAdapter    : enableLoggingRequestDetails='false': form data and headers will be masked to prevent unsafe logging of potentially sensitive data
2020-03-26 11:24:27.390  INFO 38406 --- [    Test worker] r.m.b.web.signin.SignInControllerTest    : Started SignInControllerTest in 4.384 seconds (JVM running for 6.038)
2020-03-26 11:24:28.628 DEBUG 38406 --- [    Test worker] o.s.w.r.f.client.ExchangeFunctions       : [48fcb68c] HTTP POST /api/sign-in
2020-03-26 11:24:28.759 DEBUG 38406 --- [     parallel-1] o.s.http.codec.json.Jackson2JsonEncoder  : [48fcb68c] Encoding [RequestCredentials([email protected], password=123456)]
2020-03-26 11:24:28.797 DEBUG 38406 --- [     parallel-1] o.s.w.s.adapter.HttpWebHandlerAdapter    : [6997f224] HTTP POST "/api/sign-in"
2020-03-26 11:24:28.911 DEBUG 38406 --- [oundedElastic-1] o.s.w.s.s.DefaultWebSessionManager       : Created new WebSession.
2020-03-26 11:24:28.926 DEBUG 38406 --- [oundedElastic-1] o.s.w.s.adapter.HttpWebHandlerAdapter    : [6997f224] Completed 403 FORBIDDEN
2020-03-26 11:24:28.930 DEBUG 38406 --- [oundedElastic-1] o.s.w.r.f.client.ExchangeFunctions       : [48fcb68c] Response 403 FORBIDDEN

Status expected:<200 OK> but was:<403 FORBIDDEN>

> POST /api/sign-in
> WebTestClient-Request-Id: [1]
> Accept: [application/json]
> Content-Type: [application/json]
> Content-Length: [45]

{"email":"[email protected]","password":"123456"}

< 403 FORBIDDEN Forbidden
< Content-Type: [text/plain]
< Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
< Pragma: [no-cache]
< Expires: [0]
< X-Content-Type-Options: [nosniff]
< X-Frame-Options: [DENY]
< X-XSS-Protection: [1 ; mode=block]
< Referrer-Policy: [no-referrer]

CSRF Token has been associated to this client

java.lang.AssertionError: Status expected:<200 OK> but was:<403 FORBIDDEN>

> POST /api/sign-in
> WebTestClient-Request-Id: [1]
> Accept: [application/json]
> Content-Type: [application/json]
> Content-Length: [45]

{"email":"[email protected]","password":"123456"}

< 403 FORBIDDEN Forbidden
< Content-Type: [text/plain]
< Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
< Pragma: [no-cache]
< Expires: [0]
< X-Content-Type-Options: [nosniff]
< X-Frame-Options: [DENY]
< X-XSS-Protection: [1 ; mode=block]
< Referrer-Policy: [no-referrer]

CSRF Token has been associated to this client

    at org.springframework.test.web.reactive.server.ExchangeResult.assertWithDiagnostics(ExchangeResult.java:209)
    at org.springframework.test.web.reactive.server.StatusAssertions.assertStatusAndReturn(StatusAssertions.java:227)
    at org.springframework.test.web.reactive.server.StatusAssertions.isOk(StatusAssertions.java:67)
    at ru.medissima.backend.web.signin.SignInControllerTest.success authentication(SignInControllerTest.kt:80)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.AssertionError: Status expected:<200 OK> but was:<403 FORBIDDEN>
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
    at org.springframework.test.web.reactive.server.StatusAssertions.lambda$assertStatusAndReturn$4(StatusAssertions.java:227)
    at org.springframework.test.web.reactive.server.ExchangeResult.assertWithDiagnostics(ExchangeResult.java:206)
    ... 91 more

2020-03-26 11:24:28.990 DEBUG 38406 --- [    Test worker] o.s.w.r.f.client.ExchangeFunctions       : [5ee937d3] HTTP POST /api/sign-in
2020-03-26 11:24:28.991 DEBUG 38406 --- [     parallel-2] o.s.w.s.adapter.HttpWebHandlerAdapter    : [5fe66132] HTTP POST "/api/sign-in"
2020-03-26 11:24:28.992 DEBUG 38406 --- [oundedElastic-1] o.s.w.s.s.DefaultWebSessionManager       : Created new WebSession.
2020-03-26 11:24:28.994 DEBUG 38406 --- [oundedElastic-1] o.s.w.s.adapter.HttpWebHandlerAdapter    : [5fe66132] Completed 403 FORBIDDEN
2020-03-26 11:24:28.994 DEBUG 38406 --- [oundedElastic-1] o.s.w.r.f.client.ExchangeFunctions       : [5ee937d3] Response 403 FORBIDDEN
SignInControllerTest > success authentication() FAILED
    java.lang.AssertionError at SignInControllerTest.kt:80
        Caused by: java.lang.AssertionError at SignInControllerTest.kt:80
2 tests completed, 1 failed

Here is the code of test implementation

@RunWith(value = SpringRunner::class)
@WebFluxTest(value = [SignInController::class])
class SignInControllerTest(
    @Autowired val webTestClient: WebTestClient
) {

    @MockkBean
    private lateinit var service: AuthorizationService

    @MockkBean
    private lateinit var validationService: ValidationService

    @MockkBean
    private lateinit var repository: AuthRepository

    @Test
    fun `failed sign in test`() {
        webTestClient
            .post()
            .uri("/api/sign-in")
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .expectStatus().isForbidden
    }

    @Test
    fun `success authentication`() {
        val user = createTestUser()

        val request = RequestCredentials(
            "[email protected]",
            "123456"
        )

        val response = Mono.just(user)

        every { repository.findByEmail("") }.returns(Optional.of(user))
        every { validationService.matchPasswords("", "") }.returns(Unit)
        every { service.authorize("", "") } returns response

        webTestClient
            .post()
            .uri("/api/sign-in")
            .bodyValue(request)
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .expectStatus().isOk
    }
}

I saw, that csrf token required, but i tried to tuned configuration like this:

@Configuration
class SecurityConfiguration {

    @Bean
    fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        return http
            .csrf().disable()
            .authorizeExchange()
            .pathMatchers("/api/**").permitAll()
            .anyExchange().permitAll()
            .and()
            .httpBasic()
            .and()
            .build()
    }
}

It's didn't work. Please, help me to understand why test environment not started correctly.

like image 750
Scrobot Avatar asked Mar 26 '20 04:03

Scrobot


People also ask

How is spring WebFlux non-blocking?

Spring Webflux does not block a thread to handle each request, because no thread is kept waiting for something to be done (e.g. waiting for an answer from a database). As written in 1., it can be blocked while waiting for an answer from a database or from another service that is called via HTTP.

Which class is most useful for testing spring WebFlux endpoints?

Introduction : While working with Spring MVC, you might have used Spring MockMVC to perform testing of Spring web MVC controllers. MockMVC class is part of the Spring MVC test framework which helps in testing the controllers explicitly starting a Servlet container.

What is the benefit of spring WebFlux?

Spring WebFlux makes it possible to build reactive applications on the HTTP layer. It is a reactive fully non-blocking, annotation-based web framework built on Project Reactor that supports reactive streams back pressure and runs on non-blocking servers such as Netty, Undertow and Servlet 3.1+ containers.

How do I use @webfluxtest with @controller?

By default, tests annotated with @WebFluxTest will also auto-configure a WebTestClient. Typically @WebFluxTest is used in combination with @MockBean or @Import to create any collaborators required by the @Controller beans.

How to handle webflux errors at the global level?

We can, however, opt to handle our WebFlux errors at a global level. To do this, we only need to take two steps: The exception that our handler throws will be automatically translated to an HTTP status and a JSON error body.

What is the Maven setup for spring webflux?

The Maven setup is the same as our previous article, which provides an introduction to Spring Webflux. For our example, we'll use a RESTful endpoint that takes a username as a query parameter and returns “Hello username” as a result.

What happens when you throw an exception in Spring Boot?

Throwing an Exception Any time we throw an exception, the default HTTP return status is omitted and Spring tries to find an exception handler to deal with it: To learn more about how to do that, definitely check-out the Error Handling article on Baeldung. 2.5.


Video Answer


1 Answers

It's because you are making a POST request for which CSRF Protection is enabled. This is also the case for PUT requests. There's an open issue regarding this behaviour. For now, as a work-around, just modify your test code as shown below to get past the 403 response

webClient.mutateWith(csrf()).post()
like image 67
Viswanath Avatar answered Nov 04 '22 00:11

Viswanath