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.