<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 22 September 2015 at 09:08, Marek Posolda <span dir="ltr">&lt;<a href="mailto:mposolda@redhat.com" target="_blank">mposolda@redhat.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 21/09/15 15:15, pslegr wrote:<br>
&gt;<br>
&gt;<br>
&gt; On 21.9.2015 14:27, Marek Posolda wrote:<br>
&gt;&gt; On 21/09/15 12:28, pslegr wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On 21.9.2015 12:06, Marek Posolda wrote:<br>
&gt;&gt;&gt;&gt; I&#39;ve sent the PR . Right now it works like this:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - ClientModel has flag &quot;offlineTokensEnabled&quot; . It&#39;s possible to<br>
&gt;&gt;&gt;&gt; retrieve offline tokens just if flag is enabled<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - Offline token is classic refresh token with 2 differences. It has<br>
&gt;&gt;&gt;&gt; type<br>
&gt;&gt;&gt;&gt; &quot;OFFLINE&quot; when normal refresh token has type &quot;REFRESH&quot; . And for<br>
&gt;&gt;&gt;&gt; offline<br>
&gt;&gt;&gt;&gt; token, the expiration value is 0, so it never expires.<br>
&gt;&gt;&gt; Just an idea.<br>
&gt;&gt;&gt; Have you ever thought, in terms of expiration, not only<br>
&gt;&gt;&gt; about refresh vs. never expires<br>
&gt;&gt;&gt; BUT also about defining the exact time of expiration ?<br>
&gt;&gt;&gt; for example validity for 1 Month, 1 year, 3 years ... etc.<br>
&gt;&gt;&gt; This would offer the possibility on the fly generate the so called;<br>
&gt;&gt;&gt; &quot;offline license tokens&quot;, which are<br>
&gt;&gt;&gt; then used for different lifetime periods.<br>
&gt;&gt;&gt; IMHO this might extend the usage for Keycloak into the license<br>
&gt;&gt;&gt; providers field ;)<br>
&gt;&gt; We have already some support for required action &quot;Terms &amp; Condition&quot;<br>
&gt;&gt; at the keycloak server level. AFAIK user needs to confirm &quot;Terms &amp;<br>
&gt;&gt; Conditions&quot; page when he has that required action set on him. You<br>
&gt;&gt; have also possibility to customize the content of the page.<br>
&gt;&gt;<br>
&gt;&gt;  I wonder if this required action can be used for time based licences<br>
&gt;&gt; as well? Like for example you will have possibility to configure that<br>
&gt;&gt; validity of licence is 1 year, so after 1 year will be required<br>
&gt;&gt; action added to user automatically and he will need to confirm it<br>
&gt;&gt; again during login?<br>
&gt; Well, I had more the offline licensing on my mind. In such situation<br>
&gt; you would not ever communicate with the server from client.<br>
&gt;&gt;<br>
&gt;&gt; The possibility you mentioned is about handling licence agreement at<br>
&gt;&gt; the client level by the application itself if I understand correctly?<br>
&gt;&gt; So application will save offline token and the token is valid for 3<br>
&gt;&gt; years, so application will display the licence screen when it<br>
&gt;&gt; notifies that offline token is expired. Am I understand correctly?<br>
&gt; Yes, I think you pretty much got it<br>
&gt; The thing is, once you imagine the offline license generation, then<br>
&gt; this is a once time action, at the beginning. The license provider who<br>
&gt; owns private keys makes that once and provide to the clients.<br>
&gt; The token is then verified for offline actions and once expired must<br>
&gt; be replaced by license provide again.<br>
</div></div>Interesting usecase. Looks there are more possibilities how to support this.<br>
<br>
1) We can add timeout for offline tokens (will be NEVER by default, so<br>
it will never expire).<br>
2) We can add the protocol mappers extension points for refresh tokens<br>
as well (currently we use protocol mappers just for generation of access<br>
tokens and ID tokens). This will allow even more flexibility in<br>
generating refresh/offline tokens and use different timeouts for<br>
different clients etc.<br>
3) Don&#39;t do anything directly in Keycloak, but let application handle<br>
this. When you receive offline token from Keycloak, you will save the<br>
offline token to your DB together with the time when offline token was<br>
received (you will handle the time by yourself, not from expiration<br>
field of offline token). Then your DB contains the time, so you can<br>
handle it in your application that after 3 years is token not valid<br>
anymore and the licence needs to be confirmed again.<br></blockquote><div><br></div><div>Not sure I fully understand what the use-case is around this, but it seems like what&#39;s being proposed is a complete misuse of offline tokens.</div><div><br></div><div>I&#39;m assuming by licensing you mean something along the lines of a software license where a user has paid for a 1 year license for a particular application? If so offline tokens are not the solution as something like that should work with regular tokens as well. There&#39;s also a lot of other things to consider with regards to a license. You need a mechanism to add the license in the first place (a signed token perhaps associated with the users account), a way to renew the license (pay mechanism), etc.. It&#39;s not something we&#39;ve had any demand for, nor do I really think it&#39;s something an authentication server should do.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
&gt;&gt;<br>
&gt;&gt; IMO extend the current Terms &amp; Conditions action for expiration after<br>
&gt;&gt; some time looks better to me, as you won&#39;t need to do any more coding<br>
&gt;&gt; in your application. Just set the timeout for Terms&amp;Conditions (or<br>
&gt;&gt; licence ) action at keycloak admin console.<br>
&gt;<br>
&gt; Is the &quot;Terms &amp; Conditions action&quot; something which works offline  ?<br>
</span>No. It&#39;s displayed by Keycloak server, so it requires Keycloak server to<br>
be up and running.<br>
<span class="HOEnZb"><font color="#888888"><br>
Marek<br>
</font></span><div class="HOEnZb"><div class="h5">&gt;<br>
&gt; Pavel<br>
&gt;&gt;<br>
&gt;&gt; Marek<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - Offline token is generated by auth-server when client sends<br>
&gt;&gt;&gt;&gt; &quot;scope=offline_access&quot; . It&#39;s supported for classic browser flow, but<br>
&gt;&gt;&gt;&gt; also for Direct Grant flow or Service account flow.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - I&#39;ve added OfflineClientSessionModel and OfflineUserSessionModel<br>
&gt;&gt;&gt;&gt; with<br>
&gt;&gt;&gt;&gt; CRUD methods on UserModel. So when new offline token is generated by<br>
&gt;&gt;&gt;&gt; Keycloak, some info about current UserSession and ClientSession is<br>
&gt;&gt;&gt;&gt; persisted on UserModel. This means that offline token can be used to<br>
&gt;&gt;&gt;&gt; create new access token even if &quot;normal&quot; UserSession and ClientSession<br>
&gt;&gt;&gt;&gt; are already invalid or logged out.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - When refreshing access token with offline token, the auth-server<br>
&gt;&gt;&gt;&gt; won&#39;t<br>
&gt;&gt;&gt;&gt; send back another refresh token. It will send just accessToken +<br>
&gt;&gt;&gt;&gt; IDToken. This is to avoid writes to user database for each token<br>
&gt;&gt;&gt;&gt; refresh.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - In account management applications tab, there is new table column<br>
&gt;&gt;&gt;&gt; &quot;Additional grants&quot; where is shown if client has offline token for<br>
&gt;&gt;&gt;&gt; user.<br>
&gt;&gt;&gt;&gt; The click on &quot;Revoke&quot; button will remove offline tokens and granted<br>
&gt;&gt;&gt;&gt; consents as well - no separate actions for revoke consents and offline<br>
&gt;&gt;&gt;&gt; tokens.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Still TODO:<br>
&gt;&gt;&gt;&gt; - Properly handle consents (see &quot;Questions&quot; below)<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - More tests, example, export/import , docs<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - More things/refactoring based on your feedback<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Questions:<br>
&gt;&gt;&gt;&gt; - The specs mentions that consent should be displayed when offline<br>
&gt;&gt;&gt;&gt; token<br>
&gt;&gt;&gt;&gt; is requested. See<br>
&gt;&gt;&gt;&gt; <a href="http://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess" rel="noreferrer" target="_blank">http://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess</a> .<br>
&gt;&gt;&gt;&gt; Right now, I am not doing that. So when Client has &quot;isConsentRequired&quot;<br>
&gt;&gt;&gt;&gt; as false, the consent screen is not displayed. Now we also don&#39;t have<br>
&gt;&gt;&gt;&gt; support for &quot;prompt=consent&quot; (not sure if we need this) . Is it ok to<br>
&gt;&gt;&gt;&gt; keep it like this?<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; - I am thinking about adding new builtin client role &quot;offline_access&quot;,<br>
&gt;&gt;&gt;&gt; which will be created for client when admin enables &quot;offline tokens&quot;<br>
&gt;&gt;&gt;&gt; switch. It will be used also as default role. This will allow that<br>
&gt;&gt;&gt;&gt; just<br>
&gt;&gt;&gt;&gt; some users are allowed to obtain offline-token (those which have this<br>
&gt;&gt;&gt;&gt; role). The role will be also displayed on consent screen for the<br>
&gt;&gt;&gt;&gt; clients, which needs consent.<br>
&gt;&gt;&gt;&gt; But that raises another question. IMO it will be good if role is<br>
&gt;&gt;&gt;&gt; requested and displayed on consent screen just if offline token is<br>
&gt;&gt;&gt;&gt; requested, but not when classic refresh token is requested.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Hence I was thinking about adding the flag &quot;scopeParamMode&quot; to<br>
&gt;&gt;&gt;&gt; RoleModel. The value true means that role will be requested and<br>
&gt;&gt;&gt;&gt; used in<br>
&gt;&gt;&gt;&gt; accessToken/refreshToken just if scope parameter contains it&#39;s value.<br>
&gt;&gt;&gt;&gt; This will be the setup for &quot;offline_access&quot; role, so it&#39;s used just<br>
&gt;&gt;&gt;&gt; for<br>
&gt;&gt;&gt;&gt; the offline token requests. Another thing is format of scope parameter<br>
&gt;&gt;&gt;&gt; with respect to realm roles and application roles. We can use &quot;//&quot; as<br>
&gt;&gt;&gt;&gt; delimiter, so realm role will have just &quot;my-role&quot; but client role will<br>
&gt;&gt;&gt;&gt; have &quot;my-client//my-role&quot; . The disadvantage is that for requesting<br>
&gt;&gt;&gt;&gt; offline_access you will then need to use scope like:<br>
&gt;&gt;&gt;&gt; &quot;scope=customer-portal//offline_access&quot; as it&#39;s client role.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; WDYT? Any better idea?<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Marek<br>
&gt;&gt;&gt;&gt; _______________________________________________<br>
&gt;&gt;&gt;&gt; keycloak-dev mailing list<br>
&gt;&gt;&gt;&gt; <a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
&gt;&gt;&gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
<br>
_______________________________________________<br>
keycloak-dev mailing list<br>
<a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
</div></div></blockquote></div><br></div></div>