Skip to main content

Using Caché as an OAuth 2.0 Authorization Server

This chapter describes how to use a Caché instance as an OAuth 2.0 authorization server. It discusses the following:

Note that this chapter is organized differently from the other chapters in this book. It is likely that the person who creates client definitions will not be the same person who set up the server. Moreover, it may be necessary to create client definitions on an ongoing basis. For this reason, the task of creating client definitions is included as a stand-alone section, at the end of the chapter.

Configuration Requirements for the Caché Authorization Server

To use a Caché instance as an OAuth 2.0 authorization server, perform the following configuration tasks:

  • For the web server that is serving Caché, configure that web server to use SSL. It is beyond the scope of this documentation to describe how to configure a web server to use SSL.

  • Create a Caché SSL configuration for use by the server.

    This should be a client SSL configuration; no certificate is needed. The configuration is used to connect to a web server. Via this connection, the authorization server accesses the request object specified by the request_uri parameter. Via this connection, the authorization server also accesses the jwks_uri when updating a client JWKS. If the client does not send requests using the request_uri parameter and if the authorization server does not update the client JWKSs via the jwks_uri parameter, then the authorization server does not need an SSL configuration.

    For details on creating SSL configurations, see the chapter “Using SSL/TLS with Caché” in the Caché Security Administration Guide.

    Each SSL configuration has a unique name. For reference, the documentation refers to this one as sslconfig, but you can use any unique name.

  • Create the server configuration as described in the following subsection.

  • Later, create client definitions as needed; see the last section in this chapter.

Configuring the Authorization Server

In order to perform this task, you must be logged in as a user who has USE permission on the %Admin_Secure resource.

  1. In the Management Portal, select System Administration > Security > OAuth 2.0 > Server Configuration.

  2. On the General tab, specify the following details:

    • Description — Enter an optional description.

    • Issuer endpoint — Specify the endpoint URL of the authorization server. To specify this URL, enter values for the following options:

      • Host name — Specify the host name or IP address of the authorization server.

      • Port — Specify this if needed to accommodate any changes in the CSP Gateway configuration.

      • Prefix — Specify this if needed to accommodate any changes in the CSP Gateway configuration.

      The resulting issuer endpoint has the following form:

      https://hostname:port/prefix/oauth2
      

      If you omit Port, the colon is omitted. Similarly, if you omit Prefix, there is only one slash between hostname:port and oauth2.

    • Audience required — Specify whether the authorization server requires the aud parameter in authorization code and implicit requests. If this check box is clear, aud is not required.

    • Support user session — Specify whether the authorization server supports user sessions. A Caché authorization server can support user sessions (note that these are not CSP sessions). To do this, Caché uses a session maintenance class (Session maintenance class); a default is provided. See “Code Customization Options,” later in this chapter. If this check box is clear, sessions are not supported.

    • Return refresh token — Specify the conditions under which a refresh token is returned along with the access token. Select the option appropriate for your business case.

    • Supported grant types — Specify the grant types that this authorization server allows to be used to create an access token. Select at least one.

    • OpenID provider documentation — Specify URLs provided by the OpenID provider as follows:

      • Service Documentation URL — URL of a web page that provides human-readable information that developers might want or need to know when using the OpenID provider.

      • Policy URL — URL of a web page that describes the OpenID provider’s policy on how a relying party can use the data provided by the provider.

      • Terms of Service URL — URL of a web page that describes the OpenID provider’s terms of service.

    • SSL configuration — Select the SSL configuration you created for use by the authorization server (for example, sslconfig).

  3. On the Scopes tab, specify the following details:

    • Table with Scope and Description columns — Specify all scopes supported by this authorization server.

    • Allow unsupported scope — Specify whether the authorization server ignores scope values that it does not support. If this check box is clear, the authorization server returns an error when a request contains an unsupported scope value; in this case the request is not processed. If this check box is selected, the authorization server ignores the scope and processes the request.

    • Default scope — Specify the default for access token scope if scope is not specified in the access token request or in the client configuration.

  4. On the Intervals tab, specify the following details:

    • Access token interval — Specify the number of seconds after which an access token issued by this server will expire. The default is 3600 seconds.

    • Authorization code interval — Specify the number of seconds after which an authorization code issued by this server will expire. The default is 60 seconds.

    • Refresh token interval — Specify the number of seconds after which a refresh token issued by this server will expire. The default is 24 hours (86400 seconds).

    • Session termination interval — Specify the number of seconds after which a user session will be automatically terminated. The value 0 means the session will not be automatically terminated. The default is 24 hours (86400 seconds).

    • Client secret expiration interval — Specify the number of seconds after which a client secret issued by this server will expire. The default value (0) means that the client secrets do not expire.

  5. For the JWT Settings tab, specify the following details:

    • Create JWT Settings from X509 credentials — Select this option if, for signing and encryption, you want to use the private key associated with a certificate; in this case, also see “Using Certificates for an OAuth 2.0 Authorization Server,” in the appendix “Certificates and JWTs (JSON Web Tokens).”

      Note:

      InterSystems expects that the option Create JWT Settings from X509 credentials will rarely be used, and that instead customers use the default behavior described next.

      If you leave this option clear, the system generates a pair of JWKSs (JSON web key sets). One JWKS is private and contains all the needed private keys (per algorithm) as well as the client secret for use as a symmetric key; this JWKS is never shared. The other JWKS contains the corresponding public keys and is publicly available. Caché also copies the public JWKS to the client, so that the client can encrypt and verify signatures of JWTs from the authorization server.

    • Signing algorithm — Select the algorithm to use when signing JWTs. Or leave this blank if JWTs are not to be signed.

    • Key management algorithm — Select the algorithm to use for key management when encrypting JWTs.

      Do this only if you select a content encryption algorithm.

    • Content encryption algorithm — Select the algorithm to use when encrypting JWTs. Or leave this blank if JWTs are not to be encrypted. If you select an algorithm, you must also select an algorithm for key management.

  6. On the Customization tab, specify details as described in “Code Customization Options,” later in this chapter.

  7. Select Save.

When you save this configuration, the system creates a web application (/oauth2) for use by the authorization server. Do not modify this web application.

Code Customization Options and Overall Flow

This section describes the items in the Customization Options section of the configuration options of the authorization server. Subsections describe the overall flow and the default classes.

  • Authenticate class — Use %OAuth2.Server.AuthenticateOpens in a new tab (the default) or a custom subclass of that class.

    If you define a custom subclass, implement some or all of the following methods, depending on your needs:

    • BeforeAuthenticate() — Optionally implement this method to perform custom processing before authentication.

    • DisplayLogin() — Optionally implement this method to display a login page to identify the user. (For a less common alternative, see the appendix “Implementing DirectLogin().”)

    • DisplayPermissions() — Optionally implement this method to display the requested permissions to the user.

    • AfterAuthenticate() — Optionally implement this method to perform custom processing after authentication.

  • Validate user class — Use %OAuth2.Server.ValidateOpens in a new tab (the default) or a custom class that defines the following methods:

    • ValidateUser() (used by all grant types other than client credentials)

    • ValidateClient() (used by the client credentials grant type)

    InterSystems highly recommends that you define and use a custom class. The %OAuth2.Server.ValidateOpens in a new tab class is provided for demonstration purposes and is very unlikely to be suitable for production use.

  • Session maintenance class — Use OAuth2.Server.SessionOpens in a new tab (the default) or a custom subclass of that class. The default session class maintains user sessions via an HTTP-only cookie.

  • Generate token class — Use %OAuth2.Server.GenerateOpens in a new tab (the default), %OAuth2.Server.JWTOpens in a new tab, or a custom class that defines the method GenerateAccessToken(). If you create a custom class, you might find it useful to subclass one of the classes listed here, because they provide methods you may want to use.

  • Customization namespace — Specify the namespace in which the customization code should run.

  • Customization roles — Specify the role or roles to use when running the customization code.

If you use any custom subclasses, see “Implementing the Custom Methods.”

How a Caché Authorization Server Processes Requests

This section describes what a Caché authorization server does when it receives an authorization code request or an implicit request for a token.

  1. Calls the BeforeAuthenticate() method of the class specified via the Authenticate class option. The purpose of this method is to make any modifications to the request before user identification starts.

    In the default class, this method is a stub.

  2. Next, if the grant type is authorization code or implicit grant, Caché does the following:

    1. Calls the DisplayLogin() of the class specified via the Authenticate class option. (But also see the appendix “Implementing DirectLogin().”)

      In the default class, DisplayLogin() displays a simple HTML login page.

    2. If the username is not null, calls the ValidateUser() method of the class specified via the Validate user class option. The purpose of this method is to validate the user and (by modifying the properties array) to prepare any claims to be returned by the token, Userinfo, and token introspection endpoints.

      In the default class, this method is only a sample and is very unlikely to be suitable for production use.

    3. If the user is validated, calls the DisplayPermissions() method of the class specified via the Authenticate class option. The purpose of this method is to display a page to the user that lists the requested permissions.

      In the default class, this method displays a simple HTML page with the permissions.

    Or if the grant type is password credentials, Caché just calls the ValidateUser() method of the class specified via the Validate user class option.

    Or if the grant type is client credentials, Caché just calls the ValidateClient() method of the class specified via the Validate user class option.

  3. If the user accepts the permissions, calls the AfterAuthenticate() method of the class specified via the Authenticate class option. The purpose of this method is to perform any custom processing before generating an access token.

    In the default class, this method is a stub.

  4. Calls the GenerateAccessToken() method of the class specified via the Generate token class option. The purpose of this method is to generate an access token to return to the user.

    In the default class (%OAuth2.Server.GenerateOpens in a new tab), this method generates an access token that is an opaque string. Caché also provides an alternative class (%OAuth2.Server.JWTOpens in a new tab), in which GenerateAccessToken() generates an access token that is a JWT.

Default Classes

This section describes the default classes in a Caché authorization server, as well as the class %OAuth2.Server.JWTOpens in a new tab, which is provided as another option for the Generate token class.

%OAuth2.Server.Authenticate (Default for Authenticate Class)

The class %OAuth2.Server.AuthenticateOpens in a new tab defines the following methods, listed in the order in which they are called:

  • BeforeAuthenticate() is a stub. It simply quits with an OK status.

  • DisplayLogin() writes the HTML that creates a simple login page with Login and Cancel buttons.

  • DisplayPermissions() writes the HTML that creates a simple page that displays the requested permissions. This page includes the buttons Accept and Cancel.

  • AfterAuthenticate() is a stub. It simply quits with an OK status.

%OAuth2.Server.Validate (Default for Validate User Class)

The %OAuth2.Server.ValidateOpens in a new tab class is the default class for the Validate user class option.

Note:

This class is provided for sample purposes and is very unlikely to be suitable for production use. That is, InterSystems expects that customers will replace or subclass this class for their own needs.

This class defines the following sample methods:

  • ValidateUser() does the following:

    1. Looks for the given user in the CACHESYS database.

    2. Verifies the password for the user.

    3. Gets a multidimensional array that contains information about the user.

    4. Uses this array to add additional claims to the properties object.

  • SupportedClaims() returns a $LIST of claims that are supported by this authorization server. By default, this method specifically returns the list of claims defined by OpenID Connect CoreOpens in a new tab.

  • ValidateClient() (used by the client credentials grant type) accepts all clients and adds no properties.

You can override all these methods in your subclass.

OAuth2.Server.Session (Default for Session Class)

The %OAuth2.Server.Session class is the default class for the Session maintenance class option. This class maintains sessions via an HTTP-only cookie.

In this class, the GetUser() method tries to access the current session. If there is a session, the method obtains the username from that session and returns that. If there is no session, the method returns the username as an empty string and also returns an error status as output.

For additional information on this class, see the class reference.

%OAuth2.Server.Generate (Default for Generate Token Class)

The %OAuth2.Server.GenerateOpens in a new tab class is the default class for the Generate token class option. This class defines the following methods:

  • GenerateAccessToken() generates a random string as the opaque access token.

  • IsJWT() returns 0.

%OAuth2.Server.JWT (Another Option for Generate Access Token Class)

The %OAuth2.Server.JWTOpens in a new tab class is another class you can use (or subclass) for the Generate token class option. This class defines the following methods:

  • GenerateAccessToken() returns a JWT. Before returning the JWT, Caché signs it, encrypts it, or both, according to the JSON Web Token (JWT) Settings in the authorization server configuration.

  • IsJWT() returns 1.

  • CreateJWT() creates a JWT based on a JSON object containing the claims; signs and encrypts the JWT as specified in the authorization server configuration. This method follows the specifications for OAuth 2.0 and OpenID Connect usage and should not be overridden in a subclass.

  • AddClaims() — Adds the requested claims to the JWT. This method is as follows:

    ClassMethod AddClaims(claims As %ArrayOfObjects, 
                          properties As %OAuth2.Server.Properties, 
                          json As %DynamicObject)
    

    Where:

Implementing the Custom Methods for the Caché Authorization Server

To customize the behavior of the authorization server, define classes as described in “Code Customization Options.” Then use this section for information on defining methods in those classes, depending on the processing steps that you want to customize.

  1. Optional custom processing before authentication

  2. Identifying the user

  3. Validating the user and specifying claims

  4. Optionally displaying permissions to the user

  5. Optional custom processing after authentication

  6. Generating the access token

After these subsections, a final subsection describes how to validate the client, in the case when this server must support the client credentials grant type. The client credentials grant type does not use steps 2 – 4 of the preceding list.

Optional Custom Processing Before Authentication

The information here applies to all grant types.

To perform custom processing before authenticating the user, implement the BeforeAuthenticate() method of the Authenticate class. This method has the following signature:

ClassMethod BeforeAuthenticate(scope As %ArrayOfDataTypes, 
                               properties As %OAuth2.Server.Properties) As %Status

Where:

In your method, optionally modify either or both of these arguments, both of which are later passed to the methods used to identify the user. The method must return a %StatusOpens in a new tab.

Normally, there is no need to implement this method. However, one use case is to implement the launch and launch/patient scopes used by FHIR®, where the scope needs to be adjusted to include a specific patient.

Identifying the User

The information here applies only to the authorization code and implicit grant types.

To identify the user, implement the DisplayLogin() method of the Authenticate class. The DisplayLogin() method has the following signature:

ClassMethod DisplayLogin(authorizationCode As %String, 
                         scope As %ArrayOfDataTypes, 
                         properties As %OAuth2.Server.Properties, 
                         loginCount As %Integer = 1) As %Status

Where:

  • authorizationCode

  • scope is an instance of %ArrayOfDataTypesOpens in a new tab that contains the scopes contained in the original client request, possibly modified by the BeforeAuthenticate() method. The array keys are the scope values and the array values are the corresponding display forms of the scope values.

  • properties is an instance of %OAuth2.Server.PropertiesOpens in a new tab that contains properties and claims received by the authorization server and modified by methods earlier in the processing. See “Details for the %OAuth2.Server.Properties Object.”

  • loginCount is the integer count of which login attempt is taking place.

This method is responsible for writing the HTML to display the user login form. The login form must contain a Username field, a Password field, and an AuthorizationCode field (which should be hidden). The default DisplayLogin() method uses of the InsertHiddenField() method of %CSP.PageOpens in a new tab to add the AuthorizationCode hidden field.

Typically, the form also has buttons with the values Login and Cancel. These buttons should submit the form. If the user submits the form with the Login button, the method will accept the username and password. If the user submits the form with the Cancel button, the authorization process will terminate with an error return of access_denied.

In your implementation, you might choose to display permissions on the same page. In that case, your method would display the scopes and would use a button named Accept to submit the page.

The method must return a %StatusOpens in a new tab.

Updating properties.CustomProperties

If the form contains elements with names that start p_, such elements receive special handling. After the DisplayLogin() method returns, Caché adds values of those elements to the properties.CustomProperties array, first removing the p_ prefix from the names. For example, if the form contains an element named p_addme, then Caché adds addme (and the value of the p_addme element) to the properties.CustomProperties array.

Your method can also directly set other properties of properties as needed.

Validating the User and Specifying Claims

The information here applies to all grant types other than the client credentials grant type. (For that grant type, see “Validating the Client.”)

To validate the user and specify any claims to be returned by the token, Userinfo, and token introspection endpoints, define the ValidateUser() method of the Validate user class. This method has the following signature:

ClassMethod ValidateUser(username As %String, 
                         password As %String, 
                         scope As %ArrayOfDataTypes, 
                         properties As %OAuth2.Server.Properties, 
                         Output sc As %Status) As %Boolean

Where:

  • username is the username provided by the user.

  • password is the password provided by the user. Note that if the user has already logged in, Caché calls this method with password as an empty string. This means that your method should detect when password is an empty string and not attempt to check the password in that case.

  • scope is an instance of %ArrayOfDataTypesOpens in a new tab that contains the scopes contained in the original client request, possibly modified by the BeforeAuthenticate() method. The array keys are the scope values and the array values are the corresponding display forms of the scope values.

  • properties is an instance of %OAuth2.Server.PropertiesOpens in a new tab that contains properties and claims received by the authorization server and modified by methods earlier in the processing. See “Details for the %OAuth2.Server.Properties Object.”

  • sc is the status code set by this method. Use this to communicate details of any errors.

Your method should do the following:

  • Make sure that the password applies to the given username.

  • Use the scope and properties arguments as needed for your business needs.

  • Modify the properties object to specify any claim values, as needed, or to add new claims. For example:

    // Setup claims for profile and email OpenID Connect scopes.
    Do properties.SetClaimValue("sub",username)
    Do properties.SetClaimValue("preferred_username",username)
    Do properties.SetClaimValue("email",email)
    Do properties.SetClaimValue("email_verified",0,"boolean")
    Do properties.SetClaimValue("name",fullname)
    
    
  • In the case of any errors, set the sc variable.

  • Return 1 if the user is considered valid; return 0 in all other cases.

Note that after the return from ValidateUser(), the authorization server automatically sets the following values in the properties object, if these values are missing:

  • In properties.ClaimValues:

    • iss — URL of authorization server

    • subclient_id

    • exp — expiration time in seconds since December 31, 1840

  • In properties.CustomProperties:

    • client_idclient_id of the requesting client

Displaying Permissions

The information here applies only to the authorization code and implicit grant types.

To display permissions after validating the user, implement the DisplayPermissions() method of the Authenticate class. This method has the following signature:

ClassMethod DisplayPermissions(authorizationCode As %String, 
                               scopeArray As %ArrayOfDataTypes, 
                               currentScopeArray As %ArrayOfDataTypes, 
                               properties As %OAuth2.Server.Properties) As %Status

Where:

  • authorizationCode is the authorization code.

  • scopeArray represents the newly requested scopes, for which the user has not yet granted permission. This argument is an instance of %ArrayOfDataTypesOpens in a new tab.

    The array keys are the scope values and the array values are the corresponding display forms of the scope values.

  • currentScopeArray represents the scopes for which the user has previously granted permission. This argument is an instance of %ArrayOfDataTypesOpens in a new tab.

    The array keys are the scope values and the array values are the corresponding display forms of the scope values.

  • properties is an instance of %OAuth2.Server.PropertiesOpens in a new tab that contains properties and claims received by the authorization server and modified by methods earlier in the processing. See “Details for the %OAuth2.Server.Properties Object.”

This form must have buttons with the values Accept and Cancel. These buttons should submit the form. If the user submits the form with the Accept button, the method should continue with authorization. If the user submits the form with the Cancel button, the authorization process should terminate.

Optional Custom Processing After Authentication

The information here applies to all grant types.

To perform custom processing after authentication, implement the AfterAuthenticate() method of the Authenticate class. This method has the following signature:

ClassMethod AfterAuthenticate(scope As %ArrayOfDataTypes, properties As %OAuth2.Server.Properties) As %Status

Where:

In your method, optionally modify either or both of these arguments. In particular, you may want to may add properties to the authentication HTTP response; to do so add properties to properties.ResponseProperties.

Normally, there is no need to implement this method. However, one use case is to implement the launch and launch/patient scopes used by FHIR®, where it is necessary to adjust the scope to include a specific patient.

Generating the Access Token

The information here applies to all grant types.

To generate access tokens, implement the GenerateAccessToken() method of the Generate token class. This method has the following signature:

ClassMethod GenerateAccessToken(properties As %OAuth2.Server.Properties, Output sc As %Status) As %String

Where:

The method should return the access token. The access token may be based on the properties argument. In your method, you might also want to add claims to the JSON response object. To do so, set the ResponseProperties array property of the properties object.

Validating the Client

The information here applies only to the client credentials type.

To validate the client credentials and specify any claims to be returned by the token, Userinfo, and token introspection endpoints, define the ValidateClient() method of the Validate user class. This method has the following signature:

ClassMethod ValidateClient(clientId As %String, 
                           clientSecret As %String, 
                           scope As %ArrayOfDataTypes, 
                           Output properties As %OAuth2.Server.Properties, 
                           Output sc As %Status) As %Boolean

Where:

  • clientId is the client ID.

  • clientSecret is the client secret.

  • scope is an instance of %ArrayOfDataTypesOpens in a new tab that contains the scopes contained in the original client request, possibly modified by the BeforeAuthenticate() method. The array keys are the scope values and the array values are the corresponding display forms of the scope values.

  • properties is an instance of %OAuth2.Server.PropertiesOpens in a new tab that contains properties and claims received by the authorization server and modified by methods earlier in the processing. See “Details for the %OAuth2.Server.Properties Object.”

  • sc is the status code set by this method. Use this to communicate details of any errors.

Your method should do the following:

  • Make sure that the client secret applies to the given client ID.

  • Use the scope and properties arguments as needed for your business needs.

  • Modify the properties object to specify any claim values, as needed. For example:

    // Setup claims for profile and email OpenID Connect scopes.
    Do properties.SetClaimValue("sub",username)
    Do properties.SetClaimValue("preferred_username",username)
    Do properties.SetClaimValue("email",email)
    Do properties.SetClaimValue("email_verified",0,"boolean")
    Do properties.SetClaimValue("name",fullname)
    
    
  • In the case of any errors, set the sc variable.

  • Return 1 if the user is considered valid; return 0 in all other cases.

Note that after the return from ValidateClient(), the authorization server automatically sets the following values in the properties object, if these values are missing:

  • In properties.ClaimValues:

    • iss — URL of authorization server

    • subclient_id

    • exp — expiration time in seconds since December 31, 1840

  • In properties.CustomProperties:

    • client_idclient_id of the requesting client

Details for the %OAuth2.Server.Properties Object

The methods described in the previous section use the argument properties, which is an instance of %OAuth2.Server.PropertiesOpens in a new tab. The %OAuth2.Server.PropertiesOpens in a new tab class is intended to hold information that needs to be passed from method to method within the authorization server code. This section describes the basic properties in this class, as well as the properties related to claims. The class also has methods for working with claims; the last subsection describes them.

Basic Properties

The %OAuth2.Server.PropertiesOpens in a new tab class has the following basic properties, used to convey information for any internal processing of your custom code:

RequestProperties
Property RequestProperties as array of %String (MAXLEN=16384);

Contains the query parameters from the authorization request.

Because this property is an array, use the usual array interface to work with it. (The same comment applies to the other properties of this class.) For example, to get the value of a query parameter, use RequestProperties.GetAt(parmname), where parmname is the name of the query parameter.

ResponseProperties
Property ResponseProperties as array of %String (MAXLEN=1024);

Contains any properties to be added to the JSON response object to a token request. Set this property as needed.

CustomProperties
Property CustomProperties as array of %String (MAXLEN=1024);

Contains any custom properties to be used to communicate between various pieces of customization code. See the section “Updating properties.CustomProperties.”

ServerProperties
Property ServerProperties as array of %String (MAXLEN=1024);

Contains any properties that the authorization server chooses to share with the customization code. The logo_uri, client_uri, policy_uri and tos_uri client properties are shared in this way for use by the Authentication Class.

Properties Related to Claims

The %OAuth2.Server.PropertiesOpens in a new tab class contains the IntrospectionClaims, IDTokenClaims, UserinfoClaims, and JWTClaims properties, which carry information about required claims, specifically custom claims.

The class also contains the ClaimValues property, which carries the actual claim values. Your customization code should set the values of the claims (typically in the ValidateUser class).

The following list describes these properties:

IntrospectionClaims
Property IntrospectionClaims as array of %OAuth2.Server.Claim;

Specifies the claims to be returned by the Introspection endpoint (beyond the base required claims). The authorization server will return the scope, client_id, username, token_type, exp, iat, nbf, sub, aud, iss, and jti claims even if they are not in this property.

In most cases, the value of this property can be an empty string; this property is included to support the claims request parameter (see OpenID Connect CoreOpens in a new tab section 5.5 for details).

Formally, this property is an array in which the array key is the claim name (which matches the name in the ClaimValues property) and the array value is an instance of %OAuth2.Server.ClaimOpens in a new tab. The %OAuth2.Server.ClaimOpens in a new tab class has the following properties:

  • Essential

    property Essential as %Boolean [ InitialExpression = 0 ];
    

    Specifies whether the claim is essential or voluntary. The value 1 means essential and the value 0 means voluntary.

  • Values

    property Values as list of %String(MAXLEN=2048);
    

    Specifies the list of permissible values for this claim.

The value of the claims will usually be set by the ValidateUser class.

IDTokenClaims
Property IDTokenClaims as array of %OAuth2.Server.Claim;

Specifies the claims that the authorization server requires in the IDToken (beyond the base set of required claims). The authorization server requires the iss, sub, exp, aud, and azp claims even if these claims are not in this property.

This property is an array of objects; for details, see the entry for the IntrospectionClaims property.

In most cases, the value of this property can be an empty string; this property is included to support the claims request parameter (see OpenID Connect CoreOpens in a new tab section 5.5 for details).

UserinfoClaims
Property UserinfoClaims as array of %OAuth2.Server.Claim;

Specifies the claims to be returned by the Userinfo endpoint (beyond the base required claims). The authorization server will return the sub claim even if that claim is not in this property.

In most cases, the value of this property can be an empty string; this property is provided to support section 5.5 of OpenID Connect Core.

This property is an array of objects; for details, see the entry for the IntrospectionClaims property.

The claims are defined based on the scope and request claims parameter. The value to be returned for the claim will have the same key in the ClaimValues property. The value of the claims will usually be set by the ValidateUser class.

JWTClaims
Property JWTClaims as array of %OAuth2.Server.Claim;

Specifies the claims that are needed for the JWT access token that is returned by the default JWT-based access token class (%OAuth2.Server.JWTOpens in a new tab) beyond the base set of required claims. The authorization server will return the iss, sub, exp, aud, and jti claims even if they are not in this property.

This property is an array of objects; for details, see the entry for the IntrospectionClaims property.

The claims are defined by the customization code. The value of the claims will usually be set by the ValidateUser class.

ClaimValues
property ClaimValues as array of %String(MAXLEN=1024);

Specifies the actual claim values and their types. To work with this property, use the methods in the next section.

If you need to work with this property directly, note that this property is an array in which:

  • The array key is the claim name.

  • The array value has the form $LISTBUILD(type,value), where type holds the type of the value, and value holds the actual value. The type can be "string", "boolean", "number", or "object". If type is "object", then value is a JSON object serialized as a string.

    Note that value can be a $LIST structure. In this case, when the claim value is serialized, it is serialized as a JSON array, in which each array item has the given type.

Methods for Working with Claims

The %OAuth2.Server.PropertiesOpens in a new tab class also provides instance methods that you can use to work with that simplify working with the ClaimValues property.

SetClaimValue()
Method SetClaimValue(name As %String, value As %String, type As %String = "string")

Updates the ClaimValues property by setting the value of the claim named by the name argument. The type argument indicates the type of the claim: "string" (the default) , "boolean", "number", or "object". If type is "object", then value must be a JSON object serialized as a string.

Note that value can be a $LIST structure. In this case, when the claim value is serialized, it is serialized as a JSON array, in which each array item has the given type.

RemoveClaimValue()
Method RemoveClaimValue(name As %String)

Updates the ClaimValues property by removing the claim named by the name argument.

GetClaimValue()
Method GetClaimValue(name As %String, output type) As %String

Examines the ClaimValues property and returns the value of the claim named by the name argument. The type argument, which is returned as output, indicates the type of the claim; see SetClaimValue().

NextClaimValue()
Method NextClaimValue(name As %String) As %String

Returns the name of the next claim (in the ClaimValues property) after the given claim.

Locations of the Authorization Server Endpoints

When you use a Caché instance as an OAuth 2.0 authorization server, the URLs for the authorization endpoints are as follows:

Endpoint URL
Issuer endpoint https://serveraddress/oauth2
Authorization endpoint https://serveraddress/oauth2/authorize
Token endpoint https://serveraddress/oauth2/token
Userinfo endpoint https://serveraddress/oauth2/userinfo
Token introspection endpoint https://serveraddress/oauth2/introspection
Token revocation endpoint https://serveraddress/oauth2/revocation

In all cases, serveraddress is the IP address or host name of the server on which the Caché instance is running.

Creating Client Definitions on a Caché OAuth 2.0 Authorization Server

This section describes how to create a client definition on a Caché OAuth 2.0 authorization server, if you have not registered the client dynamically. First, set up the Caché OAuth 2.0 authorization server as described earlier in this chapter. Then use the Management Portal to do the following:

  1. Select System Administration > Security > OAuth 2.0 > Server Configuration.

  2. Click the Client Configurations button to view the client descriptions. This table is initially empty.

  3. On the General tab, specify the following details:

    • Name — Specify the unique name of this client.

    • Description — Specify an optional description.

    • Client type — Specify the type of this client. The choices are public (a public client, per RFC 6749Opens in a new tab), confidential (a confidential client, per RFC 6749), and resource (a resource server which is not also a client).

    • Redirect URLs — One or more expected redirect URLs for this client.

    • Supported grant types — Specify the grant types that this client can use to create an access token. Select at least one.

    • Supported response types — Select the OAuth 2.0 response_type values that the Client will restrict itself to using.

    • Authentication type — Select the type of authentication (as specified in RFC 6749Opens in a new tab or OpenID Connect Core section 9Opens in a new tab) to be used for HTTP requests to the authorization server. Select one of the following:

      • none

      • basic

      • form encoded body

      • client secret JWT

      • private key JWT

    • Authentication signing algorithm — Select the algorithm that must be used for signing the JWTs used to authenticate this client at the token endpoint (if the authentication type is client secret JWT or private key JWT). If you do not select an option, any algorithm supported by the OpenID provider and the relying party may be used.

  4. If needed, select the Client Credentials tab and view the following details:

    • Client ID — Client ID as specified in RFC 6749. Caché generates this string.

    • Client secret — Client secret as specified in RFC 6749. Caché generates this string.

  5. On the Client Information tab, specify the following details:

    • Launch URL — Specify the URL used to launch this client. In some circumstances, this value can be used to identify the client and can be used as the value of the aud claim.

    • Authorization display section:

      • Client name — Specify the name of the client to be presented to the end user.

      • Logo URL — Specify a URL that references a logo for the client application. If you specify this option, the authorization server displays this image to the end user during approval. The value of this field must point to a valid image file.

      • Client home page — Specify the URL of the home page of the client. The value of this field must point to a valid web page. If you specify this option, the authorization server displays this URL to the end user in a followable fashion.

      • Policy URL — Specify the URL that the Relying Party Client provides to the end user to read about the how the profile data will be used. The value of this field must point to a valid web page.

      • Terms of service URL — Specify the URL that the Relying Party Client provides to the end user to read about the Relying Party's terms of service. The value of this field must point to a valid web page.

    • Contact emails — Comma-separated list of email addresses suitable for use in contacting those responsible for the client application.

    • Default max age — Specify the default maximum authentication age, in seconds. If you specify this option, the end user must be actively re-authenticated when the maximum authentication age is reached. The max_age request parameter overrides this default value. If you omit this option, there is no default maximum authentication age.

    • Default scope — Specify the default scope, as a blank separated list, for access token requests.

  6. On the JWT Settings tab, specify the following details:

    • JSON Web Token (JWT) Settings — Specifies the source of the public keys that the client uses to verify signatures of JWTs from the authorization server and to encrypt JWTs sent to the authorization server.

      By default, the dynamic registration process generates a pair of JWKSs (JSON web key sets). One JWKS is private and contains all the needed private keys (per algorithm) as well as the client secret for use as a symmetric key; this JWKS is never shared. The other JWKS contains the corresponding public keys and is publicly available. The dynamic registration process also copies the public JWKS to the client.

      The other options are as follows:

      To access any of these options, first select Source other than dynamic registration.

  7. Select Save.

Rotating Keys Used for JWTs

In most cases, you can cause the authorization server to generate new public/private key pairs; this applies only to the RSA keys used for the asymmetric RS256, RS384, and RS512 algorithms. (The exception is if you specify Source other than dynamic registration as X509 certificate. In this case, it is not possible to generate new keys.)

Generating new public/private key pairs is known as key rotation; this process adds new private RSA keys and associated public RSA keys to the private and public JWKSs.

When you perform key rotation on the authorization server, the authorization server uses the new private RSA keys to sign JWTs to be sent to the clients. Similarly, the authorization server uses the new public RSA keys to encrypt JWTs to be sent to the clients. To decrypt JWTs received from the clients, the authorization server uses the new RSA keys, and if that fails, uses the old RSA keys; thus the server can decrypt a JWT that was created using its old public RSA keys.

Last, if the authorization server cannot verify a signed JWT received from a client, then if the authorization server has the URL for the client public JWKS, the authorization server obtains a new public JWKS and tries again to verify the signature. (Note that the authorization server has a URL for the client public JWKS if you used dynamic discovery or if the configuration specified the JWKS from URL option; otherwise, the authorization server does not have this URL.)

To rotate keys for the authorization server:

  1. Select System Administration > Security > OAuth 2.0 > Server Configuration.

    The system displays the configuration for the authorization server.

  2. Select the Rotate Keys button.

Note:

The symmetric HS256, HS384, and HS512 algorithms always use the client secret as the symmetric key.

API for Key Rotation on the Authorization Server

To rotate keys programmatically on the authorization server, call the RotateKeys() method of OAuth2.Server.ConfigurationOpens in a new tab.

To obtain a new client JWKS, call the UpdateJWKS() method of OAuth2.Server.ClientOpens in a new tab.

For details on these methods, see the class reference.

Getting a New Public JWKS from a Client

In most cases, a client generates a public/private pair of JWKSs. There are different ways in which the authorization server can receive the public JWKS. One way is for the client to provide the public JWKS at a URL; see the JWKS from URL option in “Creating Client Definitions on a Caché OAuth 2.0 Authorization Server.”

If the client was defined with JWKS from URL and if the client generates a new pair of JWKSs, you can cause the authorization server to obtain the new public JWKS from the same URL. To do so:

  1. In the Management Portal, select System Administration > Security > OAuth 2.0 > Server Configuration.

    The system displays the configuration for the authorization server.

  2. Select the Update JWKS button.

If the client was not defined with JWKS from URL and if the client generates a new pair of JWKSs, it is necessary to obtain the public JWKS, send it to the authorization server, and load it from a file.

FeedbackOpens in a new tab