Files
spring-boot-demo/restclient-basic-auth/docs/02-restclient-basic-auth-patterns.md
T
Claude e4b5636f7c Add custom-validation, etag-caching, restclient-basic-auth: Boot 4.1 API pass
Three companion modules verifying and rewriting the Boot 4.1.1 / Framework
7.0.9 story for three older articles: the javax->jakarta.validation namespace
fix plus Jakarta Validation 3.1 record-validation clarification, ETag/
conditional-request APIs re-verified unchanged plus the starter rename, and
RestTemplate Basic Auth rebuilt on RestClient with the exchange() trap called
out. 19 real passing tests generate every transcript quoted from the three
companion articles.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EQNA6DJ9VgCtW6zhCE8Xud
2026-09-19 10:17:09 +00:00

70 lines
3.5 KiB
Markdown

# 2. RestClient with Basic Auth, two ways
[Prev: {noop} passwords](01-password-encoding.md) | [README](../README.md) | Next: [The starter split, and the exchange() trap](03-starter-split-and-exchange-trap.md)
Source: [`RestClientConfig.java`](../src/main/java/com/ankurm/restclientbasicauth/client/RestClientConfig.java),
[`ApiClient.java`](../src/main/java/com/ankurm/restclientbasicauth/client/ApiClient.java).
Test: [`RestClientBasicAuthTest.java`](../src/test/java/com/ankurm/restclientbasicauth/RestClientBasicAuthTest.java).
Transcripts: [`docs/output/01-restclient-basic-auth-default-headers.txt`](output/01-restclient-basic-auth-default-headers.txt),
[`docs/output/02-restclient-basic-auth-interceptor.txt`](output/02-restclient-basic-auth-interceptor.txt).
The original article's two `RestTemplate` patterns -- `RestTemplateBuilder.basicAuthentication(...)`
and a hand-added `BasicAuthenticationInterceptor` -- both have a direct `RestClient` equivalent.
Both are built on the **auto-configured `RestClient.Builder`** injected as a constructor parameter,
never `RestClient.create()`, which carries none of Boot's message converters, observability, or
customizer beans -- the same rule the
[RestTemplate to RestClient migration guide](https://ankurm.com/resttemplate-to-restclient-migration-guide/)
covers in more general depth.
## Idiomatic on RestClient: `defaultHeaders` + `setBasicAuth`
```java
@Bean
public RestClient restClientWithDefaultHeaders(RestClient.Builder builder) {
return builder
.defaultHeaders(headers -> headers.setBasicAuth("admin", "password123"))
.build();
}
```
```
Response: Hello, you have accessed a secured endpoint!
```
([`docs/output/01-restclient-basic-auth-default-headers.txt`](output/01-restclient-basic-auth-default-headers.txt))
-- a real HTTP call against a real embedded Tomcat with a real Spring Security filter chain, not a
mock.
## Ported unchanged: `BasicAuthenticationInterceptor`
```java
@Bean
public RestClient restClientWithInterceptor(RestClient.Builder builder) {
return builder
.requestInterceptor(new BasicAuthenticationInterceptor("admin", "password123"))
.build();
}
```
`BasicAuthenticationInterceptor` implements `ClientHttpRequestInterceptor` -- the exact same
interface both `RestTemplate.getInterceptors()` and `RestClient.Builder.requestInterceptor(...)`
accept, so this class needs no changes at all to move from one client to the other. Same result:
[`docs/output/02-restclient-basic-auth-interceptor.txt`](output/02-restclient-basic-auth-interceptor.txt).
Prefer `defaultHeaders` when the credentials are fixed at bean-creation time; keep the interceptor
form when credentials must be resolved per request (a token fetched from a vault, say) --
an interceptor runs on every call, a `defaultHeaders` value is captured once.
## The negative cases, checked too
`docs/output/03-restclient-no-credentials-401.txt` and `04-restclient-wrong-password-401.txt`
confirm what actually happens on the failure path: `retrieve()` throws
`HttpClientErrorException.Unauthorized` on a 401, exactly like `RestTemplate` did -- this is the
default `retrieve()` behaviour, not the `exchange()` behaviour covered in the next chapter.
## Going deeper
- [`RestClient` Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestClient.html) (rel="nofollow")
- Prev: [{noop} passwords](01-password-encoding.md)
- Next: [The starter split, and the exchange() trap](03-starter-split-and-exchange-trap.md)