<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
The Auth Service serves as an Authentication Provider built on top of core Spring Security OAuth2 functionality.
The default implementation follows basic OIDC-like principles to allow support for concepts like silent authentication flows and identity token support.
The authentication service is built to be highly extensible. It supports both SSO and non-SSO flows. The service itself ships with pre-built login pages that can be easily styled to support custom templates. Additionally, the backing authentication mechanisms can be integrated with external services using typical Spring Boot OAuth 2 configuration patterns.
Those already familiar with Spring Security OAuth and Open ID Connect integrations will feel comfortable working within the patterns and flows implemented within Broadleaf’s Auth Service
Broadleaf uses Centralized Universal Login by default and recommends this for users. This means that the Auth Microservice hosts the login, registration, change password, and reset password forms. Thus, users of the commerce or admin apps will be redirected to the Auth service to perform these operations; then redirected back upon completion.
|
Tip
|
Universal Login also supports Remember-Me Login |
Embedded login means that the commerce or admin app would host its own forms and submit the data to the Auth server. The user would not be redirected anywhere. While this may seem better from a user-experience perspective, it is less secure. Auth0 discusses this in more depth.
However, if the need is strong enough to use embedded login for web apps, they may be enabled with little configuration. Moreover, the default deployment of microservices recommended by broadleaf would allow cross-origin requests to be locked down since all microservices along with the frontend apps are run behind the same gateway, which is the greatest source of risk with embedded login.
To enable embedded login in general for the system, set broadleaf.auth.login.embedded.enabled to true.
Then, set embeddedLoginEnabled to true on each individual AuthorizationServer where this feature is desired.
This allows the admin to still use Universal Login while a commerce app could use embedded since each will have their own AuthorizationServers.
(since 2.1.4)
|
Note
|
Here is the documentation for Remember-Me configuration properties. |
|
Note
|
This feature only applies when using the first-party Universal Login. It does not apply to embedded login or third party IDP login flows. |
Remember-Me functionality involves a user indicating at login time that they want their authentication on the current device/client to be remembered. If they request this behavior, then when their session expires on the device, they will not be required to re-enter their credentials and will instead be automatically re-logged in with a new session.
This can improve the user experience by reducing disruption.
Broadleaf’s Remember-Me approach is largely based on Spring’s Persistent Token Approach.
With that being said, there are a handful of key changes to this approach to make it fit into Broadleaf’s requirements:
Separation of Remember-Me state per-client.
AuthenticationServices can be used to log into a variety of AuthorizedClients. In the same way that the BLSID session state is distinct per-client, we also maintain separate Remember-Me state per-client.
This means that a user can sign in to multiple different clients on the same device, and the Remember-Me preferences/expiration for each will remain independent.
This includes ensuring logging out of one client does not affect any other client.
Remember-Me auto-login is only engaged on requests to GET /login
In Broadleaf, 'login' is only a means to obtain a session token (BLSID).
The session token is what operations in AuthenticationServices typically require for authentication.
For this reason, Remember-Me auto-login is only engaged on requests to GET /login, and does not apply to any other request.
If the user has a valid Remember-Me cookie available during a request to GET /login, the login page will be skipped altogether: they will be granted a new session cookie, granted a renewed Remember-Me cookie, and immediately redirected away with the same logic as if they just entered their credentials.
|
Note
|
When an auto-login has been engaged, DefaultSessionAuthenticationStrategy will include the remember_me_autologin claim in the session token.
This can be used by downstream operations to identify whether a user had to enter their credentials to obtain their current session token.
|
A major advantage of this design is its seamless integration with existing flows in AuthenticationServices.
For example, when there is an error with a session token, the user is typically redirected back to /login (with a saved request BLSR cookie set).
Since Remember-Me applies to this path, the user will seamlessly be re-logged in with a new session and redirected back.
In AuthorizationServer, inactivityTimeoutSeconds configures the issued session token’s initial validity time (exp), and requireLoginTimeoutSeconds drives the maximum date to which that original session token can be automatically 'refreshed' by AuthenticationServices (max).
This logic is seen in OAuth2SessionAuthenticationFilter.
These concepts are still intact when Remember-Me is active.
For example, after a user provides their credentials and signs in, the session token will expire in inactivityTimeoutSeconds.
In the interim, if there are any requests made to AuthenticationServices with the session cookie provided, the session token’s expiration will be automatically 'refreshed' up to the original max in requireLoginTimeoutSeconds.
When the session token finally reaches max and can no longer be silently refreshed, the user can be redirected to /remember-me-continuation, which ultimately leads back to /login where Remember-Me auto-login can kick in.
At this point, a net-new session token with a new max expiration is issued to the user, and the process can be repeated.
|
Note
|
The user can also be pre-emptively redirected to /remember-me-continuation before their session token is expired.
When they reach /login, if Remember-Me is active, they will still be issued a brand-new session token to replace their existing one.
|
When Remember-Me is enabled via configuration properties, a variety of components are registered into the Spring context.
BroadleafRememberMeAuthenticationFilter is responsible for intercepting GET /login requests and engaging auto-login if applicable.
This component invokes the same SessionAuthenticationStrategy and AuthenticationSuccessHandler as the form login flow in order to issue the session cookie and engage the appropriate redirect (ex: by honoring the BLSR saved request cookie).
RememberMeLoginAuthenticationStrategyDelegate is invoked by SessionAuthenticationStrategy to ensure a session cookie is issued successfully after auto-login.
BroadleafPersistentTokenRememberMeServices and BroadleafPersistentTokenRepository are responsible for managing token issue on successful interactive login, token rotation on auto-login, and token revocation on error.
The integration with credentials-entry login is done by setting BroadleafPersistentTokenRememberMeServices on FormLoginAuthenticationFilter.setRememberMeServices.
RememberMeLogoutHandlerDelegate is invoked by AuthenticationLogoutHandler to cancel/revoke Remember-Me tokens for a user during logout.
RememberMeCookieTheftExceptionHandler is responsible for handling the scenario where Remember-Me cookie theft has been detected.
By default, this redirects to logout.
RememberMeCookieUtility is a component that centralizes management of the Remember-Me cookie to guarantee consistent logic in all components that need to operate on it.
RememberMeAvailableHeaderFilter engages on certain requests to provide a response header that a frontend client application can use as a hint to determine when Remember-Me is available for the current session.
This is only useful if the frontend and AuthenticationServices are on the same domain and can therefore share cookies. In such cases, the frontend will be able to use the response header to inform its session management logic.
In cross-origin scenarios (where the frontend is on a different domain than AuthenticationServices), this will not be useful.
Cross-origin requests will not include the requisite cookies, and the frontend will not receive the responses from AuthenticationServices directly anyway.
This shouldn’t matter, however, since in cross-origin environments, the 'session' is driven by refresh tokens rather than session cookies, and thus the frontend is not responsible for session management anyway.
Typically, to obtain new tokens, the frontend will do a full redirect to the /oauth/authorize endpoint in AuthenticationServices, at which point AuthenticationServices itself can intelligently redirect to /login and handle Remember-Me as-needed before redirecting back to the OAuth2 flow.
RememberMeContinuationEndpointFilter is responsible for exposing the GET /remember-me-continuation endpoint.
This is relevant when a frontend client application wants to pre-emptively renew a user’s session.
Due to restrictions imposed by VerifyRedirectCookieFilter, the frontend typically can’t just redirect to /login directly without having a BLSR saved request cookie present.
The Remember-Me Continuation endpoint serves as a "middleman" that the frontend can redirect to instead.
This endpoint establishes the necessary BLSR cookie with an appropriate post-login redirect value for the client, and then redirects to /login where the normal auto-login functionality can engage.
After auto-login, the user is subsequently redirected to the post-login success URL.
Since Broadleaf’s implementation is based on Spring’s 'persistent token' approach, it requires domain and persistence configuration.
|
Note
|
Even if remember-me is disabled, this persistence configuration will still be active. In such a case, the domain will simply be unused and remain dormant. |
The JpaPersistentRememberMeToken entity (table name blc_remember_me_token) is an analog to the persistent_logins table from Spring’s JdbcTokenRepositoryImpl.
Having an explicitly defined JPA entity grants a higher maintainability and flexibility over the default implementation.
RememberMeTokenEntityRepository is the repository responsible for managing JpaPersistentRememberMeToken entities.
This is intentionally distinct from BroadleafPersistentTokenRepository to separate lower-level persistence concerns from requirements of the Spring PersistentTokenRepository interface.
(since 3.0.0)
Session Token Blacklisting is a security feature designed to satisfy strict security postures and rigorous audit requirements.
To understand this feature, it’s helpful to clarify the distinction between the token types used in Broadleaf’s authentication/authorization flows:
Session Tokens (e.g., BLSID-* cookies): These are authentication tokens managed by AuthenticationServices.
They represent a user’s active session with the AuthenticationServices itself after logging in with credentials (potentially via third party IDP).
These are used for endpoints within AuthenticationServices, such as authenticating requests to /oauth/authorize to generate new access tokens. They rely on configurable sliding-window expirations.
Access Tokens (OAuth2 Bearer tokens): These are strictly permission-scoped authorization tokens with a (configurable) much shorter lifetime than other types of tokens. Actual API calls to downstream resource servers (like CatalogServices or CartServices) rely exclusively on access tokens to execute.
Refresh Tokens (only relevant when using OAuth2 Refresh Token functionality): Strictly permission scoped tokens used to obtain new access tokens when the current ones expire, without requiring the user to log in again.
In stateless, JWT-based architectures, an authentication session token remains cryptographically valid until its configured expiration time (TTL) elapses.
Broadleaf’s standard security measures for session cookies (ex: BLSID-*) provide a high degree of protection against token theft via HttpOnly and Secure flags, prevent token abuse through SameSite restrictions and CSRF protections, and limit the overall window of exposure with configurable short-lived sliding expirations.
Standard logouts simply clear the client-side state by removing the session cookie.
However, the raw token itself remains technically valid on the server until it naturally expires.
Session Token Blacklisting provides an additional layer of defense-in-depth, ensuring that once a session is terminated via logout or re-login, the underlying tokens cannot be replayed even if somehow intercepted.
This feature applies specifically to session tokens, and optionally to access tokens as well if 'Access Token Blacklisting Checks' are enabled as described below.
This feature relies on a Session ID (sid) lineage.
Upon initial login, a unique sid claim is generated and embedded in the session token claims.
When a session token is automatically refreshed (such as for an updated expiration within an inactivity timeout), the existing sid is preserved and copied over to the new token.
Thus, all tokens in a sliding-window refresh chain share the exact same sid.
When a session is terminated, this sid is blacklisted, instantly invalidating the entire lineage of session tokens.
There are two distinct features in this space:
Session Token Blacklisting: Fully self-contained within AuthenticationServices. When enabled, this invalidates the session lineage on logout, preventing the reuse of any session tokens issued during that specific session.
Access Token Blacklisting Checks: An optional additional filter in MicroservicesGateways.
While access tokens already have a much shorter expiration and strict permissions, strict security requirements may dictate that access tokens should stop working immediately after a user logs out.
This feature achieves that.
By propagating the originating sid from the session token into the downstream access token claims (via the SessionIdAccessTokenEnhancer), this filter allows the API Gateway to check incoming access tokens against the active blacklist before routing requests to downstream services.
Out of the box, two implementations are available for both AuthenticationServices and MicroservicesGateways: LOCAL_MEMORY and REDIS.
Local Memory (LOCAL_MEMORY): Designed exclusively for local development and testing.
It is transient and should not be used in production.
|
Note
|
Since access token blacklisting checks require the gateways and AuthenticationServices to share a source of truth, a local memory blacklist in AuthenticationServices will not be visible to MicroservicesGateways enforcement. If testing the gateway enforcement feature locally, you must either spin up a local Redis container and use the |
Redis (REDIS): Production-ready implementation that integrates with Redis as the blacklist store, offering low latency for blacklisting operations.
|
Note
|
This feature relies on an external Redis instance but does not provision or include the Redis server itself. Clients are responsible for establishing and managing that Redis instance, whether it’s self-hosted or provided via a cloud-managed offering. |
For more details on all available configuration options, please see:
To configure Redis for Session Token Blacklisting in AuthenticationServices, follow these steps:
Add the Dependency: Add the Spring Data Redis starter to AuthenticationServices in your client project.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
|
Note
|
Adding this dependency automatically enables support for Spring Data Redis Repositories due to Spring Boot’s auto-configuration. However, the session token blacklisting implementation does not rely on those repositories (it uses |
|
Note
|
If Redis is used as the implementation in higher environments, but Redis will be unavailable for local development in AuthenticationServices, it may be worthwhile to set |
Configure the Implementation: Enable the Redis implementation in your properties.
broadleaf.auth.security.token-blacklist-manager.implementation=REDIS
Configure the Connection: Provide standard Spring Data properties to configure the Redis connection.
Example for Local Redis Instance:
spring:
data:
redis:
# Or host.docker.internal if Auth is running inside a container and Redis is also in a container
host: localhost
port: 6379
Example for Remote Redis Instance (e.g., Serverless ElastiCache):
|
Note
|
The following is just an example. Instructions and exact property mappings will vary depending on the exact provider and instance type used. Refer to Spring Data Redis documentation for the full suite of possible configuration options. |
When connecting to an ElastiCache Serverless instance, it should be provisioned within the same VPC as the application clusters to allow reachability on port 6379.
Ideally, User Groups and ACLs should be utilized instead of a single shared password.
The generated passwords for each user should be stored in a secure location, such as an encrypted Spring Cloud Config Server source.
spring:
data:
redis:
host: ${REDIS_CLUSTER_URL} # e.g., the serverless endpoint URL
port: 6379
ssl:
enabled: true
# example user that can be configured with 'on ~* +@read +@write +@connection -@dangerous'
username: auth-svc-user
password: ${AUTH_SVC_REDIS_PASSWORD}
To enforce blacklisting at the edge for access tokens, configure the MicroservicesGateways:
Enable the Redis Configuration: The MicroservicesGateways apps come pre-packaged as Docker images with the spring-boot-starter-data-redis-reactive dependency already available. By default, the Spring Redis configuration is fully dormant and disabled. It must be explicitly enabled to activate the Spring AutoConfiguration.
broadleaf.gateway.redis.enabled=true
Configure the Implementation: Enable the Redis implementation for the gateway filter.
broadleaf.gateway.auth.access-token-blacklist-filter.implementation=REDIS
Configure the Connection: Provide standard Spring Data properties to configure the Redis connection.
Example for Local Redis Instance:
spring:
data:
redis:
# Or host.docker.internal if the Gateway is running inside a container and Redis is also in a container
host: localhost
port: 6379
Example for Remote Redis Instance (e.g., Serverless ElastiCache):
|
Note
|
The following is just an example. Instructions and exact property mappings will vary depending on the exact provider and instance type used. Refer to Spring Data Redis documentation for the full suite of possible configuration options. |
When connecting to an ElastiCache Serverless instance, it should be provisioned within the same VPC as the application clusters to allow reachability on port 6379.
Ideally, User Groups and ACLs should be utilized instead of a single shared password.
The generated passwords for each user should be stored in a secure location, such as an encrypted Spring Cloud Config Server source.
spring:
data:
redis:
host: ${REDIS_CLUSTER_URL} # e.g., the serverless endpoint URL
port: 6379
ssl:
enabled: true
# example user that can be configured with 'on ~* +@read +@connection -@dangerous'
username: gateway-svc-user
password: ${GATEWAY_SVC_REDIS_PASSWORD}
|
Note
|
In the gateways, the access token blacklisting filter comes with a pre-configured circuit breaker in case there is an infrastructure issue when communicating with Redis. This fail-open resilience pattern ensures that legitimate traffic is not blocked if the cache goes down. The properties of this circuit breaker can be customized via the appropriate |