<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">On 21/09/15 12:33, Stian Thorgersen
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAJgngAd+J8Q6C=Wi3Kz9JUvRnzfjeqtZUR5+ogbeOZTOsfQ38g@mail.gmail.com"
      type="cite">
      <div dir="ltr"><br>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On 21 September 2015 at 12:06, 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:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">I've
              sent the PR . Right now it works like this:<br>
              <br>
              - ClientModel has flag "offlineTokensEnabled" . It's
              possible to<br>
              retrieve offline tokens just if flag is enabled<br>
              <br>
              - Offline token is classic refresh token with 2
              differences. It has type<br>
              "OFFLINE" when normal refresh token has type "REFRESH" .
              And for offline<br>
              token, the expiration value is 0, so it never expires.<br>
              <br>
              - Offline token is generated by auth-server when client
              sends<br>
              "scope=offline_access" . It's supported for classic
              browser flow, but<br>
              also for Direct Grant flow or Service account flow.<br>
              <br>
              - I've added OfflineClientSessionModel and
              OfflineUserSessionModel with<br>
              CRUD methods on UserModel. So when new offline token is
              generated by<br>
              Keycloak, some info about current UserSession and
              ClientSession is<br>
              persisted on UserModel. This means that offline token can
              be used to<br>
              create new access token even if "normal" UserSession and
              ClientSession<br>
              are already invalid or logged out.<br>
              <br>
              - When refreshing access token with offline token, the
              auth-server won't<br>
              send back another refresh token. It will send just
              accessToken +<br>
              IDToken. This is to avoid writes to user database for each
              token refresh.<br>
              <br>
              - In account management applications tab, there is new
              table column<br>
              "Additional grants" where is shown if client has offline
              token for user.<br>
              The click on "Revoke" button will remove offline tokens
              and granted<br>
              consents as well - no separate actions for revoke consents
              and offline<br>
              tokens.<br>
              <br>
              <br>
              Still TODO:<br>
              - Properly handle consents (see "Questions" below)<br>
              <br>
              - More tests, example, export/import , docs<br>
              <br>
              - More things/refactoring based on your feedback<br>
              <br>
              <br>
              Questions:<br>
              - The specs mentions that consent should be displayed when
              offline token<br>
              is requested. See<br>
              <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>
              Right now, I am not doing that. So when Client has
              "isConsentRequired"<br>
              as false, the consent screen is not displayed. Now we also
              don't have<br>
              support for "prompt=consent" (not sure if we need this) .
              Is it ok to<br>
              keep it like this?<br>
            </blockquote>
            <div><br>
            </div>
            <div>Wording is "<span
style="color:rgb(0,0,0);font-family:verdana,charcoal,helvetica,arial,sans-serif">MUST
                explicitly receive or have consent" - as the client does
                not require consent (</span>isConsentRequired=false)<span
style="color:rgb(0,0,0);font-family:verdana,charcoal,helvetica,arial,sans-serif"> that
                implies the client already has been given consent by the
                admin.</span></div>
            <div> </div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
              - I am thinking about adding new builtin client role
              "offline_access",<br>
              which will be created for client when admin enables
              "offline tokens"<br>
              switch. It will be used also as default role. This will
              allow that just<br>
              some users are allowed to obtain offline-token (those
              which have this<br>
              role). The role will be also displayed on consent screen
              for the<br>
              clients, which needs consent.<br>
              But that raises another question. IMO it will be good if
              role is<br>
              requested and displayed on consent screen just if offline
              token is<br>
              requested, but not when classic refresh token is
              requested.</blockquote>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
              Hence I was thinking about adding the flag
              "scopeParamMode" to<br>
              RoleModel. The value true means that role will be
              requested and used in<br>
              accessToken/refreshToken just if scope parameter contains
              it's value.<br>
              This will be the setup for "offline_access" role, so it's
              used just for<br>
              the offline token requests. Another thing is format of
              scope parameter<br>
              with respect to realm roles and application roles. We can
              use "//" as<br>
              delimiter, so realm role will have just "my-role" but
              client role will<br>
              have "my-client//my-role" . The disadvantage is that for
              requesting<br>
              offline_access you will then need to use scope like:<br>
              "scope=customer-portal//offline_access" as it's client
              role.<br>
            </blockquote>
            <div><br>
            </div>
            <div>Spec says scope should be "offline_access", so if we
              use a different name for it won't comply with the spec.</div>
            <div><br>
            </div>
            <div>Shouldn't the offline_access role be a realm role
              rather than a role per-client?</div>
          </div>
        </div>
      </div>
    </blockquote>
    The issue with realm role is, that user needs to confirm
    offline_access consent just once per all clients, which doesn't look
    correct to me. <br>
    <br>
    For example there would be 2 clients "foo" and "bar":<br>
    - User john wants offline_access for client "foo"<br>
    - Consent screen is displayed with "offline_access" role and he
    confirms it<br>
    - Then user john wants offline_access for client "bar"<br>
    - There is no "offline_access" anymore on consent screen because
    john already has consent for realm role "offline_access" . <br>
    <br>
    <br>
    IMO it should be "offline_access" displayed again as it's different
    client. Also logically offline_access is granted per client, so the
    text on the grant screen is:<br>
    <br>
    "has Offline Access in foo"<br>
    <br>
    or <br>
    <br>
    "has Offline Access in bar"<br>
    <br>
    which will be with client roles.<br>
    <br>
    <blockquote
cite="mid:CAJgngAd+J8Q6C=Wi3Kz9JUvRnzfjeqtZUR5+ogbeOZTOsfQ38g@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <div><br>
            </div>
            <div>Another thing to consider is that we'll be moving to
              role namespaces instead of realm/client roles soon. In
              that case we might want a OpenID Connect namespace that
              can hold these scopes. So role could be
              "openid/offline_access".</div>
          </div>
        </div>
      </div>
    </blockquote>
    Ok. Maybe for now I won't do anything tricky but just limit the
    scope param support to client roles of current client. So scope
    "offline_access" is "offline_access" role of current client. We can
    improve it later once we add role namespaces support. WDYT? <br>
    <br>
    Marek<br>
    <blockquote
cite="mid:CAJgngAd+J8Q6C=Wi3Kz9JUvRnzfjeqtZUR5+ogbeOZTOsfQ38g@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <div> </div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
              WDYT? Any better idea?<br>
              <br>
              Marek<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>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>