[keycloak-dev] creating JPA user storage provider difficult

Bill Burke bburke at redhat.com
Thu Aug 4 09:10:24 EDT 2016



On 8/4/16 4:00 AM, Marek Posolda wrote:
> On 04/08/16 01:48, Bill Burke wrote:
>> I wrote an JPA example for the new User Storage Provider SPI [1].  It
>> was very difficult to figure out how to wire in JPA.  I'm going to take
>> a guess that very very few users have actually tried to implement a
>> JPA-based User Federation Provider.  They would have run into a ton of
>> hurdles.
>>
>> * Putting just a jar within the "providers/" directory is unusable.  JPA
>> classes and other dependencies will not be visible.
>>
>> * So, you have to craft a *CORRECT* module.xml file and know exactly
>> which dependencies to bring in. [2]
>>
>> * javax.persistence.Persistence.createEntityManagerFactory() did not
>> work, so I had to call Hibernate APIs directly.  Not only that, but
>> non-simple Hibernate APIs. [3]
>>
>> * When configuring JPA I also had to know what classloader to use so
>> that persistence.xml was visible.
> In some recent release, we added JpaEntityProvider SPI. This allows to 
> register your own JPA entities with Keycloak own EntityManager . So in 
> your provider, you don't need to care about the complex stuff like 
> proprietary Hibernate API, classloader or transaction enlisting.
>

The  JpaEntityProvider SPI extends the keycloak persistence unit. Not 
very useful if you are integrating some other external RDBMs.

> We have a docs [1] and example for that [2]
>
> [1] 
> https://keycloak.gitbooks.io/server-developer-guide/content/v/2.1/topics/extensions.html
> [2] 
> https://github.com/patriot1burke/keycloak/tree/master/examples/providers/domain-extension 
>
>
> That's much easier, isn't it? Just not sure if it helps with EJB...

Easier if you don't need any other dependency defined.  What if they 
want to JAX-RS client and a specific provider from Resteasy? As I 
mentioned in a previous point, its just not as simple as including the 
modules.  Persistence.createEMF() doesn't work as the classloaders all 
seem confused.

>> * Had to use JpaKeycloakTransaction to enlist EntityManager with
>> keycloak transactions.  This means using EJBs is out of the question.
>>
>> This is unacceptable.  Keycloak is supposed to be simple and this is
>> extremely difficult.  When Keycloak was an exploded WAR you could use
>> every Java EE component type as you could just plop your extensions
>> within META-INF/lib.  Classloading was simple as it was all the same
>> classloader.
>>
>> Going forward we need to write an actual deployer for Keycloak
>> extensions that allow you to define Keycloak providers within EE jars,
>> ears, etc.  Writing an extension to Keycloak should be as easy as
>> writing a Java EE application.  Extension developers should be able to
>> leverage the entire JBoss/Wildfly platform. Minimally, we also need to
>> begin and commit/rollback a UserTransaction within a Keycloak request
>> flow so that transaction EE and Spring component layers can function.
> +1 for deployer. Maybe we can try to prototype an example, which uses 
> stuff like EJB and then see what exactly we need to add?
>
> For UserTransaction, we can maybe have the KeycloakTransaction 
> implementation, which will delegate to UserTransaction? Then people 
> can optionally enlist it in their provider if they need it :
>
> session.getTransactionManager().enlistAfterCompletion(new 
> UserTransactionWrapper());
>
> Then Keycloak will automatically take care of commit/rollback this 
> transaction at end of request.
Why wouldn't they just use UserTransaction?

Bill


More information about the keycloak-dev mailing list