[keycloak-dev] Scope parameter support

Stian Thorgersen sthorger at redhat.com
Fri Jul 1 08:45:29 EDT 2016


On 1 July 2016 at 14:34, Marek Posolda <mposolda at redhat.com> wrote:

> On 01/07/16 09:37, Stian Thorgersen wrote:
>
> 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.
>
> A scope could affect:
>
> * Behavior - for example openid and offline_access. We can hard code
> those, but what about others and custom ones?
>
> 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.
>
> For offline_access we already has that driven by realm role actually.
>
> * Roles - limit what roles are included. This is probably the simplest
> case as it's just about removing roles.
>
> 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:
> role-a : scopeParamRequired=false
> role-b : scopeParamRequired=true
> role-c : scopeParamRequired=true
>
> 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).
>
> 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.
>

I meant that a single scope should be able to change several things, not
just enable/disable a single role.


>
> * 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.
> * 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
>
> 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:
>
> * Gallery wants to view your personal details
> * Backup application wants to access your photos
>
> A few more points:
>
> * It should be possible to view scopes available for a realm directly, not
> by scanning through roles and protocol mappers
> * It should be possible to set a description on a scope
> * It should be possible to define a scope that maps to multiple roles
> * It should be possible to define a scope that maps to multiple protocol
> mappers roles
> * It may be useful to be able to have protocol mappers that behave
> differently depending on the scope. Complexity may outweigh usefulness here
> though.
>
> With that in mind I don't think option (a) is great. Option (b) would need
> introducing a whole new concept.
>
> How about we use a combination of (a) and (b), by using composite roles?
> Something along the lines of:
>
> * scope maps to a role. but the role could be a composite role and hence
> expand to other roles.
> * Protocol mappers could require a specific role to be applied
> * We could add a page to view scopes for a realm
>   - This would show the corresponding role as well as effective roles if
> it's a composite role
>   - It would also list the protocol mappers included
>
> +1 to this concept and "mapping" scope param values to roles. However
> there are some things to clarify.
>
> - 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?
>

Would be better if we had role namespaces as we could then have a OIDC
namespace. That would remove some of the confusion I think.


>
> - 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).
>

Not sure I full agree with that. I think it can be a per-realm and
per-client thing, at least per group of clients. The scope could affect the
app, services it invokes and also authorization policies. I would actually
think that most organizations would define a "organization" level scopes
rather than per-client scopes.


>
> - We will need some way how to map value of scope parameter to particular
> role.
> 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.
> 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?
>
>
Why not just use the role name as the scope name? A composite role can be
used to create an "alias" if required.


> So after we add roleNamespaces, I can imagine something like this:
> - Each client will have reserved namespace, where all roles mapped to
> "scope" parameter lives. Also each clientTemplate will have such namespace.
>
> - After creation of client, there will be a set of corresponding roles
> added automatically for the client like:
> "prefix:/clients/my-client-id/scope-param/phone"
> "prefix:/clients/my-client-id/scope-param/address"
> "prefix:/clients/my-client-id/scope-param/profile"
> "prefix:/clients/my-client-id/scope-param/offline_access"
>
> You won't need to configure "Scope param name" as that will be based on
> the roleName
>
> - 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.
>
> - 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.
>
> - 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.
>
> - 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)  .
>
> - 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") .
>

Reading all of this makes me think it would be cleaner to introduce a
separate scope concept ;)

A user doesn't have a scope - a user has roles and attributes. Re-using
roles concept for the scope just makes it feel awkward and retrofitted.


>
>
> Marek
>
>
>
> 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?
>
> On 30 June 2016 at 15:56, Marek Posolda <mposolda at redhat.com> wrote:
>
>> It seems that for OIDC certification, we will need more proper support
>> for "scope" parameter. There are few tests from OIDC conformance
>> testsuite, which end with WARNING because of issues with "scope"
>> parameter.
>>
>>
>> SUMMARY OF SPECS REQUIREMENTS
>> -----------------------------
>>
>> - In OIDC specification, the "scope" parameter is actually REQUIRED. And
>> you must add the scope value "openid" to all authorization requests.
>> Hence if you don't use "scope=openid", the request is pure OAuth2
>> request, but it's not OIDC request.
>>
>> In https://issues.jboss.org/browse/KEYCLOAK-3147 we discuss the
>> possibility that we should change our adapters and add "scope=openid" to
>> all requests, and also the possibility to remove IDToken if it's not
>> OIDC request (and maybe other things). However it may be potential issue
>> with backward compatibility with older adapters (which don't add
>> "scope=openid" at all).
>>
>>
>> - OIDC also prescribes the "scope=offline_access", which you use if you
>> want offline token. We actually support this as we have realm role
>> "offline_access", with scopeParamRequired=true . So this role is applied
>> just if it's included in scope parameter. This is our only support of
>> scope param actually. ATM we reference the realm roles by name (role
>> name must match the value of scope parameter) and clientRoles by
>> "clientId/roleName" . So it's not very flexible and won't work well in
>> the future with role namespaces.
>>
>>
>> - OIDC defines four other scope values, which we don't support, with the
>> meaning like this:
>>
>> profile
>>      OPTIONAL. This scope value requests access to the End-User's
>> default profile Claims, which are: "name", "family_name", "given_name",
>> "middle_name", "nickname", "preferred_username", "profile", "picture",
>> "website", "gender", "birthdate", "zoneinfo", "locale", and "updated_at".
>>
>> email
>>      OPTIONAL. This scope value requests access to the "email" and
>> "email_verified" Claims.
>>
>> address
>>      OPTIONAL. This scope value requests access to the "address" Claim.
>>
>> phone
>>      OPTIONAL. This scope value requests access to the "phone_number"
>> and "phone_number_verified" Claims.
>>
>>
>> - Not directly related to scopes, however OIDC also has one parameter
>> "claims" described in section
>> http://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter .
>> This allows to define some additional claims, which should be included
>> in IDToken or UserInfo endpoint in addition to claims specified by
>> "scope" parameter.
>>
>>
>>
>> HOW TO IMPLEMENT?
>> -----------------
>>
>> My current thinking is, that we will have 2 kinds of protocolMappers and
>> roles.
>>
>> 1) "Always applied" - Those roles/protocolMappers are always applied to
>> token even if they are not specified by scope parameter.
>>
>> 2) "Applied on demand" - Those roles/protocolMappers are applied just if
>> they are specifically requested by scope parameter
>>
>> For roles, we already have that with "scope param required" flag defined
>> per roleModel. However for protocolMappers we don't have it yet.
>>
>> IMO We will also need some more flexible way to specify how the value of
>> scope parameter will be mapped to roles and protocolMappers. For example
>> if I use "scope=foo", it can mean that I want realm role "foo1", client
>> role "client1/foo2" and protocolMapper for "firstName" and "lastName" etc.
>>
>> I can see 2 possibilities:
>>
>> a) Configure allowed scope param separately per each role / protocolMapper
>>
>> If some role has "Scope param required" checked, you will have
>> possibility to configure list of available values of scope parameter,
>> which this role will be applied to. This will be configured per-each
>> role separately.
>>
>> Example: I have realm role "foo" . I check "scope param required" to
>> true. Then I will define "scope param values" :  "bar" and "baz". It
>> means that if someone uses parameter "scope=bar" or
>> scope=baz", then role "foo" will be applied to token. Otherwise it won't
>> be applied.
>>
>> Similarly it will be for protocolMappers. We will add switch "Scope
>> param required" to protocolMappers and we will use list of available
>> values of scope parameter, which is configured per each protocolMapper
>> separately.
>>
>>
>> b) Configure scope parameter in separate place
>>
>> We will have another tab "Scope parameter config" (or maybe rather
>> another sub-tab under existing "Scope" tab). Here you will define the
>> allowed values of scope parameter. For each allowed value, you will
>> define protocolMappers and roles to apply. Hence for example for
>> "profile" scope parameter, you will define all protocolMappers for
>> corresponding claims ( name, family_name, ...) here.
>>
>> We will still need "scope param required" switch for protocolMappers in
>> case (b).
>>
>> My current thinking is to go with (a). So when you go to some role (or
>> protocolMapper) in admin console you will see if you need scope
>> parameter and what are available values of scope parameter to request it.
>>
>> WDYT? Another ideas?
>>
>>
>> Marek
>>
>> _______________________________________________
>> keycloak-dev mailing list
>> keycloak-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/keycloak-dev
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-dev/attachments/20160701/092c4d5c/attachment-0001.html 


More information about the keycloak-dev mailing list