mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-12 07:02:13 +00:00
Separate Testing Reactive Docs
Issue gh-10367
This commit is contained in:
parent
d779cd1d48
commit
b4ffe154d7
@ -103,5 +103,11 @@
|
||||
** Integrations
|
||||
*** xref:reactive/integrations/cors.adoc[CORS]
|
||||
*** xref:reactive/integrations/rsocket.adoc[RSocket]
|
||||
** xref:reactive/test.adoc[Testing]
|
||||
** xref:reactive/test/index.adoc[Testing]
|
||||
*** xref:reactive/test/method.adoc[Testing Method Security]
|
||||
*** xref:reactive/test/web/index.adoc[Testing Web Security]
|
||||
**** xref:reactive/test/web/setup.adoc[WebTestClient Setup]
|
||||
**** xref:reactive/test/web/authentication.adoc[Testing Authentication]
|
||||
**** xref:reactive/test/web/csrf.adoc[Testing CSRF]
|
||||
**** xref:reactive/test/web/oauth2.adoc[Testing OAuth 2.0]
|
||||
** xref:reactive/configuration/webflux.adoc[WebFlux Security]
|
||||
|
5
docs/modules/ROOT/pages/reactive/test/index.adoc
Normal file
5
docs/modules/ROOT/pages/reactive/test/index.adoc
Normal file
@ -0,0 +1,5 @@
|
||||
[[test-webflux]]
|
||||
= Reactive Test Support
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
Spring Security supports two basic modes for testing reactive applications.
|
75
docs/modules/ROOT/pages/reactive/test/method.adoc
Normal file
75
docs/modules/ROOT/pages/reactive/test/method.adoc
Normal file
@ -0,0 +1,75 @@
|
||||
[[test-erms]]
|
||||
= Testing Method Security
|
||||
|
||||
For example, we can test our example from xref:reactive/authorization/method.adoc#jc-erms[EnableReactiveMethodSecurity] using the same setup and annotations we did in xref:servlet/test/method.adoc#test-method[Testing Method Security].
|
||||
Here is a minimal sample of what we can do:
|
||||
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = HelloWebfluxMethodApplication.class)
|
||||
public class HelloWorldMessageServiceTests {
|
||||
@Autowired
|
||||
HelloWorldMessageService messages;
|
||||
|
||||
@Test
|
||||
public void messagesWhenNotAuthenticatedThenDenied() {
|
||||
StepVerifier.create(this.messages.findMessage())
|
||||
.expectError(AccessDeniedException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
public void messagesWhenUserThenDenied() {
|
||||
StepVerifier.create(this.messages.findMessage())
|
||||
.expectError(AccessDeniedException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = "ADMIN")
|
||||
public void messagesWhenAdminThenOk() {
|
||||
StepVerifier.create(this.messages.findMessage())
|
||||
.expectNext("Hello World!")
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@RunWith(SpringRunner::class)
|
||||
@ContextConfiguration(classes = [HelloWebfluxMethodApplication::class])
|
||||
class HelloWorldMessageServiceTests {
|
||||
@Autowired
|
||||
lateinit var messages: HelloWorldMessageService
|
||||
|
||||
@Test
|
||||
fun messagesWhenNotAuthenticatedThenDenied() {
|
||||
StepVerifier.create(messages.findMessage())
|
||||
.expectError(AccessDeniedException::class.java)
|
||||
.verify()
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
fun messagesWhenUserThenDenied() {
|
||||
StepVerifier.create(messages.findMessage())
|
||||
.expectError(AccessDeniedException::class.java)
|
||||
.verify()
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = ["ADMIN"])
|
||||
fun messagesWhenAdminThenOk() {
|
||||
StepVerifier.create(messages.findMessage())
|
||||
.expectNext("Hello World!")
|
||||
.verifyComplete()
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
114
docs/modules/ROOT/pages/reactive/test/web/authentication.adoc
Normal file
114
docs/modules/ROOT/pages/reactive/test/web/authentication.adoc
Normal file
@ -0,0 +1,114 @@
|
||||
= Testing Authentication
|
||||
|
||||
After xref:reactive/test/web/setup.adoc[applying the Spring Security support to `WebTestClient`] we can use either annotations or `mutateWith` support.
|
||||
For example:
|
||||
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Test
|
||||
public void messageWhenNotAuthenticated() throws Exception {
|
||||
this.rest
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isUnauthorized();
|
||||
}
|
||||
|
||||
// --- WithMockUser ---
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
public void messageWhenWithMockUserThenForbidden() throws Exception {
|
||||
this.rest
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = "ADMIN")
|
||||
public void messageWhenWithMockAdminThenOk() throws Exception {
|
||||
this.rest
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("Hello World!");
|
||||
}
|
||||
|
||||
// --- mutateWith mockUser ---
|
||||
|
||||
@Test
|
||||
public void messageWhenMutateWithMockUserThenForbidden() throws Exception {
|
||||
this.rest
|
||||
.mutateWith(mockUser())
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageWhenMutateWithMockAdminThenOk() throws Exception {
|
||||
this.rest
|
||||
.mutateWith(mockUser().roles("ADMIN"))
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("Hello World!");
|
||||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
import org.springframework.test.web.reactive.server.expectBody
|
||||
|
||||
//...
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
fun messageWhenWithMockUserThenForbidden() {
|
||||
this.rest.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = ["ADMIN"])
|
||||
fun messageWhenWithMockAdminThenOk() {
|
||||
this.rest.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk
|
||||
.expectBody<String>().isEqualTo("Hello World!")
|
||||
|
||||
}
|
||||
|
||||
// --- mutateWith mockUser ---
|
||||
|
||||
@Test
|
||||
fun messageWhenMutateWithMockUserThenForbidden() {
|
||||
this.rest
|
||||
.mutateWith(mockUser())
|
||||
.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun messageWhenMutateWithMockAdminThenOk() {
|
||||
this.rest
|
||||
.mutateWith(mockUser().roles("ADMIN"))
|
||||
.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk
|
||||
.expectBody<String>().isEqualTo("Hello World!")
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
In addition to `mockUser()`, Spring Security ships with several other convenience mutators for things like xref:reactive/test/web/csrf.adoc[CSRF] and xref:reactive/test/web/oauth2.adoc[OAuth 2.0].
|
28
docs/modules/ROOT/pages/reactive/test/web/csrf.adoc
Normal file
28
docs/modules/ROOT/pages/reactive/test/web/csrf.adoc
Normal file
@ -0,0 +1,28 @@
|
||||
= Testing with CSRF
|
||||
|
||||
Spring Security also provides support for CSRF testing with `WebTestClient`.
|
||||
For example:
|
||||
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
this.rest
|
||||
// provide a valid CSRF token
|
||||
.mutateWith(csrf())
|
||||
.post()
|
||||
.uri("/login")
|
||||
...
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
this.rest
|
||||
// provide a valid CSRF token
|
||||
.mutateWith(csrf())
|
||||
.post()
|
||||
.uri("/login")
|
||||
...
|
||||
----
|
||||
====
|
5
docs/modules/ROOT/pages/reactive/test/web/index.adoc
Normal file
5
docs/modules/ROOT/pages/reactive/test/web/index.adoc
Normal file
@ -0,0 +1,5 @@
|
||||
[[test-webtestclient]]
|
||||
= Testing Web Security
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
In this section, we'll talk about testing web application endpoints.
|
@ -1,259 +1,7 @@
|
||||
[[test-webflux]]
|
||||
= Reactive Test Support
|
||||
|
||||
[[test-erms]]
|
||||
== Testing Reactive Method Security
|
||||
|
||||
For example, we can test our example from xref:reactive/authorization/method.adoc#jc-erms[EnableReactiveMethodSecurity] using the same setup and annotations we did in xref:servlet/test/method.adoc#test-method[Testing Method Security].
|
||||
Here is a minimal sample of what we can do:
|
||||
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = HelloWebfluxMethodApplication.class)
|
||||
public class HelloWorldMessageServiceTests {
|
||||
@Autowired
|
||||
HelloWorldMessageService messages;
|
||||
|
||||
@Test
|
||||
public void messagesWhenNotAuthenticatedThenDenied() {
|
||||
StepVerifier.create(this.messages.findMessage())
|
||||
.expectError(AccessDeniedException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
public void messagesWhenUserThenDenied() {
|
||||
StepVerifier.create(this.messages.findMessage())
|
||||
.expectError(AccessDeniedException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = "ADMIN")
|
||||
public void messagesWhenAdminThenOk() {
|
||||
StepVerifier.create(this.messages.findMessage())
|
||||
.expectNext("Hello World!")
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@RunWith(SpringRunner::class)
|
||||
@ContextConfiguration(classes = [HelloWebfluxMethodApplication::class])
|
||||
class HelloWorldMessageServiceTests {
|
||||
@Autowired
|
||||
lateinit var messages: HelloWorldMessageService
|
||||
|
||||
@Test
|
||||
fun messagesWhenNotAuthenticatedThenDenied() {
|
||||
StepVerifier.create(messages.findMessage())
|
||||
.expectError(AccessDeniedException::class.java)
|
||||
.verify()
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
fun messagesWhenUserThenDenied() {
|
||||
StepVerifier.create(messages.findMessage())
|
||||
.expectError(AccessDeniedException::class.java)
|
||||
.verify()
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = ["ADMIN"])
|
||||
fun messagesWhenAdminThenOk() {
|
||||
StepVerifier.create(messages.findMessage())
|
||||
.expectNext("Hello World!")
|
||||
.verifyComplete()
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[test-webtestclient]]
|
||||
== WebTestClientSupport
|
||||
|
||||
Spring Security provides integration with `WebTestClient`.
|
||||
The basic setup looks like this:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = HelloWebfluxMethodApplication.class)
|
||||
public class HelloWebfluxMethodApplicationTests {
|
||||
@Autowired
|
||||
ApplicationContext context;
|
||||
|
||||
WebTestClient rest;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.rest = WebTestClient
|
||||
.bindToApplicationContext(this.context)
|
||||
// add Spring Security test Support
|
||||
.apply(springSecurity())
|
||||
.configureClient()
|
||||
.filter(basicAuthentication())
|
||||
.build();
|
||||
}
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
=== Authentication
|
||||
|
||||
After applying the Spring Security support to `WebTestClient` we can use either annotations or `mutateWith` support.
|
||||
For example:
|
||||
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Test
|
||||
public void messageWhenNotAuthenticated() throws Exception {
|
||||
this.rest
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isUnauthorized();
|
||||
}
|
||||
|
||||
// --- WithMockUser ---
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
public void messageWhenWithMockUserThenForbidden() throws Exception {
|
||||
this.rest
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = "ADMIN")
|
||||
public void messageWhenWithMockAdminThenOk() throws Exception {
|
||||
this.rest
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("Hello World!");
|
||||
}
|
||||
|
||||
// --- mutateWith mockUser ---
|
||||
|
||||
@Test
|
||||
public void messageWhenMutateWithMockUserThenForbidden() throws Exception {
|
||||
this.rest
|
||||
.mutateWith(mockUser())
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageWhenMutateWithMockAdminThenOk() throws Exception {
|
||||
this.rest
|
||||
.mutateWith(mockUser().roles("ADMIN"))
|
||||
.get()
|
||||
.uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("Hello World!");
|
||||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
import org.springframework.test.web.reactive.server.expectBody
|
||||
|
||||
//...
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
fun messageWhenWithMockUserThenForbidden() {
|
||||
this.rest.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = ["ADMIN"])
|
||||
fun messageWhenWithMockAdminThenOk() {
|
||||
this.rest.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk
|
||||
.expectBody<String>().isEqualTo("Hello World!")
|
||||
|
||||
}
|
||||
|
||||
// --- mutateWith mockUser ---
|
||||
|
||||
@Test
|
||||
fun messageWhenMutateWithMockUserThenForbidden() {
|
||||
this.rest
|
||||
.mutateWith(mockUser())
|
||||
.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun messageWhenMutateWithMockAdminThenOk() {
|
||||
this.rest
|
||||
.mutateWith(mockUser().roles("ADMIN"))
|
||||
.get().uri("/message")
|
||||
.exchange()
|
||||
.expectStatus().isOk
|
||||
.expectBody<String>().isEqualTo("Hello World!")
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
=== CSRF Support
|
||||
|
||||
Spring Security also provides support for CSRF testing with `WebTestClient`.
|
||||
For example:
|
||||
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
this.rest
|
||||
// provide a valid CSRF token
|
||||
.mutateWith(csrf())
|
||||
.post()
|
||||
.uri("/login")
|
||||
...
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
this.rest
|
||||
// provide a valid CSRF token
|
||||
.mutateWith(csrf())
|
||||
.post()
|
||||
.uri("/login")
|
||||
...
|
||||
----
|
||||
====
|
||||
|
||||
[[webflux-testing-oauth2]]
|
||||
=== Testing OAuth 2.0
|
||||
= Testing OAuth 2.0
|
||||
|
||||
When it comes to OAuth 2.0, the same principles covered earlier still apply: Ultimately, it depends on what your method under test is expecting to be in the `SecurityContextHolder`.
|
||||
When it comes to OAuth 2.0, xref:reactive/test/method.adoc#test-erms[the same principles covered earlier still apply]: Ultimately, it depends on what your method under test is expecting to be in the `SecurityContextHolder`.
|
||||
|
||||
For example, for a controller that looks like this:
|
||||
|
||||
@ -277,7 +25,7 @@ fun foo(user: Principal): Mono<String> {
|
||||
----
|
||||
====
|
||||
|
||||
There's nothing OAuth2-specific about it, so you will likely be able to simply <<test-erms,use `@WithMockUser`>> and be fine.
|
||||
There's nothing OAuth2-specific about it, so you will likely be able to simply xref:reactive/test/method.adoc#test-erms[use `@WithMockUser`] and be fine.
|
||||
|
||||
But, in cases where your controllers are bound to some aspect of Spring Security's OAuth 2.0 support, like the following:
|
||||
|
||||
@ -304,7 +52,7 @@ fun foo(@AuthenticationPrincipal user: OidcUser): Mono<String> {
|
||||
then Spring Security's test support can come in handy.
|
||||
|
||||
[[webflux-testing-oidc-login]]
|
||||
=== Testing OIDC Login
|
||||
== Testing OIDC Login
|
||||
|
||||
Testing the method above with `WebTestClient` would require simulating some kind of grant flow with an authorization server.
|
||||
Certainly this would be a daunting task, which is why Spring Security ships with support for removing this boilerplate.
|
||||
@ -387,7 +135,7 @@ Further, it also links that `OidcUser` to a simple instance of `OAuth2Authorized
|
||||
This can be handy if your tests <<webflux-testing-oauth2-client,use the `@RegisteredOAuth2AuthorizedClient` annotation>>..
|
||||
|
||||
[[webflux-testing-oidc-login-authorities]]
|
||||
==== Configuring Authorities
|
||||
=== Configuring Authorities
|
||||
|
||||
In many circumstances, your method is protected by filter or method security and needs your `Authentication` to have certain granted authorities to allow the request.
|
||||
|
||||
@ -416,7 +164,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-oidc-login-claims]]
|
||||
==== Configuring Claims
|
||||
=== Configuring Claims
|
||||
|
||||
And while granted authorities are quite common across all of Spring Security, we also have claims in the case of OAuth 2.0.
|
||||
|
||||
@ -472,7 +220,7 @@ client
|
||||
since `OidcUser` collects its claims from `OidcIdToken`.
|
||||
|
||||
[[webflux-testing-oidc-login-user]]
|
||||
==== Additional Configurations
|
||||
=== Additional Configurations
|
||||
|
||||
There are additional methods, too, for further configuring the authentication; it simply depends on what data your controller expects:
|
||||
|
||||
@ -517,7 +265,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-oauth2-login]]
|
||||
=== Testing OAuth 2.0 Login
|
||||
== Testing OAuth 2.0 Login
|
||||
|
||||
As with <<webflux-testing-oidc-login,testing OIDC login>>, testing OAuth 2.0 Login presents a similar challenge of mocking a grant flow.
|
||||
And because of that, Spring Security also has test support for non-OIDC use cases.
|
||||
@ -606,7 +354,7 @@ Further, it also links that `OAuth2User` to a simple instance of `OAuth2Authoriz
|
||||
This can be handy if your tests <<webflux-testing-oauth2-client,use the `@RegisteredOAuth2AuthorizedClient` annotation>>.
|
||||
|
||||
[[webflux-testing-oauth2-login-authorities]]
|
||||
==== Configuring Authorities
|
||||
=== Configuring Authorities
|
||||
|
||||
In many circumstances, your method is protected by filter or method security and needs your `Authentication` to have certain granted authorities to allow the request.
|
||||
|
||||
@ -635,7 +383,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-oauth2-login-claims]]
|
||||
==== Configuring Claims
|
||||
=== Configuring Claims
|
||||
|
||||
And while granted authorities are quite common across all of Spring Security, we also have claims in the case of OAuth 2.0.
|
||||
|
||||
@ -689,7 +437,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-oauth2-login-user]]
|
||||
==== Additional Configurations
|
||||
=== Additional Configurations
|
||||
|
||||
There are additional methods, too, for further configuring the authentication; it simply depends on what data your controller expects:
|
||||
|
||||
@ -733,7 +481,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-oauth2-client]]
|
||||
=== Testing OAuth 2.0 Clients
|
||||
== Testing OAuth 2.0 Clients
|
||||
|
||||
Independent of how your user authenticates, you may have other tokens and client registrations that are in play for the request you are testing.
|
||||
For example, your controller may be relying on the client credentials grant to get a token that isn't associated with the user at all:
|
||||
@ -846,7 +594,7 @@ assertThat(authorizedClient.accessToken.scopes).containsExactly("read")
|
||||
The client can then be retrieved as normal using `@RegisteredOAuth2AuthorizedClient` in a controller method.
|
||||
|
||||
[[webflux-testing-oauth2-client-scopes]]
|
||||
==== Configuring Scopes
|
||||
=== Configuring Scopes
|
||||
|
||||
In many circumstances, the OAuth 2.0 access token comes with a set of scopes.
|
||||
If your controller inspects these, say like so:
|
||||
@ -914,7 +662,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-oauth2-client-registration]]
|
||||
==== Additional Configurations
|
||||
=== Additional Configurations
|
||||
|
||||
There are additional methods, too, for further configuring the authentication; it simply depends on what data your controller expects:
|
||||
|
||||
@ -961,7 +709,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-jwt]]
|
||||
=== Testing JWT Authentication
|
||||
== Testing JWT Authentication
|
||||
|
||||
In order to make an authorized request on a resource server, you need a bearer token.
|
||||
If your resource server is configured for JWTs, then this would mean that the bearer token needs to be signed and then encoded according to the JWT specification.
|
||||
@ -970,7 +718,7 @@ All of this can be quite daunting, especially when this isn't the focus of your
|
||||
Fortunately, there are a number of simple ways that you can overcome this difficulty and allow your tests to focus on authorization and not on representing bearer tokens.
|
||||
We'll look at two of them now:
|
||||
|
||||
==== `mockJwt() WebTestClientConfigurer`
|
||||
=== `mockJwt() WebTestClientConfigurer`
|
||||
|
||||
The first way is via a `WebTestClientConfigurer`.
|
||||
The simplest of these would be to use the `SecurityMockServerConfigurers#mockJwt` method like the following:
|
||||
@ -1144,7 +892,7 @@ client
|
||||
----
|
||||
====
|
||||
|
||||
==== `authentication()` `WebTestClientConfigurer`
|
||||
=== `authentication()` `WebTestClientConfigurer`
|
||||
|
||||
The second way is by using the `authentication()` `Mutator`.
|
||||
Essentially, you can instantiate your own `JwtAuthenticationToken` and provide it in your test, like so:
|
||||
@ -1184,7 +932,7 @@ client
|
||||
Note that as an alternative to these, you can also mock the `ReactiveJwtDecoder` bean itself with a `@MockBean` annotation.
|
||||
|
||||
[[webflux-testing-opaque-token]]
|
||||
=== Testing Opaque Token Authentication
|
||||
== Testing Opaque Token Authentication
|
||||
|
||||
Similar to <<webflux-testing-jwt,JWTs>>, opaque tokens require an authorization server in order to verify their validity, which can make testing more difficult.
|
||||
To help with that, Spring Security has test support for opaque tokens.
|
||||
@ -1270,7 +1018,7 @@ assertThat(token.authorities).containsExactly(SimpleGrantedAuthority("SCOPE_read
|
||||
Spring Security does the necessary work to make sure that the `BearerTokenAuthentication` instance is available for your controller methods.
|
||||
|
||||
[[webflux-testing-opaque-token-authorities]]
|
||||
==== Configuring Authorities
|
||||
=== Configuring Authorities
|
||||
|
||||
In many circumstances, your method is protected by filter or method security and needs your `Authentication` to have certain granted authorities to allow the request.
|
||||
|
||||
@ -1299,7 +1047,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-opaque-token-attributes]]
|
||||
==== Configuring Claims
|
||||
=== Configuring Claims
|
||||
|
||||
And while granted authorities are quite common across all of Spring Security, we also have attributes in the case of OAuth 2.0.
|
||||
|
||||
@ -1353,7 +1101,7 @@ client
|
||||
====
|
||||
|
||||
[[webflux-testing-opaque-token-principal]]
|
||||
==== Additional Configurations
|
||||
=== Additional Configurations
|
||||
|
||||
There are additional methods, too, for further configuring the authentication; it simply depends on what data your controller expects.
|
||||
|
27
docs/modules/ROOT/pages/reactive/test/web/setup.adoc
Normal file
27
docs/modules/ROOT/pages/reactive/test/web/setup.adoc
Normal file
@ -0,0 +1,27 @@
|
||||
= WebTestClient Security Setup
|
||||
|
||||
The basic setup looks like this:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = HelloWebfluxMethodApplication.class)
|
||||
public class HelloWebfluxMethodApplicationTests {
|
||||
@Autowired
|
||||
ApplicationContext context;
|
||||
|
||||
WebTestClient rest;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.rest = WebTestClient
|
||||
.bindToApplicationContext(this.context)
|
||||
// add Spring Security test Support
|
||||
.apply(springSecurity())
|
||||
.configureClient()
|
||||
.filter(basicAuthentication())
|
||||
.build();
|
||||
}
|
||||
// ...
|
||||
}
|
||||
----
|
Loading…
x
Reference in New Issue
Block a user