[keycloak-user] Policy Enforcer: enforcement-mode=ENFORCING question

Alexey Titorenko titorenko at dtg.technology
Mon Feb 4 07:59:47 EST 2019


Thanks!

> On 4 Feb 2019, at 15:58, Pedro Igor Silva <psilva at redhat.com> wrote:
> 
> Yeah, you are right. I've created https://issues.jboss.org/browse/KEYCLOAK-9483 <https://issues.jboss.org/browse/KEYCLOAK-9483> to track this and make this behaviour more intuitive without forcing you to create additional permissions or only associate scopes.
> 
> On Mon, Feb 4, 2019 at 10:52 AM Alexey Titorenko <titorenko at dtg.technology> wrote:
> Ok, thank you, Pedro. 
> 
> Just few words about this.
> 
> If I see description of ‘Resource’ field, then it says that it is just a filter for scopes field shown below it (see screenshot below). It this filter has side affects and changes access area, then it is even more strange and dangerous.
> This might be problematic if I have two resources in my service that have same set of scopes (or intersecting sets).
> 
> 
> Again, thank you for Jira ticket.
> 
> Alexey
> 
> <Screenshot 2019-02-04 at 15.45.20.png>
> 
> 
> 
> 
>> On 4 Feb 2019, at 15:41, Pedro Igor Silva <psilva at redhat.com <mailto:psilva at redhat.com>> wrote:
>> 
>> Or just leave "list" and remove the resource from your permission ....
>> 
>> I agree with you, will open a JIRA to make this more intuitive.
>> 
>> Tks 
>> 
>> 
>> On Mon, Feb 4, 2019 at 10:39 AM Alexey Titorenko <titorenko at dtg.technology <mailto:titorenko at dtg.technology>> wrote:
>> Hi Pedro.
>> 
>> Ok, I understand. To my opinion it is a bit not intuitive and dangerous, as scope based permission opens access to the whole resource. Yes, if I specify permissions for all scopes, then it works fine. 
>> 
>> Thank you!
>> 
>> Alexey
>> 
>> 
>>> On 4 Feb 2019, at 15:32, Pedro Igor Silva <psilva at redhat.com <mailto:psilva at redhat.com>> wrote:
>>> 
>>> The main point here is that you are granted with a permission without any scope:
>>> 
>>> 2019-02-04 12:29:12.698 DEBUG 5364 --- [nio-8085-exec-4] o.k.a.a.AbstractPolicyEnforcer           : Authorization GRANTED for path [PathConfig{name='Documents', type='null', path='/documents/{id}', scopes=[], id='b14999a7-0853-4063-8fe6-c0469a975846', enforcerMode='ENFORCING'}]. Permissions [[Permission {id=b14999a7-0853-4063-8fe6-c0469a975846, name=Documents, scopes=[]}]].
>>> 
>>> The policy enforcer understands that "no scopes" means access to the resource itself and that explains why you are able to access that protected resource.
>>> 
>>> The reason why you are granted with permission with no scopes is that the policy engine checks whether or not the permission (regardless if scope or resource based) is associated with a resource. If so, access to the resource is granted.
>>> 
>>> You can try removing the resource from "List Documents" permission and leave only the "list" scope.
>>> 
>>> Another option is define a scope-based permission to each scope.
>>> 
>>> For last, I'm wondering if we should only grant access to a resource if the permissions ia actually a resource-based permission. So you will none of the steps above would be necessary and your configuration will work as expected.
>>> 
>>> Wdyt ? 
>>> 
>>> 
>>> On Mon, Feb 4, 2019 at 7:54 AM Alexey Titorenko <titorenko at dtg.technology <mailto:titorenko at dtg.technology>> wrote:
>>> Hello guys!
>>> 
>>> Could someone help me with this.
>>> 
>>> I’m playing with policy enforcers in test Spring Boot application trying to find how to apply it to our cases. I’m trying to investigate how 'ENFORCING’ mode is working with scope based permissions. 
>>> 
>>> My intuitive understanding of this:
>>> if resource does not have any permissions defined on it, then access is denied for any scope requested.
>>> if resource has some permissions, then access to scopes, not covered by any existing permissions is always denied.
>>> 
>>> What I see in reality:
>>> first case works fine. Access to my service is denied If no permissions defined on it.
>>> if the resource has a permission, controlling access to one scope, then access to the other scopes is always GRANTED.
>>> 
>>> In particular, I’ve created demo REST document storage service, which defines CRUD operations, plus one ‘list’ operation to get list of documents for an entity. All these operations are covered by a corresponding scope (create, view, update, delete, list). After that:
>>> If I have no permissions defined for this service, then no access is granted whatever scope I request.
>>> If I define scope-based permission, let’s say, controlling access to the ‘list’ scope on the resource, then access is automatically granted to requests for all CRUD operations, for example, for ‘create' operation.
>>> 
>>> Is it how this is intended to work or not? My expectation is that everything should be denied (every scope), until explicitly allowed by some permission.
>>> 
>>> Below are debug log messages that might be of some interest, my policy enforcer config, and some screenshots.
>>> 
>>> The first log entry corresponds to ‘create’ operation with ‘create’ scope and the other one — to ‘list’ operation. 
>>> 
>>> Thank you,
>>> Alexey.
>>> 
>>> From Logs:
>>> 2019-02-04 12:29:12.698 DEBUG 5364 --- [nio-8085-exec-4] o.k.a.a.AbstractPolicyEnforcer           : Authorization GRANTED for path [PathConfig{name='Documents', type='null', path='/documents/{id}', scopes=[], id='b14999a7-0853-4063-8fe6-c0469a975846', enforcerMode='ENFORCING'}]. Permissions [[Permission {id=b14999a7-0853-4063-8fe6-c0469a975846, name=Documents, scopes=[]}]].
>>> 
>>> 2019-02-04 12:29:11.846 DEBUG 5364 --- [nio-8085-exec-3] o.k.a.a.AbstractPolicyEnforcer           : Authorization GRANTED for path [PathConfig{name='Documents', type='null', path='/documents/', scopes=[], id='b14999a7-0853-4063-8fe6-c0469a975846', enforcerMode='ENFORCING'}]. Permissions [[Permission {id=b14999a7-0853-4063-8fe6-c0469a975846, name=Documents, scopes=[list]}]].
>>> 
>>> 
>>> Config
>>> svc.name <http://svc.name/>=docs-uma
>>> server.port = 8085
>>> keycloak.realm=DemoApp
>>> keycloak.auth-server-url=http://localhost:8180/auth <http://localhost:8180/auth>
>>> keycloak.ssl-required=external
>>> keycloak.resource=docs-svc-uma
>>> keycloak.cors=true
>>> keycloak.use-resource-role-mappings=true
>>> keycloak.verify-token-audience=false
>>> keycloak.credentials.secret=0e55734e-aadc-4268-8757-b5dca453980a
>>> keycloak.confidential-port=0
>>> keycloak.bearer-only=true
>>> 
>>> keycloak.securityConstraints[0].securityCollections[0].name = secured operation
>>> keycloak.securityConstraints[0].authRoles[0] = user
>>> keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /documents
>>> keycloak.securityConstraints[0].securityCollections[0].patterns[1] = /documents/*
>>> 
>>> keycloak.securityConstraints[1].securityCollections[0].name = admin operation
>>> keycloak.securityConstraints[1].authRoles[0] = admin
>>> keycloak.securityConstraints[1].securityCollections[0].patterns[0] = /admin
>>> keycloak.securityConstraints[1].securityCollections[0].patterns[1] = /admin/
>>> 
>>> logging.level.org.keycloak=DEBUG
>>> logging.level.dtg.plays.iam.keycloak.demo.backend.docs.auth.keycloak.cip=DEBUG
>>> 
>>> # policy enforcer
>>> keycloak.policy-enforcer-config.enforcement-mode=ENFORCING
>>> keycloak.policy-enforcer-config.lazy-load-paths=true
>>> keycloak.policy-enforcer-config.on-deny-redirect-to=/public
>>> 
>>> keycloak.policy-enforcer-config.paths[0].name=Public Resources
>>> keycloak.policy-enforcer-config.paths[0].path=/*
>>> 
>>> keycloak.policy-enforcer-config.paths[1].name=Admin Resources
>>> keycloak.policy-enforcer-config.paths[1].path=/admin/*
>>> keycloak.policy-enforcer-config.paths[1].claimInformationPointConfig.claims[some-claim]={request.uri}
>>> keycloak.policy-enforcer-config.paths[1].claimInformationPointConfig.claims[claims-from-document]={request.uri}
>>> 
>>> keycloak.policy-enforcer-config.paths[2].name=Documents
>>> keycloak.policy-enforcer-config.paths[2].path=/documents/
>>> keycloak.policy-enforcer-config.paths[2].methods[0].method=POST
>>> keycloak.policy-enforcer-config.paths[2].methods[0].scopes[0]=create
>>> keycloak.policy-enforcer-config.paths[2].methods[1].method=GET
>>> keycloak.policy-enforcer-config.paths[2].methods[1].scopes[0]=list
>>> keycloak.policy-enforcer-config.paths[3].name=Documents
>>> keycloak.policy-enforcer-config.paths[3].path=/documents/{id}
>>> keycloak.policy-enforcer-config.paths[3].methods[0].method=GET
>>> keycloak.policy-enforcer-config.paths[3].methods[0].scopes[0]=get
>>> keycloak.policy-enforcer-config.paths[3].methods[1].method=POST
>>> keycloak.policy-enforcer-config.paths[3].methods[1].scopes[0]=update
>>> keycloak.policy-enforcer-config.paths[3].methods[2].method=DELETE
>>> keycloak.policy-enforcer-config.paths[3].methods[2].scopes[0]=delete
>>> 
>>> Client authorisation config:
>>> {
>>>   "allowRemoteResourceManagement": true,
>>>   "policyEnforcementMode": "ENFORCING",
>>>   "resources": [
>>>     {
>>>       "name": "Admin Resources",
>>>       "type": "urn:docs-svc-uma:resources:admin",
>>>       "ownerManagedAccess": false,
>>>       "attributes": {},
>>>       "_id": "0ca1b086-c3d1-47eb-8fa6-3bb699af8791",
>>>       "uris": [
>>>         "/admin/*",
>>>         "/admin"
>>>       ],
>>>       "icon_uri": ""
>>>     },
>>>     {
>>>       "name": "Documents",
>>>       "type": "urn:docs-svc-uma:resources:documents",
>>>       "ownerManagedAccess": false,
>>>       "attributes": {},
>>>       "_id": "b14999a7-0853-4063-8fe6-c0469a975846",
>>>       "uris": [
>>>         "/documents/{id}",
>>>         "/documents/"
>>>       ],
>>>       "scopes": [
>>>         {
>>>           "name": "view"
>>>         },
>>>         {
>>>           "name": "update"
>>>         },
>>>         {
>>>           "name": "delete"
>>>         },
>>>         {
>>>           "name": "create"
>>>         },
>>>         {
>>>           "name": "list"
>>>         }
>>>       ]
>>>     }
>>>   ],
>>>   "policies": [
>>>     {
>>>       "id": "72f8ced8-8b2f-41f3-be41-c371e5d66788",
>>>       "name": "Default Policy",
>>>       "description": "A policy that grants access only for users within this realm",
>>>       "type": "js",
>>>       "logic": "POSITIVE",
>>>       "decisionStrategy": "AFFIRMATIVE",
>>>       "config": {
>>>         "code": "// by default, grants any permission associated with this policy\n$evaluation.grant();\n"
>>>       }
>>>     },
>>>     {
>>>       "id": "b786a8bb-3705-4df6-86cd-c041065d3703",
>>>       "name": "Never",
>>>       "type": "js",
>>>       "logic": "POSITIVE",
>>>       "decisionStrategy": "UNANIMOUS",
>>>       "config": {
>>>         "code": "$evaluation.deny();"
>>>       }
>>>     },
>>>     {
>>>       "id": "6ca70fa3-907b-4368-97cb-3aadc1b6d5db",
>>>       "name": "List Documents",
>>>       "type": "scope",
>>>       "logic": "POSITIVE",
>>>       "decisionStrategy": "UNANIMOUS",
>>>       "config": {
>>>         "resources": "[\"Documents\"]",
>>>         "scopes": "[\"list\"]",
>>>         "applyPolicies": "[\"Default Policy\"]"
>>>       }
>>>     }
>>>   ],
>>>   "scopes": [
>>>     {
>>>       "id": "be6a7101-f5a3-4b9f-a6be-349e167e89ae",
>>>       "name": "create"
>>>     },
>>>     {
>>>       "id": "ba3a7575-db45-407b-b74a-4e8b1fc461c2",
>>>       "name": "delete"
>>>     },
>>>     {
>>>       "id": "e749c197-b70a-4ccd-a719-1c9ef40b6050",
>>>       "name": "update"
>>>     },
>>>     {
>>>       "id": "d72a9d39-3750-41c4-954f-0db7853cb964",
>>>       "name": "list"
>>>     },
>>>     {
>>>       "id": "6ee46777-a0ee-492a-bb4e-ef8aaeb8f402",
>>>       "name": "view",
>>>       "iconUri": ""
>>>     }
>>>   ]
>>> }
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> keycloak-user mailing list
>>> keycloak-user at lists.jboss.org <mailto:keycloak-user at lists.jboss.org>
>>> https://lists.jboss.org/mailman/listinfo/keycloak-user <https://lists.jboss.org/mailman/listinfo/keycloak-user>
> 



More information about the keycloak-user mailing list