<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>I'm working on a new SPI right now.  Here is my notebad to
      capture how things work, issues weed to consider, and problems we
      have to solve:</p>
    <p><a class="moz-txt-link-freetext" href="https://github.com/keycloak/keycloak/wiki/2.0-User-Federation-Storage-SPI">https://github.com/keycloak/keycloak/wiki/2.0-User-Federation-Storage-SPI</a><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 6/13/16 3:39 AM, Marek Posolda
      wrote:<br>
    </div>
    <blockquote cite="mid:575E6344.3000605@redhat.com" type="cite">
      <meta content="text/html; charset=windows-1252"
        http-equiv="Content-Type">
      <div class="moz-cite-prefix">We discussed some time ago how to
        ensure that UserFederationProvider lifecycle is properly tight
        to KeycloakSession <a moz-do-not-send="true"
          class="moz-txt-link-freetext"
href="http://lists.jboss.org/pipermail/keycloak-dev/2016-April/007123.html">http://lists.jboss.org/pipermail/keycloak-dev/2016-April/007123.html</a>
        . The last we discussed was to add new method on KeycloakSession
        like:<br>
        <br>
        &lt;T extends Provider&gt; T getProvider(Class&lt;T&gt; clazz,
        String id, String instanceId);<br>
        <br>
        where instanceId is the state associated with the provider (in
        case of UserFederationProvider it will be DB ID of
        UserFederationProviderModelId). That way, the
        UserFederationProviderFactory.create can load the
        UserFederationProviderModel (assumption is that RealmModel is
        available in KeycloakContext, so
        UserFederationProviderFactory.create has access to RealmModel +
        providerDatabaseId to load it from DB).<br>
        <br>
        In the thread, you can see that I've initially proposed
        something similar to your proposal, but it's a bit more complex
        though. Hopefully going "simple" way and adding just the method
        with "instanceId" String argument can solve the issue.<br>
        <br>
        Marek<br>
        <br>
        On 10/06/16 01:36, Ariel Carrera wrote:<br>
      </div>
      <blockquote
cite="mid:CAFzO_6c=RBb=Xin_G4vDcqeihqQ0x5U4q5G09TRapwCOa2RCuw@mail.gmail.com"
        type="cite">
        <div dir="ltr">
          <div>There is not problem! :)</div>
          <div>One more thing, I solved the problem of multiple
            "federation provider" instances, adding this code to the
            DefaultKeycloakSession (and the method definition in
            KeycloakSession interface):</div>
          <div>
            <div>    </div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">public
              &lt;T extends Provider&gt; void
              registerProvider(Class&lt;T&gt; clazz, Provider provider,
              String id) {<br>
                      Integer hash = clazz.hashCode() + id.hashCode();<br>
                      providers.put(hash, provider);<br>
                  }</blockquote>
            <div><br>
              And into
              MyUserFederationProviderFactory.getInstance(session,
              model) something like this:</div>
            <div><br>
            </div>
            <div>
              <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">public
                UserFederationProvider getInstance(KeycloakSession
                session, UserFederationProviderModel model){<br>
                <span class="" style="white-space:pre">                </span>UserFederationProvider
                provider = (UserFederationProvider)
                session.getProvider(UserFederationProvider.class,
                model.getId());<br>
                <span class="" style="white-space:pre">                </span>if
                (provider == null){<br>
                <span class="" style="white-space:pre">                        </span>lazyInit(session);<br>
                <span class="" style="white-space:pre">        </span>         
                      provider = new MyUserFederationProvider(session,
                model, config, ......);<br>
                <span class="" style="white-space:pre">        </span>         
                     
((KeycloakSession)session).registerProvider(UserFederationProvider.class,
                provider, model.getId());<br>
                <span class="" style="white-space:pre">                </span>};<br>
                        return provider;<br>
                    }</blockquote>
              <br>
              After a few tests and debug it seems to work... creating,
              catching, and closing provider instances as expected.</div>
            <div><br>
            </div>
            <div><br>
            </div>
            <div>
              <div>In future versions as you said, maybe would be better
                include a way to instantiate a complex object/provider
                instead of doing</div>
              <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">ProviderFactory.create(KeycloakSession
                session) <br>
                some kind of method like<br>
                ProviderFactory.create(KeycloakSession session,
                Object... obj);</blockquote>
              <div>and the appropriate method into the KeycloakSession</div>
              <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">&lt;T
                extends Provider&gt; T getProvider(Class&lt;T&gt; clazz,
                Object... obj);<br>
                &lt;T extends Provider&gt; T getProvider(Class&lt;T&gt;
                clazz, String id, Object... obj);</blockquote>
              <div><br>
              </div>
              <div>And why not a map into the keycloakSession to store
                some additional context data to share between providers
                during same request? It's only a vague idea</div>
            </div>
            <div><br>
            </div>
            <div>Regards!</div>
            <div class="gmail_extra"><br>
              <div class="gmail_quote">2016-06-09 17:14 GMT-03:00 Bill
                Burke <span dir="ltr">&lt;<a moz-do-not-send="true"
                    href="mailto:bburke@redhat.com" target="_blank">bburke@redhat.com</a>&gt;</span>:<br>
                <blockquote class="gmail_quote" style="margin:0px 0px
                  0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
                  <div bgcolor="#FFFFFF" text="#000000">
                    <p>Its gonna be awhile.  Its going to be difficult
                      to make everything both backward compatible and
                      cover all the current and future use cases we need
                      to cover.  Listen on the dev list.  I should post
                      some info soon on what the new impl will look
                      like.<br>
                    </p>
                    <div>
                      <div class="h5"> <br>
                        <div>On 6/9/16 3:57 PM, Ariel Carrera wrote:<br>
                        </div>
                        <blockquote type="cite">
                          <div dir="ltr">Yes Bill, exactly! I will
                            waiting to test it Thanks!<br>
                          </div>
                          <div class="gmail_extra"><br>
                            <div class="gmail_quote">2016-06-09 16:29
                              GMT-03:00 Bill Burke <span dir="ltr">&lt;<a
                                  moz-do-not-send="true"
                                  class="moz-txt-link-abbreviated"
                                  href="mailto:bburke@redhat.com"><a class="moz-txt-link-abbreviated" href="mailto:bburke@redhat.com">bburke@redhat.com</a></a>&gt;</span>:<br>
                              <blockquote class="gmail_quote"
                                style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><span><br>
                                  <br>
                                  On 6/9/16 2:52 PM, Ariel Carrera
                                  wrote:<br>
                                  <blockquote class="gmail_quote"
                                    style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
                                    Hi Bill, is a little expensive for
                                    me because I am creating a new
                                    entity manager to connect with a
                                    legacy database, and
                                    creating/enlisting a transaction per
                                    instance.<br>
                                    For example in a simple flow case
                                    where a user needs to click "I
                                    forgot my password" link to recover
                                    the password, there is more than
                                    nine or ten instances created to do
                                    this. It's really not a big problem
                                    but I think that is not necessary
                                    and can be implemented like others
                                    spi providers catched into the
                                    keycloak session.<br>
                                    <br>
                                  </blockquote>
                                </span> This is good feedback.  We need
                                a way to associate a provider, by name,
                                to the KeycloakSession.  Maybe we just
                                need a way to associate anything with
                                the KeycloakSession period.<span><br>
                                  <br>
                                  <blockquote class="gmail_quote"
                                    style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
                                    In my case, another difficulty is
                                    synchronization between an old
                                    authentication system and keycloak
                                    implemented on demand (there is no
                                    full/partial syncrhonization because
                                    the legacy system is still working
                                    and need to work together for a
                                    while). Also I implemented
                                    synchronization support but at this
                                    moment it not used.<br>
                                    Every time that keycloak needs to
                                    validate a user (isValid) recovered
                                    from the user storage or cache, a
                                    query to the legacy system is made.
                                    Added to this... I need to recover
                                    some attributes and roles changes
                                    produced on the legacy system.... so
                                    I decided to implement a "user
                                    federation cache" with a short term
                                    expiration to improve the
                                    performance with certain
                                    synchronization delay tolerance.<br>
                                    <br>
                                    In a few words I have: a custom User
                                    Federation Provider + on deman
                                    synchronization + a user Federation
                                    Provider Cache (my own cache SPI).<br>
                                    <br>
                                    Maybe an optional spi to obtain a
                                    custom container from infinispan
                                    could be a good choice to add to the
                                    new implementation and provide
                                    another one tool to do things with
                                    better performance.<br>
                                    <br>
                                  </blockquote>
                                </span> I think the new model might
                                solve your caching needs.  There will be
                                no importing by default.  This means no
                                synching, etc.  Keycloak will only store
                                metadata that your user store can't
                                provide.  User Federation Providers will
                                work just as the default Keycloak user
                                store and user cache.<br>
                                <br>
                              </blockquote>
                            </div>
                            <br>
                            <br clear="all">
                            <div><br>
                            </div>
                            -- <br>
                            <div data-smartmail="gmail_signature">Tatú</div>
                          </div>
                        </blockquote>
                        <br>
                      </div>
                    </div>
                  </div>
                </blockquote>
              </div>
              <br>
              <br clear="all">
              <div><br>
              </div>
              -- <br>
              <div class="gmail_signature"
                data-smartmail="gmail_signature">Tatú</div>
            </div>
          </div>
        </div>
        <br>
        <fieldset class="mimeAttachmentHeader"></fieldset>
        <br>
        <pre wrap="">_______________________________________________
keycloak-dev mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
      </blockquote>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
keycloak-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
    </blockquote>
    <br>
  </body>
</html>