On 24/02/16 14:57, Thomas Darimont wrote:
What I actually want to do is to restrict the application listing on
the account page to just the clients where a user has a role mapping.
Currently this is only possible via "Full Scope Allowed -> off" 
and explicit role mappings.
Yes, exactly.

Some points:
* Each user is able to retrieve accessToken for each client configured in the realm
* The roles in the accessToken for particular client are intersection of:
** roles of user
** scopes of the client user is login to. If client has "Full scope allowed" then scopes are not taken into equation, so the roles in accessToken are consisted just of the user roles. Also note that client doesn't need scope for his own client roles (Those are always added into accessToken)

So one of your examples:

In case that "user-a" is member of "client-a:user-role-a" and he login to "client-b" what happens is:
- Roles of user contains "client-a:user-role-a"
- Scopes of client "client-b" contains "client-a:user-role-a" as well, because client-b has "Full scope allowed" on (which in other words means that accessToken will contain all roles of user-a including realm roles and roles of all clients)

Result is that accessToken of "user-a" to "client-b" will contain role "client-a:user-role-a".

By default, the applications page already filters the clients, which user don't have any roles. See https://github.com/keycloak/keycloak/blob/master/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java#L56 . But in the case above, the accessToken will contain the role client-a:user-role-a , so it's not the case.

You can look at TokenManager.getAccess to see how it works in details.

The "Full Access" in the "Granted Permissions" and "Granted personal info" is applicable just for the clients, which requires consent. It contains the roles and personal info, which user already confirmed on the consent screen. Maybe the UI should be changed to be more "friendly" here...  I think we have JIRA already open to improve usability of account management in general.

Marek


Then an admin has full control over what applications a user can see in the listing.

What I now ended up with is modifying the application.ftl in a custom theme 
that explicitly excludes clients with no role mappings for the current user
(+ the account client itself).

<#list applications.applications as application>
        <#-- filters out "account" app & anything that the user doesn't have an explicitly defined role in. -->
        <#if application.client.clientId != 'account' && application.resourceRolesAvailable[application.client.clientId]?has_content>
     
     //render account 

        </#if>
</#list>


Here are some of my experiments that describe the default behaviour of the 
"Full Scope Allowed" Setting in combination with the application listing in the account page.

Scenario 1)

client      role            Full Scope Allowed
client-a    "user-role-a"   "on"
client-b    "user-role-b"   "on"

user    roles
user-a  client-a: user-role-a
user-b  client-b: user-role-b

On account/applications page

user    applications with access
user-a  account (full access), client-a (full access), client-b (full access)
user-b  account (full access), client-a (full access), client-b (full access)

---

Scenario 2)

client      role            Full Scope Allowed
client-a    "user-role-a"   "off"
client-b    "user-role-a"   "on"

user    roles
user-a  client-a: user-role-a
user-b  client-b: user-role-b

On account/applications page

user    applications with access
user-a  account (full access), client-a (full access), client-b (full access)
user-b  account (full access), client-b (full access)

---

Scenario 3)

client      role            Full Scope Allowed
client-a    "user-role-a"   "on"
client-b    "user-role-b"   "off"

user    roles
user-a  client-a: user-role-a
user-b  client-b: user-role-b

On account/applications page

user    applications with access
user-a  account (full access), client-a (full access)
user-b  account (full access), client-a (full access), client-b (full access)

-> user-a sees only the application he has acces to
-> user-b sees however also sees client-a although he doesn't have a role mapping for client-a

---

Scenario 4)

client      role            Full Scope Allowed
client-a    "user-role-a"   "off"
client-b    "user-role-b"   "off"

user    roles
user-a  client-a: user-role-a
user-b  client-b: user-role-b

On account/applications page

user    applications with access
user-a  account (full access), client-a (full access)
user-b  account (full access), client-b (full access)

-> User only sees the applications for which he has roles
---

Scenario 5) introduced a common client...

client      role            Full Scope Allowed
client-a    "user-role-a"   "off"
client-b    "user-role-b"   "off"
client-c    "user-role-c"   "on"

user    roles
user-a  client-a: user-role-a, client-c: user-role-c
user-b  client-b: user-role-b

On account/applications page

user    applications with access
user-a  account (full access), client-a (full access), client-c (full access)
user-b  account (full access), client-b (full access), client-c (full access)

-> user-a sees only the applications he has a role for or access to: client-a, client-c
-> user-a sees client-c for which he doesn't have a role mapping

Cheers,
Thomas

2016-02-24 12:35 GMT+01:00 Marek Posolda <mposolda@redhat.com>:
On 24/02/16 11:26, Thomas Darimont wrote:
Steps to reproduce:

create client A with client id "client-a" with a newly defined role "user"
create client B with client id "client-b" with a newly defined role "user"

create user A with username "user-a" with "user" role granted for "client-a"
create user B with username "user-b" with "user" role granted for "client-b"

Goto applications tab in account page:
http://localhost:8082/auth/realms/eurodata.local/account/applications

login as user-a

Actual: The listing shows both applications client-a AND client-b 
        although the user-a only has a user-role to client-a.
Expected: Only client-a (+ account) applications should be shown
So "client-a" and "client-b" have fullScopeAllowed on? If yes, then the current behaviour is correct IMO. The thing is that user-a is able to login to application "client-b" and retrieve the accessToken for "client-b". And this accessToken will contain "user" role to "client-a" because of fullScopeAllowed.


The scope is used to limit the roles, which will user see after retrieve accessToken for particular client. So for example if you limit scope to client-a, then accessToken for user-a to client-b won't contain "user" role of "client-a". But if you retrieve accessToken for client-a, it will contain it.

Since the user-a doesn't have role "user" for "client-b" you will never see this role in any access token. So current behaviour is correct to me.

Marek


logout

login as user-b

Actual: The listing shows both applications client-a and client-b 
        although the user-b only has a user-role to client-b.
Expected: Only client-b (+ account) applications should be shown

By default a client has the "Full Scope Allowed" switch set to "on".
Changing this switch to "off" and explicitly assigning the client role "user" to "client-a" 
in the scope settings for client-a and to the user role for client-b in the scope settings 
for client-b solves the issue.

With this setting only the applications for which a user actually has the "user" role is shown.

Even though the help text for "Full Scope Allowed" says: "Allows you to disable all restrictions"
one would expect that "Full Scope Allowed" set to "on" would honor the assigned roles.

Is there something wrong here or should the help text be more descriptive?
I think the piece of code that does this is: org.keycloak.protocol.oidc.TokenManager.getAccess(String, boolean, ClientModel, UserModel)

Cheers,
Thomas


_______________________________________________
keycloak-dev mailing list
keycloak-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev