In the previous article we got familiar with the common configuration of Keycloak, today we will do an analysis of the execution flow of Keycloak adapted to Spring Security and briefly understand some of its customized Spring Security filters.
Execution flow of /admin/foo
In the Spring Boot application adapted with Keycloak and Spring Security, I wrote a /admin/foo
interface and configured the permissions for this interface as follows.
This is a typical Spring Security configuration where a user with the base_user
role has access to /admin/**
. What you need to understand here is that the so-called user
and base_user
roles are currently managed by the Keycloak platform, and our application can currently only control the access policy to resources. In order to see the flow of execution I turned on all log printing, and when I access /admin/foo
I go through the following filters.
|
|
In addition to the regular built-in filters of Spring Security several filters of the Keycloak adapter have been added here, combine them with the execution flow to get to know them.
KeycloakPreAuthActionsFilter
The purpose of this filter is to expose a Keycloak adapter object PreAuthActionsHandler
to Spring Security. And the role of this adapter is to intercept the processing of a Keycloak’s functional request handling interfaces, which are built in with specific suffixes.
You can generally ignore this filter without going deep into the bottom.
KeycloakAuthenticationEntryPoint
KeycloakAuthenticationEntryPoint
is an implementation ofAuthenticationEntryPoint
configured inKeycloakWebSecurityConfigurerAdapter
.
When the request is filtered by the FilterSecurityInterceptor
, the current user is found to be an anonymous
and does not meet the access control requirements of /admin/foo
and an AccessDeniedException
is thrown. This is passed to KeycloakAuthenticationEntryPoint
via ExceptionTranslationFilter
to handle the 401
exception.
|
|
It implements two policies.
- When the request is a login request
/sso/login
orBearerOnly
(these properties were partly covered in the previous article) it returns a401
response with aWWW-Authenticate
header. - In all other cases, a OIDC authentication authorization request is jumped.
|
|
Our interface obviously takes the above approach, so it’s obvious that we need to jump to the login page. At this point we need to see if /admin/foo
is cached, because after login we have to perform the logic of /admin/foo
. If Spring Security does not store the Session or Cookie, it will cache /admin/foo
to the Cookie and then redirect to the Keycloak authorization page:
|
|
KeycloakAuthenticationProcessingFilter
The above is a typical Authorization Code Flow pattern. When an account password is entered to agree to authorization, the authorization server requests a callback link with code
and state
(in this case /sso/login
). The interceptor for /sso/login
is the KeycloakAuthenticationProcessingFilter
. This interface does not only handle logins, but also intercepts any authorization header Authorization
, access_token
, or Keycloak Cookie
.
In this filter and the familiar UsernamePasswordAuthenticationFilter
are inherited from AbstractAuthenticationProcessingFilter
in fact, the general process is very similar, except that the Keycloak authentication authorization API is used. If the authentication authorization is successful, the /admin/foo
interface is retrieved from the Session and jumped. The entire simple Keycloak authentication authorization process is complete.
KeycloakSecurityContextRequestFilter
This filter has a single function, it is used to determine if it is RefreshableKeycloakSecurityContext
, refreshable security context, if it is, put a RefreshableKeycloakSecurityContext
in the ServletRequest
object, the subsequent other filters will do something based on this marker.
KeycloakAuthenticatedActionsFilter
This filter is used to catch the RefreshableKeycloakSecurityContext
placed by the KeycloakSecurityContextRequestFilter
in the request object ServletRequest
. The core is this.
|
|
Returning true
here blocks it from going further. It is mainly based on the policy provided by Keycloak to determine whether authorization has been granted, and the logic looks quite complicated.
Based on the principle of space, we will introduce Keycloak’s filters in detail afterwards, but today we know roughly what they are used for.
Supplementary
If you want to figure out the flow of any framework, the best way is to extract some key points from the log printing. I took apart the annotation that opens the Keycloak adapter to open the Spring Security logs.
To see more logs, adjust the logs for Spring Boot’s org
related packages to debug
as well.
Then the code running process will be very clear in the console Console, which greatly facilitated me to figure out the running process of Keycloak. Keycloak’s process is simple to understand, it feels very bland and boring, and most of them do not need customization. I personally think that the focus is actually not here, how to customize Keycloak’s user management, role management and a series of management APIs according to the business is the key to using it well. Do not go away, the follow-up will be combined with some scenarios to modify keycloak.
Reference
https://felord.cn/keycloak5.html