Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Use oauth2 scopes for access control #28

Open
farshidtz opened this issue Jun 23, 2020 · 1 comment
Open

Use oauth2 scopes for access control #28

farshidtz opened this issue Jun 23, 2020 · 1 comment
Labels
enhancement New feature or request

Comments

@farshidtz
Copy link
Member

farshidtz commented Jun 23, 2020

Currently, the Keycloak plugin which uses the OpenID Connect protocol performs access control on endpoint/methods using user claims (username, group) or the clientID.

We may be able to use OAuth2 scopes for the same level of access control.

OAuth2 security scheme:
https://www.w3.org/TR/wot-thing-description/#oauth2securityscheme

Set of authorization scope identifiers provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. The values associated with a form should be chosen from those defined in an OAuth2SecurityScheme active on that form.

Example: https://www.w3.org/TR/wot-thing-description/#example-15

... OAuth2 makes use of scopes. These are identifiers that may appear in tokens and must match with corresponding identifiers in a resource to allow access to that resource (or Interaction Affordance in the case of W3C WoT). For example, in the following, the status Property can be read by Consumers using bearer tokens containing the scope limited, but the configure Action can only be invoked with a token containing the special scope. Scopes are not identical to roles, but are often associated with them; for example, perhaps only those in an administrative role are authorized to perform "special" interactions. Tokens can have more than one scope. In this example, an administrator would probably be issued tokens with both the limited and special scopes, while ordinary users would only be issued tokens with the limited scope.

{
    ...
    "securityDefinitions": {
        "oauth2_sc": {
            "scheme": "oauth2",
            ...
            "flow": "code",
            "authorization": "https://example.com/authorization",
            "token": "https://example.com/token",
            "scopes": ["limited", "special"]
        }
    },
    "security": ["oauth2_sc"],
    ...
    "properties": {
        "status": {
            ...
            "forms": [{
                "href": "https://scopes.example.com/status",
                "scopes": ["limited"]
            }]
        }
    },
    "actions": {
        "configure": {
            ...
            "forms": [{
                "href": "https://scopes.example.com/configure",
                "scopes": ["special"]
            }]
        }
    },
    ...
}

From OAuth2 specs:

The authorization and token endpoints allow the client to specify the
scope of the access request using the "scope" request parameter. In
turn, the authorization server uses the "scope" response parameter to
inform the client of the scope of the access token issued.

Or a more understandable version:

Scope is a mechanism in OAuth 2.0 to limit an application's access to a user's account. An application can request one or more scopes, this information is then presented to the user in the consent screen, and the access token issued to the application will be limited to the scopes granted.

There are also a few examples here.

@farshidtz farshidtz added the enhancement New feature or request label Jun 23, 2020
@farshidtz
Copy link
Member Author

farshidtz commented Jun 23, 2020

In Keycloak, scopes can be associated with roles and users in the following way:

  1. Roles -> Create a role
  2. Client Scopes
    i. Create a scope
    ii. Edit the scope -> Scope -> Assign the role
  3. Clients -> Edit client -> Client Scopes -> Assign the role to Assigned Optional Client Scopes
  4. Users -> Role Mappings -> Assign the role

In the OAuth2 token request, when asking for the specific scope, the server will provide it in response only if the user has an associated role.

E.g. password grant:

curl --location --request POST '<token-endpoint>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=test-client' \
--data-urlencode 'username=tester' \
--data-urlencode 'password=******' \
--data-urlencode 'scope=limited'
{
    "access_token": "<access-token>",
    "expires_in": 300,
   ...
    "scope": "email limited profile"
}

Access Token Payload:

{
  "exp": 1592929675,
  "iat": 1592929375,
  "typ": "Bearer",
  ...
  "scope": "email limited profile",
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant