Configuring OAuth Authorization

Solace PubSub+ event brokers support two different types of OAuth tokens: access_token and id_token. The OAuth standards state that the access_token is required and is opaque data and that the id_token is optional and a JWT. PubSub+ event brokers permit both types of tokens and also allow the access_token to be a JWT.

JWTs can be cryptographically signed. Solace PubSub+ event brokers support JWTs with the alg claim equal to: none, RS256, RS384, RS512. If the alg claim is anything else, it is rejected as an invalid token. If the header includes a type claim, it must identify the payload as JWT (this corresponds to the type or typ claim in the JWT header).

To implement OAuth authorization for clients connecting to a Solace PubSub+ event broker, the following configurations are required on an event broker:

  1. An OAuth provider must be configured and enabled for OAuth authentication. See Managing OAuth Providers.
  2. The source used to determine the authorization group must be configured. See Configuring Authorization Group Determination.
  3. OAuth authorization must be enabled for any Message VPNs that OAuth-authenticated clients will connect to. See Enabling OAuth Authorization.
  4. An authorization group must be configured and enabled on the event broker. See Configuring LDAP Authorization Groups.

Solace PubSub+ event brokers support OAuth authorization only for MQTT clients.

Configuring Authorization Group Determination

By default, PubSub+ event brokers use the scope field in OpenID Connect ID tokens to determine the client authorization group. You can change these defaults to suit your deployment.

To configure the token field used to determine the client authorization group, enter the following command:

solace(...on/oauth/provider/authorization-group)# claim name <name>

Where:

<name> is the field in the token used to determine the client authorization group. If no value is provided, scope is used as the default. When using JWTs, claim names must be at the top level of the JWT. In other words, they cannot be embedded. In addition, the value of any claim that you want to use as a client authorization group must be a space-separated string or an array of strings.

In this example the "authGroupClaim" field is used to determine the authorization group, and its value is the space-separated string "abcdefghi":

{
...
   "authGroupClaim": "abcdefghi",
...
}

In this example the "scope" field is used to determine the authorization group, and its value is the space-separated string "abc def ghi". In this case, the event broker interprets this value as three separate authorization groups, "abc", "def", and "ghi":

{
...
   "scope": "abc def ghi",
...
}

In this example the "authGroup" field is used to determine the authorization group, and its value is the string array ["a b c", "def", "ghi"]. The event broker interprets this array as three authorization groups, "a b c" (including the spaces), "def", and "ghi". If you require spaces in the authorization group claim, you must pass a string array:

{
...
   "authGroup": ["a b c", "def", "ghi"],
...
}

To configure the token source used to determine the client authorization group, enter the following command:

solace(...on/oauth/provider/authorization-group)# claim source {access-token | id-token | introspection}

Where:

access-token specifies to search for the authorization group value in the JWT OAuthv2 access token.

id-token specifies to search for the authorization group value in the OpenID Connect ID token. This is the default token source.

introspection specifies to use token introspection on the access token, regardless of whether it is a JWT or opaque data, to determine the authorization group. If you want to use token introspection, you must also configure the token parameter the OAuth authorization server expects (see Configuring OAuth Authorizationas well as the appropriate connection details for the server (see Configuring OAuth Authorization).

Enabling OAuth Authorization

To enable OAuth authorization for clients connecting to the given Message VPN, enter the following commands:

solace(configure)# message-vpn <vpn-name>
solace(configure/message-vpn)# authentication
solace(configure/message-vpn/authentication)# oauth
solace(...gure/message-vpn/authentication/oauth)# provider <provider name>
solace(...age-vpn/authentication/oauth/provider)# authorization-group
solace(...on/oauth/provider/authorization-group)# no shutdown

To disable OAuth authorization for clients connecting to the given Message VPN, enter the following command:

solace(...on/oauth/provider/authorization-group)# shutdown

OAuth Authorization Example Configuration

The following example shows how to create and set up an OAuth provider on a new Message VPN which is used for OAuth authentication and authorization.

In this example:

  • The OAuth authorization server introspection URI is located at 192.168.1.23: 23432 and requires credentials of oauthServerUsername/oauthServerPassword through HTTPS.
  • It is assumed that ID tokens used to log in to the event broker contain the following:
    • A non-default userNameClaim claim instead of sub. This means the event broker will search for the client username in the userNameClaim field of the token instead of the sub field.
    • A non-default audience claim instead of aud. This means the event broker will search for the audience value in the audience field of the token instead of the aud field.
    • A non-default authGroupClaim claim instead of scope. This means the event broker will search for the authorization group in the authGroupClaim field of the token instead of the scope field.
  • Audience validation is enabled and audienceValue is the audience value required for an ID token to be considered valid.
  • The JWKS refresh URI is located at http://192.168.1.24:34543.
  • JWKS public keys stored on the event broker are refreshed every 24 hours.
solace(configure)# create message-vpn oauthExample
solace(configure/message-vpn)# authentication oauth
solace(...gure/message-vpn/authentication/oauth)# no shutdown
solace(...gure/message-vpn/authentication/oauth)# create provider myOauthProvider
solace(...age-vpn/authentication/oauth/provider)# no shutdown
solace(...age-vpn/authentication/oauth/provider)# token introspection
solace(...on/oauth/provider/token/introspection)# username oauthServerUsername
solace(...on/oauth/provider/token/introspection)# password oauthServerPassword
solace(...on/oauth/provider/token/introspection)# uri https://192.168.1.23:23432
solace(...on/oauth/provider/token/introspection)# exit
solace(...n/authentication/oauth/provider/token)# exit
solace(...age-vpn/authentication/oauth/provider)# authorization-group
solace(...on/oauth/provider/authorization-group)# no shutdown
solace(...on/oauth/provider/authorization-group)# claim name authGroupClaim
solace(...on/oauth/provider/authorization-group)# exit
solace(...age-vpn/authentication/oauth/provider)# audience
solace(...uthentication/oauth/provider/audience)# no shutdown
solace(...uthentication/oauth/provider/audience)# claim value audienceValue
solace(...uthentication/oauth/provider/audience)# claim name audience
solace(...uthentication/oauth/provider/audience)# exit
solace(...age-vpn/authentication/oauth/provider)# jwks
solace(...pn/authentication/oauth/provider/jwks)# refresh-interval 86400
solace(...pn/authentication/oauth/provider/jwks)# uri http://192.168.1.24:34543