<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>Hi !<div><br><div><div>I'm new to keycloak and i'm trying to do a custom user federation provider also. Unfortunately, i can't find to the article you are refering (keycloak-user Digest, Vol 22, Issue 18). Is there any way you could send me this article ?</div><div><br></div><div>Thanks in advance,</div><div><br></div><div>Christian</div></div><div><br><div><hr id="stopSpelling">Date: Thu, 8 Oct 2015 10:17:39 +0200<br>From: valerij.timofeev@gmail.com<br>To: stian@redhat.com<br>CC: keycloak-user@lists.jboss.org<br>Subject: Re: [keycloak-user] Best practice for database access in a keycloak custom provider?<br><br><div dir="ltr">Exactly.&nbsp;<div><br><div>Plain text passwords are unknown, so the "custom user federation provider" approach, suggested by&nbsp;<span style="color:rgb(80,0,80);font-size:12.8px;">Scott Rossillo in the keycloak-user Digest, Vol 22, Issue 18,</span>&nbsp;seems to be feasible:</div><div><div>- User federation provider searches for the user in the legacy user storage on the 1st login.&nbsp;</div><div>- If the user is found and the password legacy hash matches the value in the legacy user storage, user credential is updated in the Keycloak storage and federation link is removed then (see code snippet below).</div><div><br></div><div>My question is, what would be the best way to access legacy database from within a Keycloak custom provider?&nbsp;</div><div>JPA datasource &nbsp;for the legacy database is available on the same application server, where the Keycloak server runs (EAP 6.4.3).<br></div><div><br></div><div><br></div><div><table cellspacing="0" cellpadding="0" border="0" width="100%" style="font-family:Arial,sans-serif;font-size:1em;color:black;line-height:1.4em !important;background-color:rgb(245,245,245);"><tbody><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="color:gray;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">@Override</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">    </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">public</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">boolean</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> validCredentials(RealmModel realm, UserModel user, List&lt;UserCredentialModel&gt; input)</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">    {</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">for</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> (UserCredentialModel cred : input)</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        {</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">if</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> (cred.getType().equals(UserCredentialModel.PASSWORD))</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            {</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><br></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">                </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">return</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">this</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">.updateCredential(realm, user, cred);</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><br></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            } </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">else</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            {</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">                </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">return</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">false</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">; </span><span style="color:rgb(0,130,0);font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">// invalid cred type</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            }</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        }</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">return</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">false</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">;</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">    }</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;">&nbsp;</pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">    </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">private</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">boolean</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> updateCredential(RealmModel realm, UserModel user, UserCredentialModel cred)</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">    {</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        String password = properties.getProperty(user.getUsername());</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">if</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> (password == </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">null</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">)</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">return</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">false</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">;</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;">&nbsp;</pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        String encodedPassword = Digest.createPassword(cred.getValue());</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">boolean</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> isPasswordOK = password.equals(encodedPassword);</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">if</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> (isPasswordOK)</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        {</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            </span><span style="color:rgb(0,130,0);font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">// save password</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            session.userStorage().getUserById(user.getId(), realm).updateCredential(cred);</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            </span><span style="color:rgb(0,130,0);font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">// break the federation link</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">            session.userStorage().getUserById(user.getId(), realm).setFederationLink(</span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">null</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">);</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        }</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">        </span><span style="color:rgb(0,102,153);font-weight:bold;font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">return</span><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;"> isPasswordOK;</span></pre></td></tr><tr id="ecxsyntaxplugin_code_and_gutter"><td style="padding:0em;vertical-align:top;line-height:1.4em !important;"><pre style="padding:0px;font-size:1em;width:auto;"><span style="font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace !important;">    }</span></pre></td></tr></tbody></table><div class="ecxgmail_extra"><br><div class="ecxgmail_quote">2015-10-08 5:57 GMT+02:00 Stian Thorgersen <span dir="ltr">&lt;<a href="mailto:sthorger@redhat.com" target="_blank">sthorger@redhat.com</a>&gt;</span>:<br><blockquote class="ecxgmail_quote" style="border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex;"><div dir="ltr">Do you want to permanently import the users into the Keycloak database?<div class="ecxgmail_extra"><br><div class="ecxgmail_quote"><div><div class="h5">On 7 October 2015 at 18:37, Valerij Timofeev <span dir="ltr">&lt;<a href="mailto:valerij.timofeev@gmail.com" target="_blank">valerij.timofeev@gmail.com</a>&gt;</span> wrote:<br></div></div><blockquote class="ecxgmail_quote" style="border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex;"><div><div class="h5"><div dir="ltr"><div><div><div><div>Hi,<br><br></div>in order to import users having encrypted passwords from existing user storage <em></em>I'm implementing user federation provider based on the keycloak example <b><em>keycloak-examples-1.5.0.Final/providers/federation-provider</em></b><em>.<br></em></div>Additionally I considered hints<em> </em>provided by Scott Rossillo in the keycloak-user Digest, Vol 22, Issue 18<br></div><div>Above example works properly when retrieving users from a properties file. The next step in the implementation would be access to the database where users data is stored.<br>&nbsp;<br></div><b>My question: </b>What would be the best practice for accessing database from a custom keycloak provider?<br><br></div>Something like this?<br><br>// KeycloakSession<br>session.getProvider(JpaConnectionProvider.class, "myTS")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getEntityManager()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .createQuery("SELECT... ?<br><div><div><div><div><em><br><br></em></div><div><em><b>keycloak-server.json:</b><br>"connectionsJpa": {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "default": {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "dataSource": "java:jboss/datasources/KeycloakDS",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "databaseSchema": "update"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br></em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em><em>"myTS": {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "dataSource": "java:jboss/datasources/myTsDS"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</em>&nbsp;&nbsp;&nbsp; }<br><br></em>Thank you,<em><br></em></div><div><em><br></em>Valerij Timofeev<br>Software Engineer<br></div><div>Trusted Shops GmbH<br><br></div><div><br></div></div></div></div></div>
<br></div></div>_______________________________________________<br>
keycloak-user mailing list<br>
<a href="mailto:keycloak-user@lists.jboss.org" target="_blank">keycloak-user@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-user" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-user</a><br></blockquote></div><br></div></div>
</blockquote></div><br></div></div></div></div></div>
<br>_______________________________________________
keycloak-user mailing list
keycloak-user@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user</div></div></div>                                               </div></body>
</html>