OAuth
The Simple OAuth module is used to provide an OAuth2 standard authorization server.
For documentation on using and authenticating with the farmOS API see API.
Providing OAuth Scopes
OAuth Scopes define different levels of access. The farmOS server implements scopes that represent individual roles or permissions. Users will authorize clients with one or more scopes that determine how much access they have to data on the server.
OAuth scopes are provided to the server using scope provider plugins. Each scope provider determines how scopes are implemented and created. The OAuth server must choose a single scope provider to provide all the scopes necessary for the server's authorization needs. All scopes use the same configuration and provide the same features regardless of the scope provider.
The Simple OAuth module
provides two scope providers: static
and dynamic
. The static
scope
provider implements scopes as a yaml
plugin that must be provided by modules
and prevents scopes from being modified. The dynamic
scope provider
implements scopes as a config entity and allows scopes to be created and
modified via the UI. Modules can provide dynamic
scopes as well but there are
no guarantees that these scopes will remain unmodified.
farmOS defaults to using the static
scope provider. This allows modules
providing OAuth scopes to guarantee that their scopes exist unmodified within
the server. The farmOS administrator can change to using the dynamic
scope
provider if necessary, but may need to re-create any static
scopes that
are needed for integrations provided by other modules.
The farmOS Default Roles module provides a static
OAuth scope for each of the
default roles: farm_manager
, farm_worker
, and farm_viewer
.
Scope Configuration
All scopes use the same configuration and provide the same features regardless of the scope provider:
- Scopes must provide a
name
to uniquely identify the scope - Scopes must provide a
description
- Scopes must specify if they are an
umbrella
scope. Umbrella scopes are only used as parent for child scopes to reference and do not specify agranularity
. - Scopes must configure which
grant_types
they allow. Each grant type can include an optionaldescription
to describe how the scope is used in the context of each grant type. - Scopes can optionally specify a
parent
scope that the scope is a part of. When the parent scope is requested, all of its child scopes are granted as well. - Scopes must specify a
granularity
if they are not anumbrella
scope. This value must be equal topermission
orrole
. The scope must provide a single value for thepermission
orrole
it is associated with.
This configuration is most easily demonstrated with
static
scopes that are provided in a module.oauth2_scopes.yml
plugin file.
"scope:name":
description: string (required)
umbrella: boolean (required)
grant_types: (required)
GRANT_TYPE_PLUGIN_ID: (required: only known grant types)
status: boolean (required)
description: string
parent: string
granularity: string (required: if umbrella is FALSE, values: permission or role)
permission: string (required: if umbrella is FALSE and granularity set to permission)
role: string (required: if umbrella is FALSE and granularity set to role)
An example of the static farm_manager
scope provided by the farmOS Role
Roles mdoule:
farm_manager:
description: 'Grants access to the Farm Manager role.'
umbrella: false
grant_types:
authorization_code:
status: true
refresh_token:
status: true
password:
status: true
granularity: 'role'
role: 'farm_manager'
Providing OAuth Clients
OAuth clients are modeled as "Consumer" entities (provided by the
Consumers module. To create
integrations with farmOS a consumer
entity must be created that
identifies the integration and configures the OAuth Client for the desired
authorization behavior.
The core farm_api_default_consumer
module provides a default client with
client_id = farm
that can use the password
and refresh_token
grant. You
can use this client for general usage of the API, like writing a script that
communicates with your farmOS server, but it comes with limitations.
Client Configuration
Standard Consumer configuration:
consumer.label
- A label used to identify the third party integration.consumer.client_id
- An optionalclient_id
machine name to identify the consumer. Thesimple_oauth
module uses a UUID by default, but a machine name makes it easier to identify clients across multiple farmOS servers.consumer.secret
- Aclient_secret
used to secure the OAuth client.consumer.confidential
- A boolean indicating whether the client secret needs to be validated.- Most farmOS third party integrations will disable this. Otherwise the
same
client_secret
must be configured on all farmOS servers, or the third party must keep track of a different secret for each server. This challenge is due to the nature of farmOS being a self-hosted application.
- Most farmOS third party integrations will disable this. Otherwise the
same
consumer.user_id
- When no specific user is authenticated Drupal will use this user as the author of all the actions made by this consumer.- This is only the case during the
Client Credentials
authorization flow.
- This is only the case during the
consumer.grant_types
- A list of the grant types that the client allows.consumer.scopes
- A list of default scopes that will be granted for this client if no scopes are requested during the authorization flow. No scopes will be granted that the user does not have access to.consumer.access_token_expiration
- The lifetime of access tokens in seconds.consumer.refresh_token_expiration
- The lifetime of refresh tokens in seconds.consumer.redirect_uri
- The URI this client will redirect to when needed.- This is used with the Authorization Code authorization flow.
consumer.allowed_origins
- Define any allowed origins the farmOS server should allow CORS requests from. This is required for any API integrations that will run in the browser.consumer.third_party
- Enable if the Consumer represents a third party.- Users will skip the "grant" step of the authorization flow for first party consumers only.