<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix"><i>@Christian Beikov</i>: Thanks for
      the hint on integrators!<br>
      <br>
      I was afraid I could not use integrators when working with the JPA
      'route', but I found a way. There is a property <tt>EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER
      </tt>that you can use to supply custom integrators. This even
      works with the original 'pure' JPA call: <tt>Persistence.createEntityManagerFactory</tt>.
      In the integrator you can add annotated classes to the Hibernate
      Configuration. So the solution is still Hibernate only of course.<br>
      <br>
      The only downside is that there is less validation on the supplied
      classes, they are just added to the config directly. For instance
      I tested with adding Object.class as annotated class. This doesn't
      raise an exception and seems to be silently ignored by Hibernate.
      Not sure if it might result in problems during runtime though.
      Either way, normally this should be fine and with a little extra
      documentation on how these extra classes are handled I think using
      an integrator is the least intrusive thus best way to go. Agreed?<br>
      <br>
      Ok, List as collection type is fine too, indeed easier to use.
      Conceptually I like Set, because List seems to imply there is some
      kind of ordering involved which in this case there isn't. But
      that's just a minor matter of taste.<br>
      <br>
      By exotic&nbsp;<tt>ProviderLoader(Factory)</tt> I meant the <tt>org.keycloak.provider.ProviderLoader(Factory)</tt>
      that you can use to load <tt>Provider(Factory)</tt>'s from other
      locations than a file system based classpath. If that were to be a
      'read once' kindof location (like some stream) there could be a
      problem. But with the integrator solution that shouldn't matter
      anymore, since it's just the Class object that we need.<br>
      <br>
      As for Hibernate 4/5, I'll try to make a solution that works for
      both Hibernate 4 and 5 in the same way. If that's not possible, I
      guess we could have separate code paths for 4 and 5, depending on
      the runtime version. I hope there is an easy way of figuring this
      out, maybe some static Hibernate class holding a version or so. A
      quick Google returns some useful results, so I'm sure we'll get
      that sorted if needed.<br>
      <br>
      End of the month is probably too soon indeed, so let's aim for
      1.8. Should I (or someone else) create one (or several) JIRA
      tickets for this?<br>
      <br>
      <br>
      On 12/11/15 14:32, Stian Thorgersen wrote:<br>
    </div>
    <blockquote cite="mid:CAJgngAedJ80KUqg3qh5grWBw1MLANwy52ctXmfM0N2-5HO5tnA@mail.gmail.com" type="cite">
      <div dir="ltr"><br>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On 12 November 2015 at 13:58, Erik
            Mulder <span dir="ltr">&lt;<a moz-do-not-send="true" href="mailto:erik.mulder@docdatapayments.com" target="_blank">erik.mulder@docdatapayments.com</a>&gt;</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"><span class="">
                  <div>On 11/11/15 13:54, Stian Thorgersen wrote:<br>
                  </div>
                  <blockquote 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>
                </span> 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?</div>
            </blockquote>
            <div><br>
            </div>
            <div>We do a release every ~6 weeks. It's already a bit late
              for 1.7 (it's due end of the month) so would have to aim
              for 1.8 in either case (early January).</div>
            <div>&nbsp;</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"><span class=""><br>
                  <br>
                  <blockquote 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>
                </span> 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>
                <span class=""> <br>
                  <blockquote type="cite">
                    <div dir="ltr">
                      <div>*&nbsp;JpaEntityProvider should have a single
                        method &quot;Class&lt;?&gt; getEntities&quot;</div>
                    </div>
                  </blockquote>
                  <br>
                </span> 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&lt;Class&lt;?&gt;&gt;</tt>
                or <tt>Set&lt;Class&lt;?&gt;&gt;</tt> depending on what
                is most consistent with the rest of the system. Do you
                have a preference?</div>
            </blockquote>
            <div><br>
            </div>
            <div>Yup - List would be fine, that's what we tend to use as
              it's nicer to use than collection or set.</div>
            <div>&nbsp;</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"><span class=""><br>
                  <br>
                  <blockquote type="cite">
                    <div dir="ltr">
                      <div>* Implement&nbsp;<span>org.hibernate.boot.registry.classloading.spi.</span>ClassLoaderService

                        - looks like this can just return null for
                        everything except&nbsp;classForName where it would
                        return the classes returned by the
                        JpaEntityProvider implementations</div>
                    </div>
                  </blockquote>
                  <br>
                </span> 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>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Sounds OK, but not sure what you mean about
              exotic&nbsp;ProviderLoader(Factory) is that a Hibernate thing?</div>
            <div>&nbsp;</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"> <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.</div>
            </blockquote>
            <div><br>
            </div>
            <div>We are soon moving to WildFly 10 which includes
              Hibernate 5, but we still need to support EAP 6.4 which
              includes Hibernate 4. At some point next year we will drop
              support for EAP 6.4 and move on to EAP 7.</div>
            <div><br>
            </div>
            <div>We either have to support both Hibernate 4 and 5 for a
              while, or we make it use the old approach on Hibernate 4
              (so now custom entity class support on EAP 6.4) and the
              new approach on Hibernate 5. That would probably require
              some magic reflection code though.</div>
            <div>&nbsp;</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 class="h5"><br>
                    <br>
                    <br>
                    <blockquote 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">&lt;<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>&gt;</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>&gt; 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
                                    &quot;deployment.keycloak-server.war:main&quot;
                                    from Service Module Loader<br>
                                    2. ModuleClassLoader for Module
                                    &quot;org.hibernate:main&quot; 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&lt;ParsedPersistenceXmlDescriptor&gt;

                                      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(&quot;org.keycloak.models.jpa.entities.UserMerchantEntity&quot;,</tt><tt>
&quot;org.keycloak.models.jpa.entities.MerchantEntity&quot;);</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">&lt;<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>&gt;</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>&nbsp;</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">&lt;<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>&gt;</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>&nbsp;</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>&nbsp;</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>
                                                          &gt; Custom
                                                          mappers should
                                                          be possible.&nbsp;
                                                          I didn't
                                                          document it as
                                                          I wasn't<br>
                                                          &gt; sure if
                                                          we wanted to
                                                          make the SPI
                                                          public.&nbsp;
                                                          Custom mappers
                                                          should just<br>
                                                          &gt; follow
                                                          the Provider
                                                          SPI and they
                                                          will be picked
                                                          up.&nbsp; If you
                                                          see the<br>
                                                          &gt;
                                                          META-INF/services/...
                                                          file in the
                                                          resources
                                                          directory of
                                                          the &quot;services&quot;<br>
                                                          &gt; or
                                                          &quot;broker&quot;
                                                          modules you'll
                                                          see how to set
                                                          this up.<br>
                                                          &gt;<br>
                                                          &gt; As for
                                                          extending the
                                                          JPA datamodel,
                                                          what you could
                                                          do is write a
                                                          new JPA<br>
                                                          &gt;
                                                          Connections
                                                          Provider and
                                                          plug that in.&nbsp;
                                                          See
                                                          connections/jpa.&nbsp;
                                                          I'm not<br>
                                                          &gt; sure how
                                                          you would
                                                          handle the
                                                          liquibase db
                                                          migration.<br>
                                                          &gt;<br>
                                                          &gt; On
                                                          11/4/2015 6:03
                                                          AM, Erik
                                                          Mulder wrote:<br>
                                                          &gt;&gt; Hi
                                                          everybody,<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Quick
                                                          intro: I’m
                                                          part of a
                                                          development
                                                          team in The
                                                          Netherlands
                                                          that is<br>
                                                          &gt;&gt;
                                                          building a
                                                          company-wide
                                                          SSO solution.
                                                          We’ve chosen
                                                          KeyCloak to
                                                          realize<br>
                                                          &gt;&gt; this
                                                          and will use
                                                          OpenID Connect
                                                          to secure our
                                                          REST services.
                                                          It’s a<br>
                                                          &gt;&gt; great
                                                          product and
                                                          seems to be
                                                          the only one
                                                          having both
                                                          support for
                                                          all<br>
                                                          &gt;&gt; kinds
                                                          of security
                                                          standards and
                                                          a model and
                                                          GUI for users
                                                          and roles.<br>
                                                          &gt;&gt;
                                                          Thanks for
                                                          creating it! J<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; (if
                                                          this should be
                                                          asked instead
                                                          on the users
                                                          mailing list,
                                                          please<br>
                                                          &gt;&gt;
                                                          correct me and
                                                          I’ll post it
                                                          there)<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; So
                                                          far, so good,
                                                          but we have
                                                          some extra
                                                          requirements
                                                          that do not
                                                          fit<br>
                                                          &gt;&gt; into
                                                          the base
                                                          KeyCloak data
                                                          model. See
                                                          below for
                                                          details if
                                                          you’re<br>
                                                          &gt;&gt;
                                                          interested. My
                                                          question is:
                                                          what is the
                                                          preferred way
                                                          / best
                                                          practice to<br>
                                                          &gt;&gt;
                                                          extend the
                                                          functionality
                                                          of KeyCloak
                                                          while keeping
                                                          the impact on
                                                          the<br>
                                                          &gt;&gt;
                                                          original
                                                          sources to a
                                                          minimum? Of
                                                          course we
                                                          could just
                                                          fork the most<br>
                                                          &gt;&gt;
                                                          recent version
                                                          and start
                                                          hacking away,
                                                          but we’d like
                                                          to be able to<br>
                                                          &gt;&gt;
                                                          upgrade to
                                                          newer versions
                                                          of KeyCloak
                                                          without too
                                                          much hassle.<br>
                                                          &gt;&gt;
                                                          Possibilities
                                                          that we’ve
                                                          come up with
                                                          so far:<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          1.Create
                                                          completely
                                                          separate
                                                          modules that
                                                          will extend
                                                          the
                                                          functionality<br>
                                                          &gt;&gt; the
                                                          way we need.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          2.Fork on
                                                          Github, apply
                                                          custom
                                                          changes, and
                                                          try to merge
                                                          in updates
                                                          from<br>
                                                          &gt;&gt; the
                                                          master /
                                                          release
                                                          branches /
                                                          tags<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          3.Apply custom
                                                          changes on
                                                          KeyCloak
                                                          artifacts
                                                          using a Maven
                                                          plugin, such<br>
                                                          &gt;&gt; as
                                                          Truezip<br>
                                                          &gt;&gt; (<a moz-do-not-send="true" href="http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html" 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>
                                                          &gt;&gt;
                                                          manipulate zip
                                                          files by
                                                          adding/removing/replacing
                                                          or Shade<br>
                                                          &gt;&gt; (<a moz-do-not-send="true" href="http://maven.apache.org/plugins/maven-shade-plugin/" 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>
                                                          &gt;&gt; jars
                                                          to 1
                                                          'uber-jar'
                                                          containing the
                                                          contents of
                                                          both and when<br>
                                                          &gt;&gt;
                                                          overlapping
                                                          decide on
                                                          conflicts
                                                          through
                                                          configuration.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Of
                                                          course number
                                                          1 is
                                                          preferred, but
                                                          I do not see
                                                          how to add
                                                          custom<br>
                                                          &gt;&gt;
                                                          mappers or JPA
                                                          entities
                                                          without making
                                                          changes in the
                                                          original
                                                          module<br>
                                                          &gt;&gt;
                                                          files. The
                                                          other options
                                                          seem like
                                                          valid
                                                          alternatives,
                                                          but maybe
                                                          there<br>
                                                          &gt;&gt; is
                                                          better /
                                                          standard way
                                                          to do this. So
                                                          any help /
                                                          insight /
                                                          shared<br>
                                                          &gt;&gt;
                                                          experience on
                                                          this is much
                                                          appreciated,
                                                          thanks!<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Kind
                                                          regards,<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Erik
                                                          Mulder<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          Senior
                                                          Software
                                                          Engineer<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          Docdata
                                                          Payments – NL<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; P.S.
                                                          Details on why
                                                          we want to
                                                          extend the
                                                          KeyCloak data
                                                          model: (any<br>
                                                          &gt;&gt;
                                                          feedback on
                                                          the contents
                                                          of this P.S.
                                                          is also
                                                          welcome!)<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt; Our
                                                          clients are
                                                          merchants that
                                                          have several
                                                          webshops. We
                                                          manage their<br>
                                                          &gt;&gt;
                                                          online
                                                          payments
                                                          (shopping cart
                                                          checkout). We
                                                          want to be
                                                          able to let a<br>
                                                          &gt;&gt;
                                                          merchant
                                                          manage their
                                                          own users and
                                                          let a user
                                                          have different
                                                          roles for<br>
                                                          &gt;&gt;
                                                          different
                                                          webshops
                                                          within the
                                                          same merchant.
                                                          The overall
                                                          possible roles<br>
                                                          &gt;&gt; are
                                                          fixed though,
                                                          no specific
                                                          roles per
                                                          merchant. We
                                                          could create a<br>
                                                          &gt;&gt;
                                                          separate realm
                                                          for every
                                                          merchant, but
                                                          then we need
                                                          to duplicate
                                                          all<br>
                                                          &gt;&gt; roles
                                                          every time.
                                                          Furthermore,
                                                          in KeyCloak
                                                          there is no
                                                          concept of a
                                                          role<br>
                                                          &gt;&gt;
                                                          within a
                                                          certain
                                                          context. This
                                                          is very
                                                          understandable,
                                                          since every<br>
                                                          &gt;&gt;
                                                          situation has
                                                          it’s own
                                                          requirements.
                                                          We did a proof
                                                          of concept by
                                                          adding<br>
                                                          &gt;&gt;
                                                          tables and
                                                          entities for
                                                          Merchant,
                                                          UserMerchant,
                                                          UserMerchantRole
                                                          etc.<br>
                                                          &gt;&gt; and
                                                          adding a
                                                          custom mapper
                                                          that can put
                                                          this
                                                          information on
                                                          the Access<br>
                                                          &gt;&gt;
                                                          token. Worked
                                                          like a charm!
                                                          But it does
                                                          need some
                                                          changes in the<br>
                                                          &gt;&gt;
                                                          KeyCloak
                                                          modules and
                                                          sources to
                                                          work, hence
                                                          the question
                                                          above.<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;<br>
                                                          &gt;&gt;
                                                          _______________________________________________<br>
                                                          &gt;&gt;
                                                          keycloak-dev
                                                          mailing list<br>
                                                          &gt;&gt; <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>
                                                          &gt;&gt; <a moz-do-not-send="true" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" 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>
                                                          &gt;&gt;<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>
                                                          </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>
                  </div>
                </div>
              </div>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>