[keycloak-dev] Keycloak servlet filter adapter on OSGi, first impressions
Dmitry Telegin
dt at acutus.pro
Wed Jul 11 13:29:31 EDT 2018
Hi,
We are working on integrating Apache Sling with Keycloak (see my
posting from June 12). It was suggested that we'd stick to servlet
filter adapter as the most generic one (unlike Keycloak OSGi
adapter which is more of a JBoss Fuse adapter).
The first step was to convert keycloak-servlet-filter-adapter and
required keycloak-servlet-adapter-spi to OSGi bundles. This went OK,
I've just added OSGi bundling to the respective POMs. However there
were two major issues when deploying and running the code:
1. Bogus dependency on org.apache.http.*
Several Keycloak modules the adapter depends on, namely keycloak-authz-client and keycloak-adapter-core, declare bogus "Import-Package: org.apache.http.*;version=4.5.2" dependency.
This comes from the following lines in the POM:
<keycloak.osgi.import>
org.keycloak.*;version="${project.version}",
org.apache.http.*;version=${apache.httpcomponents.version},
...
</keycloak.osgi.import>
org.apache.http.* is exported by org.apache.httpcomponents:httpcore-osgi, which uses its own versioning scheme (4.4.9 is the latest version ATM). Thus, deploying the bundle to OSGi runtime fails due to unsatisfied dependency.
Later, I've discovered there's keycloak-osgi-thirdparty bundle that provides required dependencies (however, they don't become less bogus because of that).
I'm OK with this workaround, but generally speaking, is keycloak-osgi-thirdparty still needed?
I've got an impression it was created at a time when not every dependency was available as OSGi bundle.
Current version of keycloak-osgi-thirdparty contains merged httpclient and httpcore, which are available as org.apache.httpcomponents:httpclient-osgi and org.apache.httpcomponents:httpcore-osgi, respectively.
So to me it seems like a candidate for deprecation and removal. If so, the bogus dependency issue, obviously, should be tackled with first.
2. Split package org.keycloak.adapters.servlet
> In standard Java programming, packages are generally treated as
> split; the Java class path approach merges all packages from
> different JAR files on the class path into one big soup. This is
> anathema to OSGi’s modularization model, where packages are treated
> as atomic (that is, they can’t be split).
http://web.ist.utl.pt/ist162500/?p=65
In Keycloak, the package org.keycloak.adapters.servlet is split between
keycloak-servlet-adapter-spi and keycloak-servlet-filter-adapter. This
leads to seemingly inexplicable NoClassDefFoundError's, when e.g.
KeycloakOIDCFilter cannot find its neighbor OIDCServletHttpFacade. The
recipe provided by the above article (create dummy bundle, prohibit
direct imports etc.) is rather cumbersome, so I've just created
org.keycloak.adapters.servlet.spi package and moved there the two
classes from keycloak-servlet-adapter-spi.
After that, I was finally able to wire Keycloak filter to a test
servlet, and it worked pretty well. There was a redirect to Keycloak's
login screen, then redirect back, and the servlet was able to obtain
valid KeycloakPrincipal with JWT token.
To sum up, I'm eager to contribute changes required to make Keycloak
servlet filter adapter a valid and working OSGi bundle. That would
include OSGi bundling for two modules and split package refactoring.
The first issue (bogus deps) IMO should require further discussion.
Let me know what you think,
Dmitry Telegin
CTO, Acutus s.r.o.
More information about the keycloak-dev
mailing list