<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 01/07/16 09:37, Stian Thorgersen
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAJgngAeKV1tPR61KW5963qanORXLFiUZ7KVZNDHpD9z0M5Y1GQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>I don't like option (a) as it would be very clear what
          scopes are available and what they result in. You'd have to
          search through all roles and protocol mappers to find a list
          of scopes as well as somehow manually build the picture of
          what a scope implies.</div>
        <div><br>
        </div>
        <div>A scope could affect:</div>
        <div><br>
        </div>
        <div>* Behavior - for example openid and offline_access. We can
          hard code those, but what about others and custom ones?</div>
      </div>
    </blockquote>
    For "openid", I think we can hardcode. I was thinking about adding
    SPI like ScopeParamMapper or something and drive the behaviour with
    it, however it won't work well and will require callbacks in various
    stages (ie. IDToken itself is created at some point, but whole
    AccessTokenResponse itself and control which tokens go to it is
    different point. <br>
    <br>
    For offline_access we already has that driven by realm role
    actually.<br>
    <blockquote
cite="mid:CAJgngAeKV1tPR61KW5963qanORXLFiUZ7KVZNDHpD9z0M5Y1GQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>* Roles - limit what roles are included. This is probably
          the simplest case as it's just about removing roles.</div>
      </div>
    </blockquote>
    Not sure what exactly you mean. For roles, we already have the
    "scopeParamRequired" flag, so we can both include and remove. For
    example user is member of roleA, roleB, roleC and they have:<br>
    role-a : scopeParamRequired=false<br>
    role-b : scopeParamRequired=true<br>
    role-c : scopeParamRequired=true<br>
    <br>
    and request will have "scope=role-b" then in token will be included
    both role-a and role-b . Just role-c won't be (as it requires
    scopeParamRequired but wasn't included in scopeParam). <br>
    <br>
    We currently use it for offline_access role, which is default role,
    but have scopeParamRequired, so it's included just if
    "scope=offline_acces" is used.<br>
    <blockquote
cite="mid:CAJgngAeKV1tPR61KW5963qanORXLFiUZ7KVZNDHpD9z0M5Y1GQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>* Claims - limit what claims are included in the token.
          This boils down to protocol mappers. Some protocol mappers
          would want to be included/excluded based on scope, but I can
          also see that some protocol mappers would internally look at
          scope to determine what to include.</div>
        <div>* Authorization - could also affect authorization
          separately? The token contains the scope param separately, so
          authorization policies could be written directly on scope
          rather than roles/attributes</div>
        <div><br>
        </div>
        <div>Another thing is that the consent screen (and also showing
          application access in account management console) should
          probably take about scope rather than individual roles. For
          example:</div>
        <div><br>
        </div>
        <div>* Gallery wants to view your personal details</div>
        <div>* Backup application wants to access your photos</div>
        <div><br>
        </div>
        <div>A few more points:</div>
        <div><br>
        </div>
        <div>* It should be possible to view scopes available for a
          realm directly, not by scanning through roles and protocol
          mappers</div>
        <div>* It should be possible to set a description on a scope</div>
        <div>* It should be possible to define a scope that maps to
          multiple roles</div>
        <div>* It should be possible to define a scope that maps to
          multiple protocol mappers roles</div>
        <div>* It may be useful to be able to have protocol mappers that
          behave differently depending on the scope. Complexity may
          outweigh usefulness here though.<br>
        </div>
        <div><br>
        </div>
        <div>With that in mind I don't think option (a) is great. Option
          (b) would need introducing a whole new concept.</div>
        <div><br>
        </div>
        <div>How about we use a combination of (a) and (b), by using
          composite roles? Something along the lines of:</div>
        <div><br>
        </div>
        <div>* scope maps to a role. but the role could be a composite
          role and hence expand to other roles.</div>
        <div>* Protocol mappers could require a specific role to be
          applied</div>
        <div>* We could add a page to view scopes for a realm</div>
        <div>  - This would show the corresponding role as well as
          effective roles if it's a composite role</div>
        <div>  - It would also list the protocol mappers included</div>
      </div>
    </blockquote>
    +1 to this concept and "mapping" scope param values to roles.
    However there are some things to clarify. <br>
    <br>
    - OIDC specs has definition for scopes like "phone" , "email" and
    "profile" . So we will need the roles for those. Isn't that
    confusing a bit? IMO our RoleModel applies well for the scope
    parameter, just not sure if it's not rather mis-using of role
    concept and bit confusing for users?<br>
    <br>
    - My understanding is, that scope is per-client thing rather than
    per-realm thing? For example if you use "scope=photo", it's
    applicable just for client "photogallery". Also the same scope
    parameter may have different meaning for different clients ( eg. if
    you use "scope=admin" in client "product-app" , the token will
    receive claims/permissions for managing products. However using
    "scope=admin" in client "customer-app" , the token will manage
    customers). So with respect to this, scope looks to me more like
    either per-client thing or per-clientTemplate thing (if some logic
    is common for more clients).<br>
    <br>
    - We will need some way how to map value of scope parameter to
    particular role. <br>
    The simple (but probably not correct) way: On role definition, we
    can have something like "Scope param value" where you can configure
    value "photo" and it would mean that the "scope=photo" is related to
    this paricular role. <br>
    However what if there are clashes? For example someone can configure
    the scope parameter value "photo" for realm role "realm-photo-role"
    or client role "photogalery/client-photo-role" . Then when you use
    "scope=photo", which one will be used?<br>
    <br>
    So after we add roleNamespaces, I can imagine something like this:<br>
    - Each client will have reserved namespace, where all roles mapped
    to "scope" parameter lives. Also each clientTemplate will have such
    namespace.<br>
    <br>
    - After creation of client, there will be a set of corresponding
    roles added automatically for the client like:<br>
    "prefix:/clients/my-client-id/scope-param/phone"<br>
    "prefix:/clients/my-client-id/scope-param/address"<br>
    "prefix:/clients/my-client-id/scope-param/profile"<br>
    "prefix:/clients/my-client-id/scope-param/offline_access"<br>
    <br>
    You won't need to configure "Scope param name" as that will be based
    on the roleName<br>
    <br>
    - Those roles won't be default roles and won't be automatically
    assigned to users. However any user, who uses "scope=phone" can
    request the scope "phone" with corresponding protocolMappers and
    children composite roles.<br>
    <br>
    - If role is assigned to user directly, it will be always used even
    if it's not used in scope parameter. So user assigned to role
    "phone" will automatically receive "phone" and "phone_verified"
    protocolMappers.<br>
    <br>
    - Keycloak will browse roles from the "scope-param" namespace of
    particular client, and then also roles from "scope-param" namespace
    of clientTemplate. So clientTemplate can have namespace for scope
    parameters, which can be used if there is some "common" scope
    applicable to more clients with common set of protocolMappers from
    this clientTemplate.<br>
    <br>
    - For the scopes like "phone" "address" and "profile" it's pretty
    straightforward. It seems we will need protocolMappers for every
    OIDC defined claim (address, phone, gender, birthday etc) and those
    will have role required. So for example protocolMapper for
    "birthday" will require role "profile" , protocolMapper for "phone"
    will require role "phone" etc. Basic existing protocolMappers (
    name, "preferred_username" etc)  .<br>
    <br>
    - For the "prefix:/clients/my-client-id/scope-param/offline_access"
    role, it will have one composite role, which is current realm role
    "offline_access" . The current "offline_access" realm role is
    default role with scopeParamRequired=true, so it's applied just if
    it's requested (directly or indirectly) through scope parameter. If
    client doesn't need offline tokens and "offline_access" scope, the
    namespaced role
    "prefix:/clients/my-client-id/scope-param/offline_access". Also if
    you remove realm role "offline_access" from user, you disallow him
    to request offline tokens. It's currently realm role, hence it's
    global setting (so you can't reject user from offline tokens for
    "clientA" but allow him request offline tokens in "clientB") .<br>
    <br>
    Marek<br>
    <br>
    <blockquote
cite="mid:CAJgngAeKV1tPR61KW5963qanORXLFiUZ7KVZNDHpD9z0M5Y1GQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div><br>
        </div>
        <div>One more thing is that maybe when a composite role is used
          on the consent screen we could have an option if the composite
          role description should be shown rather than the individual
          roles?</div>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On 30 June 2016 at 15:56, 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">It
              seems that for OIDC certification, we will need more
              proper support<br>
              for "scope" parameter. There are few tests from OIDC
              conformance<br>
              testsuite, which end with WARNING because of issues with
              "scope" parameter.<br>
              <br>
              <br>
              SUMMARY OF SPECS REQUIREMENTS<br>
              -----------------------------<br>
              <br>
              - In OIDC specification, the "scope" parameter is actually
              REQUIRED. And<br>
              you must add the scope value "openid" to all authorization
              requests.<br>
              Hence if you don't use "scope=openid", the request is pure
              OAuth2<br>
              request, but it's not OIDC request.<br>
              <br>
              In <a moz-do-not-send="true"
                href="https://issues.jboss.org/browse/KEYCLOAK-3147"
                rel="noreferrer" target="_blank">https://issues.jboss.org/browse/KEYCLOAK-3147</a>
              we discuss the<br>
              possibility that we should change our adapters and add
              "scope=openid" to<br>
              all requests, and also the possibility to remove IDToken
              if it's not<br>
              OIDC request (and maybe other things). However it may be
              potential issue<br>
              with backward compatibility with older adapters (which
              don't add<br>
              "scope=openid" at all).<br>
              <br>
              <br>
              - OIDC also prescribes the "scope=offline_access", which
              you use if you<br>
              want offline token. We actually support this as we have
              realm role<br>
              "offline_access", with scopeParamRequired=true . So this
              role is applied<br>
              just if it's included in scope parameter. This is our only
              support of<br>
              scope param actually. ATM we reference the realm roles by
              name (role<br>
              name must match the value of scope parameter) and
              clientRoles by<br>
              "clientId/roleName" . So it's not very flexible and won't
              work well in<br>
              the future with role namespaces.<br>
              <br>
              <br>
              - OIDC defines four other scope values, which we don't
              support, with the<br>
              meaning like this:<br>
              <br>
              profile<br>
                   OPTIONAL. This scope value requests access to the
              End-User's<br>
              default profile Claims, which are: "name", "family_name",
              "given_name",<br>
              "middle_name", "nickname", "preferred_username",
              "profile", "picture",<br>
              "website", "gender", "birthdate", "zoneinfo", "locale",
              and "updated_at".<br>
              <br>
              email<br>
                   OPTIONAL. This scope value requests access to the
              "email" and<br>
              "email_verified" Claims.<br>
              <br>
              address<br>
                   OPTIONAL. This scope value requests access to the
              "address" Claim.<br>
              <br>
              phone<br>
                   OPTIONAL. This scope value requests access to the
              "phone_number"<br>
              and "phone_number_verified" Claims.<br>
              <br>
              <br>
              - Not directly related to scopes, however OIDC also has
              one parameter<br>
              "claims" described in section<br>
              <a moz-do-not-send="true"
href="http://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter"
                rel="noreferrer" target="_blank">http://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter</a>
              .<br>
              This allows to define some additional claims, which should
              be included<br>
              in IDToken or UserInfo endpoint in addition to claims
              specified by<br>
              "scope" parameter.<br>
              <br>
              <br>
              <br>
              HOW TO IMPLEMENT?<br>
              -----------------<br>
              <br>
              My current thinking is, that we will have 2 kinds of
              protocolMappers and<br>
              roles.<br>
              <br>
              1) "Always applied" - Those roles/protocolMappers are
              always applied to<br>
              token even if they are not specified by scope parameter.<br>
              <br>
              2) "Applied on demand" - Those roles/protocolMappers are
              applied just if<br>
              they are specifically requested by scope parameter<br>
              <br>
              For roles, we already have that with "scope param
              required" flag defined<br>
              per roleModel. However for protocolMappers we don't have
              it yet.<br>
              <br>
              IMO We will also need some more flexible way to specify
              how the value of<br>
              scope parameter will be mapped to roles and
              protocolMappers. For example<br>
              if I use "scope=foo", it can mean that I want realm role
              "foo1", client<br>
              role "client1/foo2" and protocolMapper for "firstName" and
              "lastName" etc.<br>
              <br>
              I can see 2 possibilities:<br>
              <br>
              a) Configure allowed scope param separately per each role
              / protocolMapper<br>
              <br>
              If some role has "Scope param required" checked, you will
              have<br>
              possibility to configure list of available values of scope
              parameter,<br>
              which this role will be applied to. This will be
              configured per-each<br>
              role separately.<br>
              <br>
              Example: I have realm role "foo" . I check "scope param
              required" to<br>
              true. Then I will define "scope param values" :  "bar" and
              "baz". It<br>
              means that if someone uses parameter "scope=bar" or<br>
              scope=baz", then role "foo" will be applied to token.
              Otherwise it won't<br>
              be applied.<br>
              <br>
              Similarly it will be for protocolMappers. We will add
              switch "Scope<br>
              param required" to protocolMappers and we will use list of
              available<br>
              values of scope parameter, which is configured per each
              protocolMapper<br>
              separately.<br>
              <br>
              <br>
              b) Configure scope parameter in separate place<br>
              <br>
              We will have another tab "Scope parameter config" (or
              maybe rather<br>
              another sub-tab under existing "Scope" tab). Here you will
              define the<br>
              allowed values of scope parameter. For each allowed value,
              you will<br>
              define protocolMappers and roles to apply. Hence for
              example for<br>
              "profile" scope parameter, you will define all
              protocolMappers for<br>
              corresponding claims ( name, family_name, ...) here.<br>
              <br>
              We will still need "scope param required" switch for
              protocolMappers in<br>
              case (b).<br>
              <br>
              My current thinking is to go with (a). So when you go to
              some role (or<br>
              protocolMapper) in admin console you will see if you need
              scope<br>
              parameter and what are available values of scope parameter
              to request it.<br>
              <br>
              WDYT? Another ideas?<br>
              <br>
              <br>
              Marek<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>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>