<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <br>
    <div class="moz-cite-prefix">On 22.9.2015 09:16, Stian Thorgersen
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAJgngAdQXU96-VKEGLi50uM8GX=h1PE_FoTsZSzcWf7uteGB_Q@mail.gmail.com"
      type="cite">
      <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 moz-do-not-send="true"
                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've sent the PR . Right now it works
                  like this:<br>
                  &gt;&gt;&gt;&gt;<br>
                  &gt;&gt;&gt;&gt; - ClientModel has flag
                  "offlineTokensEnabled" . It'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; "OFFLINE" when normal refresh token
                  has type "REFRESH" . 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; "offline license tokens", 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 "Terms &amp; Condition"<br>
                  &gt;&gt; at the keycloak server level. AFAIK user
                  needs to confirm "Terms &amp;<br>
                  &gt;&gt; Conditions" 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'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's being proposed is a
              complete misuse of offline tokens.</div>
            <div><br>
            </div>
            <div>I'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'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's not
              something we've had any demand for, nor do I really think
              it's something an authentication server should do.</div>
          </div>
        </div>
      </div>
    </blockquote>
    Yes you are correct, this is a SW license related thing.<br>
    I must admit that AAA servers normally don't have such things and
    the questions is if they really should. <br>
    I can't remember seeing out there something offering complex
    solutions for online &amp; offline licensing. (I mean unpaid, being
    opensource)<br>
    Once providing an offline "permanent" tokens, this smells more the
    SW license way and that was the reasoning behind my questions ;)<br>
    I don't say this is a use-case for Keycloak directly, but you do
    have already lot's of code there, which can be reused or bent to
    work for SW licenses as well :)<br>
    cheers<br>
    Pavel<br>
    <br>
    <blockquote
cite="mid:CAJgngAdQXU96-VKEGLi50uM8GX=h1PE_FoTsZSzcWf7uteGB_Q@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <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'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 "Terms &amp; Conditions action" something
                which works offline  ?<br>
              </span>No. It'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; "scope=offline_access" . It'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'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
                  "normal" 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'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; "Additional grants" where is shown if
                  client has offline token for<br>
                  &gt;&gt;&gt;&gt; user.<br>
                  &gt;&gt;&gt;&gt; The click on "Revoke" 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
                  "Questions" 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 moz-do-not-send="true"
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 "isConsentRequired"<br>
                  &gt;&gt;&gt;&gt; as false, the consent screen is not
                  displayed. Now we also don't have<br>
                  &gt;&gt;&gt;&gt; support for "prompt=consent" (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 "offline_access",<br>
                  &gt;&gt;&gt;&gt; which will be created for client when
                  admin enables "offline tokens"<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 "scopeParamMode" 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's value.<br>
                  &gt;&gt;&gt;&gt; This will be the setup for
                  "offline_access" role, so it'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 "//" as<br>
                  &gt;&gt;&gt;&gt; delimiter, so realm role will have
                  just "my-role" but client role will<br>
                  &gt;&gt;&gt;&gt; have "my-client//my-role" . 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;
                  "scope=customer-portal//offline_access" as it'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 moz-do-not-send="true"
                    href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
                  &gt;&gt;&gt;&gt; <a moz-do-not-send="true"
                    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 moz-do-not-send="true"
                    href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
                  <a moz-do-not-send="true"
                    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>
    </blockquote>
    <br>
  </body>
</html>