2019-12-07 00:39:55 +08:00
[[servlet-authentication-basic]]
= Basic Authentication
2021-07-31 04:07:36 +08:00
:figures: servlet/authentication/unpwd
2019-12-07 00:39:55 +08:00
2021-04-22 05:01:26 +08:00
This section provides details on how Spring Security provides support for https://tools.ietf.org/html/rfc7617[Basic HTTP Authentication] for servlet-based applications.
2019-12-07 00:39:55 +08:00
// FIXME: describe authenticationentrypoint, authenticationfailurehandler, authenticationsuccesshandler
2021-04-22 05:01:26 +08:00
This section describes how HTTP Basic Authentication works within Spring Security.
First, we see the https://tools.ietf.org/html/rfc7235#section-4.1[WWW-Authenticate] header is sent back to an unauthenticated client:
2020-02-29 06:39:41 +08:00
.Sending WWW-Authenticate Header
2024-11-19 03:10:48 +08:00
[.invert-dark]
2020-02-29 06:39:41 +08:00
image::{figures}/basicauthenticationentrypoint.png[]
2021-12-14 06:57:36 +08:00
The preceding figure builds off our xref:servlet/architecture.adoc#servlet-securityfilterchain[`SecurityFilterChain`] diagram.
2020-02-29 06:39:41 +08:00
image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource `/private` for which it is not authorized.
2023-04-19 08:13:50 +08:00
image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
2020-02-29 06:39:41 +08:00
2021-08-20 03:17:49 +08:00
image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__.
2024-07-10 02:23:24 +08:00
The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of javadoc:org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint[], which sends a WWW-Authenticate header.
2020-02-29 06:39:41 +08:00
The `RequestCache` is typically a `NullRequestCache` that does not save the request since the client is capable of replaying the requests it originally requested.
2024-12-13 19:35:06 +08:00
[NOTE]
====
The default HTTP Basic Auth Provider will suppress both Response body and `WWW-Authenticate` header in the 401 response when
the request was made with a `X-Requested-By: XMLHttpRequest` header. This allows frontends to implement their own
authentication code, instead of triggering the browser login dialog.
To override, implement your own
javadoc:org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint[] .
====
2021-04-22 05:01:26 +08:00
When a client receives the `WWW-Authenticate` header, it knows it should retry with a username and password.
The following image shows the flow for the username and password being processed:
2020-02-29 06:39:41 +08:00
2020-03-25 05:33:34 +08:00
[[servlet-authentication-basicauthenticationfilter]]
2020-02-29 06:39:41 +08:00
.Authenticating Username and Password
2024-11-19 03:10:48 +08:00
[.invert-dark]
2020-02-29 06:39:41 +08:00
image::{figures}/basicauthenticationfilter.png[]
2021-12-14 06:57:36 +08:00
The preceding figure builds off our xref:servlet/architecture.adoc#servlet-securityfilterchain[`SecurityFilterChain`] diagram.
2020-02-29 06:39:41 +08:00
2021-12-14 06:57:36 +08:00
image:{icondir}/number_1.png[] When the user submits their username and password, the `BasicAuthenticationFilter` creates a `UsernamePasswordAuthenticationToken`, which is a type of xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[`Authentication`] by extracting the username and password from the `HttpServletRequest`.
2020-02-29 06:39:41 +08:00
image:{icondir}/number_2.png[] Next, the `UsernamePasswordAuthenticationToken` is passed into the `AuthenticationManager` to be authenticated.
2021-08-26 02:31:00 +08:00
The details of what `AuthenticationManager` looks like depend on how the xref:servlet/authentication/passwords/index.adoc#servlet-authentication-unpwd-storage[user information is stored].
2020-02-29 06:39:41 +08:00
2021-04-22 05:01:26 +08:00
image:{icondir}/number_3.png[] If authentication fails, then __Failure__.
2020-02-29 06:39:41 +08:00
2021-12-14 06:57:36 +08:00
. The xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder] is cleared out.
2021-04-22 05:01:26 +08:00
. `RememberMeServices.loginFail` is invoked.
2020-02-29 06:39:41 +08:00
If remember me is not configured, this is a no-op.
2024-07-10 02:23:24 +08:00
See the javadoc:org.springframework.security.web.authentication.RememberMeServices[] interface in the Javadoc.
2021-04-22 05:01:26 +08:00
. `AuthenticationEntryPoint` is invoked to trigger the WWW-Authenticate to be sent again.
2024-07-10 02:23:24 +08:00
See the javadoc:org.springframework.security.web.AuthenticationEntryPoint[] interface in the Javadoc.
2020-02-29 06:39:41 +08:00
image:{icondir}/number_4.png[] If authentication is successful, then __Success__.
2020-03-02 09:23:31 +08:00
2021-12-14 06:57:36 +08:00
. The xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] is set on the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder].
2021-04-22 05:01:26 +08:00
. `RememberMeServices.loginSuccess` is invoked.
2020-02-29 06:39:41 +08:00
If remember me is not configured, this is a no-op.
2024-07-10 02:23:24 +08:00
See the javadoc:org.springframework.security.web.authentication.RememberMeServices[] interface in the Javadoc.
2021-04-22 05:01:26 +08:00
. The `BasicAuthenticationFilter` invokes `FilterChain.doFilter(request,response)` to continue with the rest of the application logic.
2024-07-10 02:23:24 +08:00
See the javadoc:org.springframework.security.web.authentication.www.BasicAuthenticationFilter[] Class in the Javadoc
2020-02-29 06:39:41 +08:00
2021-04-22 05:01:26 +08:00
By default, Spring Security's HTTP Basic Authentication support is enabled.
2019-12-07 00:39:55 +08:00
However, as soon as any servlet based configuration is provided, HTTP Basic must be explicitly provided.
2021-04-22 05:01:26 +08:00
The following example shows a minimal, explicit configuration:
2019-12-07 00:39:55 +08:00
2020-01-09 12:00:17 +08:00
.Explicit HTTP Basic Configuration
2023-06-19 10:30:41 +08:00
[tabs]
======
Java::
+
2020-01-09 12:00:17 +08:00
[source,java,role="primary"]
2019-12-07 00:39:55 +08:00
----
2022-02-08 23:12:10 +08:00
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
2019-12-07 00:39:55 +08:00
http
// ...
.httpBasic(withDefaults());
2022-02-08 23:12:10 +08:00
return http.build();
2019-12-07 00:39:55 +08:00
}
----
2023-06-19 10:30:41 +08:00
XML::
+
2020-01-09 12:00:17 +08:00
[source,xml,role="secondary"]
2019-12-07 00:39:55 +08:00
----
<http>
<!-- ... -->
<http-basic />
</http>
----
2020-01-15 00:20:18 +08:00
2023-06-19 10:30:41 +08:00
Kotlin::
+
2020-01-15 00:20:18 +08:00
[source,kotlin,role="secondary"]
----
2022-02-08 23:12:10 +08:00
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
2020-01-15 00:20:18 +08:00
http {
// ...
httpBasic { }
}
2022-02-08 23:12:10 +08:00
return http.build()
2020-01-15 00:20:18 +08:00
}
----
2023-06-19 10:30:41 +08:00
======