<div dir="ltr"><div>As Stian said - it is really easy to do as a custom required action:</div><div><br></div><div>0) Define a custom RequiredActionFactory that returns your custom RequiredActionProvider</div><div><br></div><div>package de.tdlabs.keycloak.authentication;</div><div><br></div><div>import org.keycloak.Config.Scope;</div><div>import org.keycloak.authentication.RequiredActionFactory;</div><div>import org.keycloak.authentication.RequiredActionProvider;</div><div>import org.keycloak.models.KeycloakSession;</div><div>import org.keycloak.models.KeycloakSessionFactory;</div><div><br></div><div>public class RecordFirstLoginRequiredActionFactory implements RequiredActionFactory {</div><div><br></div><div>    @Override</div><div>    public RequiredActionProvider create(KeycloakSession session) {</div><div>        return new RecordFirstLoginRequiredActionProvider();</div><div>    }</div><div><br></div><div>    @Override</div><div>    public void init(Scope config) {</div><div>        // NOOP</div><div>    }</div><div><br></div><div>    @Override</div><div>    public void postInit(KeycloakSessionFactory factory) {</div><div>        // NOOP</div><div>    }</div><div><br></div><div>    @Override</div><div>    public void close() {</div><div>        // NOOP</div><div>    }</div><div><br></div><div>    @Override</div><div>    public String getId() {</div><div>        return &quot;record-first-login-action&quot;;</div><div>    }</div><div><br></div><div>    @Override</div><div>    public String getDisplayText() {</div><div>        return &quot;Record First Login Action&quot;;</div><div>    }</div><div>}</div><div><br></div><div>package de.tdlabs.keycloak.authentication;</div><div><br></div><div>import static java.time.LocalDateTime.now;</div><div>import static java.util.Arrays.asList;</div><div><br></div><div>import java.util.List;</div><div><br></div><div>import org.keycloak.authentication.RequiredActionContext;</div><div>import org.keycloak.authentication.RequiredActionProvider;</div><div>import org.keycloak.models.UserModel;</div><div><br></div><div>public class RecordFirstLoginRequiredActionProvider implements RequiredActionProvider {</div><div><br></div><div>    @Override</div><div>    public void close() {</div><div>        // NOOP</div><div>    }</div><div><br></div><div>    @Override</div><div>    public void evaluateTriggers(RequiredActionContext context) {</div><div><br></div><div>        UserModel user = context.getUser();</div><div><br></div><div>        List&lt;String&gt; list = user.getAttribute(&quot;login.first-login-date&quot;);</div><div><br></div><div>        if (list == null || list.isEmpty()) {</div><div>            user.setAttribute(&quot;login.first-login-date&quot;, asList(now().toString()));</div><div>        }</div><div>    }</div><div><br></div><div>    @Override</div><div>    public void requiredActionChallenge(RequiredActionContext context) {</div><div>        // NOOP</div><div>    }</div><div><br></div><div>    @Override</div><div>    public void processAction(RequiredActionContext context) {</div><div>        context.success();</div><div>    }</div><div>}</div><div><br></div><div>Create a service loader file under:</div><div>META-INF/services/org.keycloak.authentication.RequiredActionFactory</div><div><br></div><div>with:</div><div>de.tdlabs.keycloak.authentication.RecordFirstLoginRequiredActionFactory</div><div><br></div><div>1) Build the jar or add the project classpath to the keycloak-server.json via providers:</div><div>e.g.:</div><div><br></div><div>{</div><div>    &quot;providers&quot;: [</div><div>        &quot;classpath:${jboss.server.config.dir}/providers/*&quot;,</div><div>        &quot;classpath:${de.tdlabs.keycloak-rest-federation-provider.home}/target/classes/&quot;,</div><div>        &quot;classpath:${de.tdlabs.keycloak-event-listener.home}/target/classes/&quot;,</div><div>        &quot;classpath:${de.tdlabs.keycloak-required-actions.home}/target/classes/&quot;</div><div>    ],</div><div>    ...</div><div>}</div><div><br></div><div>2) Register the required action in keycloak</div><div><br></div><div>2.1) Configure Custom Required Action:</div><div>Realm -&gt; Authentication -&gt; Required Actions -&gt; Register -&gt; &quot;Record First Login Action&quot; -&gt; mark as &quot;Default Action&quot;</div><div><br></div><div>3) Test the required action</div><div>2.2) Login once</div><div>2.3) Users -&gt; your user -&gt; Attributes -&gt; the &#39;login.first-login-date&#39; attribute should be there</div><div><br></div><div>Cheers,</div><div>Thomas</div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-01-20 12:35 GMT+01:00 Stian Thorgersen <span dir="ltr">&lt;<a href="mailto:sthorger@redhat.com" target="_blank">sthorger@redhat.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Not built-in, but you can create a required action that does that and enable it as a default action. Take a look at <a href="http://keycloak.github.io/docs/userguide/keycloak-server/html/auth_spi.html" target="_blank">http://keycloak.github.io/docs/userguide/keycloak-server/html/auth_spi.html</a></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On 20 January 2016 at 11:58, LIEVRE Olivier <span dir="ltr">&lt;<a href="mailto:olivier.lievre@altran.com" target="_blank">olivier.lievre@altran.com</a>&gt;</span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">





<div lang="FR" link="blue" vlink="purple">
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;color:#1f497d">Hello,<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;color:#1f497d">Is there a possibility to store in user attributes the timestamp of first user login to keycloak ?<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;color:#1f497d">KR,<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;color:#1f497d">Olivier<u></u><u></u></span></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</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>
<br>_______________________________________________<br>
keycloak-user mailing list<br>
<a href="mailto:keycloak-user@lists.jboss.org">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>