<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">On 11/11/15 13:54, Stian Thorgersen
wrote:<br>
</div>
<blockquote cite="mid:CAJgngAeE24NxmPcK_C0Yffzt0goWgOhv+6Aksujv-ri7N2bspA@mail.gmail.com" type="cite">
<div dir="ltr">Would you be interested in contributing this
feature? ATM we don't have anyone available that could work on
it. A contribution would also need to include functional tests
and documentation.</div>
</blockquote>
<br>
Yes, I'd like to contribute this feature. I'm not sure about the
timeline though. I hope to be able to do it as part of our current
project, but I might have to use my spare time as well. Is there
some kind of deadline to be included in a certain release version?<br>
<br>
<blockquote cite="mid:CAJgngAeE24NxmPcK_C0Yffzt0goWgOhv+6Aksujv-ri7N2bspA@mail.gmail.com" type="cite">
<div dir="ltr">
<div>If so I'm happy with going down the route of using the
Hibernate specific classes. The remaining issue is figuring
out how to deal with classloading.</div>
<div><br>
</div>
<div>Looks like the following should work:</div>
<div><br>
</div>
<div>* Add JpaEntitySPI, JpaEntityProviderFactory and
JpaEntityProvider</div>
</div>
</blockquote>
<br>
I've done this and it works fine, successfully providing the extra
classes to the <tt>EntityManagerFactory</tt> build process in <tt>DefaultJpaConnectionProviderFactory</tt>.
<br>
<br>
<blockquote cite="mid:CAJgngAeE24NxmPcK_C0Yffzt0goWgOhv+6Aksujv-ri7N2bspA@mail.gmail.com" type="cite">
<div dir="ltr">
<div>* JpaEntityProvider should have a single method
"Class<?> getEntities"</div>
</div>
</blockquote>
<br>
Yes, only we need some kind of collection type, so you can provide
multiple entity classes per provider. I guess you were intending
this, considering the plural name 'getEntities'. I suggest either <tt>Collection<Class<?>></tt>
or <tt>Set<Class<?>></tt> depending on what is most
consistent with the rest of the system. Do you have a preference?<br>
<br>
<blockquote cite="mid:CAJgngAeE24NxmPcK_C0Yffzt0goWgOhv+6Aksujv-ri7N2bspA@mail.gmail.com" type="cite">
<div dir="ltr">
<div>* Implement <span style="color:rgb(51,51,51);font-family:'Lucida
Grande',Geneva,Verdana,Arial,sans-serif;font-size:12px">org.hibernate.boot.registry.classloading.spi.</span>ClassLoaderService
- looks like this can just return null for everything
except classForName where it would return the classes returned
by the JpaEntityProvider implementations</div>
</div>
</blockquote>
<br>
I see no way to interfere in the creation of the <tt>ClassLoaderService</tt>.
The official way is using the <tt>BootstrapServiceRegistryBuilder</tt>,
but with the JPA / <tt>EntityManagerFactoryBuilderImpl</tt> route
this happens 'out of reach'. I did find another way that works just
as well: you can provide a 'custom' classloader to the <tt>Bootstrap.getEntityManagerFactoryBuilder</tt>.
We can define a classloader that will return the extra
JpaEntityProvider classes if requested. Only tricky part here is
that Hibernate not only calls <tt>loadClass</tt> on a classloader,
but before that also <tt>getResource</tt> to get a <tt>URL</tt>
with an <tt>InputStream</tt> to the class bytes. It uses that to
scan for annotations with Jandex. I fixed this by forwarding that
request to the <tt>ClassLoader</tt> of the <tt>JpaEntityProvider</tt>
provided class (through <tt>Class.getClassLoader()</tt>). This
works fine and shouldn't be problem for any drop in jars. I can
imagine though that if you use some exotic <tt>ProviderLoader(Factory)</tt>,
you might somehow get in trouble if the class byte[] is not
available anymore after class loading. But this is a problem with
the way Hibernate works, not with the way we extend Hibernate in
this case. So I think it's fine to have a warning about this in the
documentation, since it will probably never be a real problem. If
you consider this as a no-go, please let me know.<br>
<br>
<br>
Last question I have considers the Hibernate version of KeyCloak.
Currently it's 4.3.10, are there any plans to upgrade to 5? The code
related to classloading etc is refactored considerably in Hibernate
5. So it would be a shame to fully get it working for 4.3.10, only
to have to upgrade soon after that. I didn't look into the details
of Hibernate 5 and I think the solution we came up with should
remain more or less intact, but you never know, so that's why I ask.<br>
<br>
<br>
<blockquote cite="mid:CAJgngAeE24NxmPcK_C0Yffzt0goWgOhv+6Aksujv-ri7N2bspA@mail.gmail.com" type="cite">
<div dir="ltr">
<div>
<div class="gmail_extra">
<div class="gmail_quote">On 7 November 2015 at 23:39, Erik
Mulder <span dir="ltr"><<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<div dir="ltr"><i>On 06/11/15 14:46, Stian Thorgersen
wrote:</i><i><br>
</i><i>> We could use Hibernate directly to
boostrap as long as it can return an
EntityManager. Do you know if that's possible?</i><i><br>
</i><br>
I was a little quick to state that with Hibernate
you can add extra entity class names besides the one
in persistence.xml, since I spotted a few answers on
StackOverflow that said it could be done. But they
resolve around classpath scanning or using a Spring
managed Hibernate. Then I thought: 'if Spring can do
it, I can do it too' so I investigated the Hibernate
source code 'behind'<tt>
Persistence.createEntityManagerFactory(unitName,
properties)</tt>. After some digging it turns out
it's pretty simple to get extra class names in the
configuration. See code sample below.<br>
<br>
The only problem is that Hibernate will only find
classes that are part of the 'main' KeyCloak
application, because of the way the Wildfly module
system and ClassLoader strategy work. The debugger
showed me Hibernate has these 3 class loaders
available to look for classes:<br>
1. ModuleClassLoader for Module
"deployment.keycloak-server.war:main" from Service
Module Loader<br>
2. ModuleClassLoader for Module "org.hibernate:main"
from local module loader<br>
3. sun.misc.Launcher$AppClassLoader<br>
<br>
Number 1 has all other KeyCloak modules in it, so
the entity classes from model-jpa will be found, but
the wildfly-extensions module is missing, so
entities in classes in a jar in the providers folder
cannot be found. Now you guys obviously know a lot
more about these internals, but as currently
configured, it seems to me there is no way to let
Hibernate 'see' these extra classes, since only the
KeyCloak services module has a dependency on
wildfly-extensions.<br>
<br>
So I think it boils down to these decisions:<br>
A. Do you accept a non-pure-JPA way of building the
EntityManagerFactory that has some ties to the
Hibernate internals?<br>
B. If A is no, than we're done. If yes, then you
must find some way to get the extra configured
classes 'into' Hibernate. You could get the
wildfly-extensions module into scope of the
Hibernate classloading. There are serveral ways to
configure Hibernate classloading or you could flip
some switches / dependencies in the module
configuration. Another alternative is to create a
separate 'dropfolder' besides themes and providers
for JPA extensions, like 'models' or so and have
that one be on the Hibernate classpath. But I don't
know the exact design principles behind KeyCloak or
the Wildfly module system. So maybe you have a
better solution or maybe you conclude that this is
'not done' in terms of the architecture.<br>
<br>
Either way, I'd really appreciate some feedback on
this and some thoughts on whether this could be a
possible addition to KeyCloak in your eyes.<br>
<br>
Thanks, Erik<br>
<br>
<br>
Current JPA way. No way to 'interfere':<br>
<tt>emf =
Persistence.createEntityManagerFactory(unitName,
properties);</tt><tt><br>
</tt><br>
Alternative Hibernate only way with adding extra
entity class names:<br>
<tt>// Let Hibernate find and parse all
'persistence.xml' files found on the classpath.<br>
List<ParsedPersistenceXmlDescriptor>
persistenceUnits =
PersistenceXmlParser.locatePersistenceUnits(properties);</tt><tt><br>
</tt><tt>// Assume there is only one persistence
unit found and that is the one we need. This can
be made more robust by checking on the persistence
unit name.<br>
ParsedPersistenceXmlDescriptor
persistenceUnitDescriptor =
persistenceUnits.get(0);</tt><tt><br>
</tt><tt>// Add extra class names. These could come
from a 'JPA class name provider' SPI or something
alike.<br>
persistenceUnitDescriptor.addClasses("org.keycloak.models.jpa.entities.UserMerchantEntity",</tt><tt>
"org.keycloak.models.jpa.entities.MerchantEntity");</tt><tt><br>
</tt><tt>// Let Hibernate create an
EntityManagerFactory out of the (enriched)
persistence unit configuration.<br>
emf =
Bootstrap.getEntityManagerFactoryBuilder(persistenceUnitDescriptor,
properties).build();</tt><tt><br>
</tt><br>
<br>
<br>
<div class="gmail_extra"><br>
<div class="gmail_quote">On 6 November 2015 at
14:29, Erik Mulder <span dir="ltr"><<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:erik.mulder@docdatapayments.com">erik.mulder@docdatapayments.com</a></a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF">
<div>
<div>Thanks for pointing me explicitly to
the SPI documentation. Of course that is
exactly what I was looking for in my
original question. I don't know how I
overlooked this earlier! Probably I was
not picking it up, because of almost a
decade of developing on Spring projects,
where this type of thing works
differently. :-)<br>
<br>
I tried a quick test with a jar with one
extra ProtocolMapper configured, put it
in the providers folder and it worked
like a charm!<br>
<br>
As for the JPA: We'll probably go with
your suggestion of the separate
EntityManagerFactory. Indeed there seems
to be no way to 'programmatically
extend' the list of entity classes in
JPA besides editing or overwriting the
persistence.xml. As you probably know it
can be done in Hibernate, but I guess
KeyCloak wants to stick to a generic JPA
solution. That said, we might consider
the Hibernate specific solution for our
case, since being able to switch the JPA
provider is not a requirement for us.
And keeping the same
connection/transaction is a lot easier
in reasoning and debugging.</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>We could use Hibernate directly to boostrap
as long as it can return an EntityManager. Do
you know if that's possible?</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF">
<div>
<div>
<div>
<div><br>
<br>
<br>
On 05/11/15 10:52, Stian Thorgersen
wrote:<br>
</div>
</div>
</div>
</div>
<div>
<div>
<blockquote type="cite">
<div dir="ltr">
<div class="gmail_extra">The way to
extend Keycloak is by implementing
your own custom providers of the
many SPIs we provide. Some SPIs
are more stable (so marked as
public) and others are not (so
marked as private). If there are
things that you want to customize
that can't be done with an
existing SPI then let us know and
we may consider adding additional
SPIs.</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On 4
November 2015 at 17:16, Erik
Mulder <span dir="ltr"><<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:erik.mulder@docdatapayments.com">erik.mulder@docdatapayments.com</a></a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Thanks
for your response!<br>
<br>
Indeed we already did a proof
of concept where we added a
custom mapper<br>
the way you described (didn't
know it was 'protected'
territory :). The<br>
question is: do we have to
override the file<br>
'org.keycloak.protocol.ProtocolMapper'
for this and add the new
mapper<br>
in the original project or is
there another way where we
don't need to<br>
touch the original sources and
keep all our changes in a
separate<br>
project? And how can we do it
such that it stays easy to
upgrade to<br>
newer KeyCloak releases?<br>
</blockquote>
<div><br>
</div>
<div>Each jar has it's own
org.keycloak.protocol.ProtocolMapper.
Take a look at the docs (<a moz-do-not-send="true" href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html" target="_blank"><a class="moz-txt-link-freetext" href="http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html">http://keycloak.github.io/docs/userguide/keycloak-server/html/providers.html</a></a>)
and examples for other
provider (<a moz-do-not-send="true" href="https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory" target="_blank"><a class="moz-txt-link-freetext" href="https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory">https://github.com/keycloak/keycloak/blob/master/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory</a></a>)</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
As for JPA: it would be easier
to integrate with the existing
JPA<br>
project. Again we are
wondering whether to start
modifying original<br>
sources (like persistence.xml)
or try to 'externalize' our
changes<br>
somehow and integrate them
using existing 'hooks' in the
system or maybe<br>
merge projects during build.<br>
<br>
Maybe there is no good answer
to this and we'll always be
having some<br>
manual merge pains when
upgrading to new KeyCloak
versions. We just<br>
wanted to check if there are
preferred ways to add
functionality with<br>
the least amount of impact on
the original sources.<br>
</blockquote>
<div><br>
</div>
<div>I initially wanted the
ability to add custom entities
to the JpaConnectProvider, but
couldn't find a way to define
entities programatically with
JPA. To add your own
persistence.xml you would have
to define your own
implementation of
JpaConnectionProvider and
change what is loaded by
default
(connectionsJpa/provider
attribute in
keycloak-server.json).</div>
<div><br>
</div>
<div>Alternative, which is
cleaner, but you end up with
separate
connection/transaction, is to
create your own
EntityManagerFactory. If it's
only used by one provider (for
example a custom
UserFederationProvider)
there's no need to add a
connect provider (that's just
a way to share one
EntityManagerFactory between
multiple providers) and you
can just create it in the
MyUserFederationProviderFactory.</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div>
<div><br>
<br>
On 04/11/15 15:30, Bill
Burke wrote:<br>
> Custom mappers should
be possible. I didn't
document it as I wasn't<br>
> sure if we wanted to
make the SPI public.
Custom mappers should just<br>
> follow the Provider
SPI and they will be
picked up. If you see the<br>
> META-INF/services/...
file in the resources
directory of the
"services"<br>
> or "broker" modules
you'll see how to set this
up.<br>
><br>
> As for extending the
JPA datamodel, what you
could do is write a new
JPA<br>
> Connections Provider
and plug that in. See
connections/jpa. I'm not<br>
> sure how you would
handle the liquibase db
migration.<br>
><br>
> On 11/4/2015 6:03 AM,
Erik Mulder wrote:<br>
>> Hi everybody,<br>
>><br>
>> Quick intro: I’m
part of a development team
in The Netherlands that is<br>
>> building a
company-wide SSO solution.
We’ve chosen KeyCloak to
realize<br>
>> this and will use
OpenID Connect to secure
our REST services. It’s a<br>
>> great product and
seems to be the only one
having both support for
all<br>
>> kinds of security
standards and a model and
GUI for users and roles.<br>
>> Thanks for
creating it! J<br>
>><br>
>> (if this should
be asked instead on the
users mailing list, please<br>
>> correct me and
I’ll post it there)<br>
>><br>
>> So far, so good,
but we have some extra
requirements that do not
fit<br>
>> into the base
KeyCloak data model. See
below for details if
you’re<br>
>> interested. My
question is: what is the
preferred way / best
practice to<br>
>> extend the
functionality of KeyCloak
while keeping the impact
on the<br>
>> original sources
to a minimum? Of course we
could just fork the most<br>
>> recent version
and start hacking away,
but we’d like to be able
to<br>
>> upgrade to newer
versions of KeyCloak
without too much hassle.<br>
>> Possibilities
that we’ve come up with so
far:<br>
>><br>
>> 1.Create
completely separate
modules that will extend
the functionality<br>
>> the way we need.<br>
>><br>
>> 2.Fork on Github,
apply custom changes, and
try to merge in updates
from<br>
>> the master /
release branches / tags<br>
>><br>
>> 3.Apply custom
changes on KeyCloak
artifacts using a Maven
plugin, such<br>
>> as Truezip<br>
>> (<a moz-do-not-send="true" href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html" rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html">http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html</a></a>)
-<br>
>> manipulate zip
files by
adding/removing/replacing
or Shade<br>
>> (<a moz-do-not-send="true" href="http://maven.apache.org/plugins/maven-shade-plugin/" rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" href="http://maven.apache.org/plugins/maven-shade-plugin/">http://maven.apache.org/plugins/maven-shade-plugin/</a></a>)
- combine multiple<br>
>> jars to 1
'uber-jar' containing the
contents of both and when<br>
>> overlapping
decide on conflicts
through configuration.<br>
>><br>
>> Of course number
1 is preferred, but I do
not see how to add custom<br>
>> mappers or JPA
entities without making
changes in the original
module<br>
>> files. The other
options seem like valid
alternatives, but maybe
there<br>
>> is better /
standard way to do this.
So any help / insight /
shared<br>
>> experience on
this is much appreciated,
thanks!<br>
>><br>
>> Kind regards,<br>
>><br>
>> Erik Mulder<br>
>><br>
>> Senior Software
Engineer<br>
>><br>
>> Docdata Payments
– NL<br>
>><br>
>> P.S. Details on
why we want to extend the
KeyCloak data model: (any<br>
>> feedback on the
contents of this P.S. is
also welcome!)<br>
>><br>
>> Our clients are
merchants that have
several webshops. We
manage their<br>
>> online payments
(shopping cart checkout).
We want to be able to let
a<br>
>> merchant manage
their own users and let a
user have different roles
for<br>
>> different
webshops within the same
merchant. The overall
possible roles<br>
>> are fixed though,
no specific roles per
merchant. We could create
a<br>
>> separate realm
for every merchant, but
then we need to duplicate
all<br>
>> roles every time.
Furthermore, in KeyCloak
there is no concept of a
role<br>
>> within a certain
context. This is very
understandable, since
every<br>
>> situation has
it’s own requirements. We
did a proof of concept by
adding<br>
>> tables and
entities for Merchant,
UserMerchant,
UserMerchantRole etc.<br>
>> and adding a
custom mapper that can put
this information on the
Access<br>
>> token. Worked
like a charm! But it does
need some changes in the<br>
>> KeyCloak modules
and sources to work, hence
the question above.<br>
>><br>
>><br>
>><br>
>>
_______________________________________________<br>
>> keycloak-dev
mailing list<br>
>> <a moz-do-not-send="true" href="mailto:keycloak-dev@lists.jboss.org" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a></a><br>
>> <a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></a><br>
>><br>
<br>
<br>
_______________________________________________<br>
keycloak-dev mailing list<br>
<a moz-do-not-send="true" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br>
<a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</blockquote>
<br>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
<blockquote type="cite"> </blockquote>
<br>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</blockquote>
<br>
</body>
</html>