I recently worked on keycloak integration in a set of Restfull API’s for OAuth2 token based authentication … and I wanted to share with you a lightweight spring-security-keycloak library I developed for managing this.
Important to note that your web application need not be necessarily developed in spring(-web) as spring security is highly pluggable in any Servlet base web application.
The security definition (routes security declarations) lies in
I still prefer using spring security namespace config’s as I prefer keeping these cross concerns apart from code.
The config defines three routes securities
/public/**non secured resources (static, helpers, … that are
accessible from a non secured web application area)
/private/**secured, accessible by Client Credentials OAuth2
grant_type tokens (generally described as Service Accounts). Remember that
these tokens are issued using only applications clientId and clientSecret.These _logged_ entities are expected
to contain _APPLICATION_ Role. This role is extracted from the `realm_access.roles` (keycloak) token claim
(remember that keycloak generates JWT tokens format)
/private/**are generally reserved when systems want to access their resources
(API to API calls for example)
/**secured accessible by users as their resources (standard Restfull resources).
Such endpoints are accessible by tokens obtained from an OAuth2 or an OpenId Connect server
using standard web flows (Authorization Code or Implicit flow) or (not recommanded) Password credentials
flowThese logged user in this scope are expected
to contain _USER_ Role. Also extracted from the
realm_access.roles(keycloak) token claim
Using the lib in your web module
- Add the project as a jar dependency
- configure the servlet in your `web.xml` as follows
- Do not forget to specify these two config parameters when starting you application
<?xml version="1.0" encoding="UTF-8"?> <web-app> <!-- Spring security config --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/token-security.xml </param-value> </context-param> </web-app>
keycloak.publicCertsUrlkeycloak public certs endpoint
keycloak.realmUrlkeycloak realm URL (as needed by the keycloak admin lib for token verification)
for example http://localhost:8080/auth/realms/myrealm
Through environment variables for example (generally preferred in cloud environments) or through standard
application.properties|yml spring config files.
Important to note that in this library, we are not using the keycloak introspection endpoint as
calling a remote http server on every received token may be rapidly an issue, especially in full API micro service
applications … loosing the benefit of the JWT format auto-signed tokens.
Sign keys retrieved from the keycloak and generated public keys objects are cached.