Skip to main content
Previous sectionNext section

Using a Caché Web Application as an OAuth 2.0 Resource Server

This chapter describes how to use a Caché web application as a resource server that uses the OAuth 2.0 framework. It discusses the following:

This chapter primarily discusses the scenario in which the resource server uses the introspection endpoint of the authorization server. See the last section for details on variations.

See the previous chapter for information on rotating keys used for signing, encryption, signature verification, and decryption of JWTs.

Prerequisites for the Caché Resource Server

Before starting the tasks described in this chapter, make sure the following items are available:

  • An OAuth 2 authorization server.

  • If the resource server uses any endpoint of the authorization server, the resource server may be registered as a client of the OAuth 2.0 authorization server. The details depend upon the implementation of the authorization server.

    In this case, you will also later need to know specific details about this server:

    • Location of the authorization server (issuer endpoint)

    • Location of the token endpoint

    • Location of the Userinfo endpoint (if supported; see OpenID Connect Core)

    • Location of the token introspection endpoint (if supported; see RFC 7662)

    • Location of the token revocation endpoint (if supported; see RFC 7009)

    • Whether the authorization server supports dynamic registration

  • If the authorization server does not support dynamic registration, you will need the client ID and client secret for the resource server. The authorization server generates these two pieces of information (on a one-time basis) and you need to get them securely to the resource server machine.

Configuration Requirements

See “Configuration Requirements” in the previous chapter, with the following changes when you create the client configuration:

  • For Application name, specify the application name of the resource server.

  • For Client Type, specify Resource Server.

    Note that when you specify Resource Server as the type, the configuration page displays only the options that are applicable to a resource server.

  • For clientID, use the client ID of the resource server.

  • For clientSecret, use the client secret of the resource server.

Code Requirements

An OAuth 2.0 resource server receives a request, examines the access token that it contains, and (depending on the access token) returns the requested information.

To create a Caché resource server, create a CSP page in the namespace used by the resource server’s web application. (Because this page needs only to define a callback method and the page is never visible to users, there is no reason to use Zen or Zen Mojo.) Specifically, InterSystems suggests creating a subclass of %CSP.REST.

In this CSP page, implement the OnPage() method. (Or if you have created a subclass of %CSP.REST, create a URL map and the corresponding methods.)

In the OnPage() method (or in the applicable REST method), do the following:

  1. Call the method GetAccessTokenFromRequest() of %SYS.OAuth2.AccessToken. This method is as follows:

    ClassMethod GetAccessTokenFromRequest(Output sc As %Status) As %String
    Copy code to clipboard

    The method returns the access token, if any, found in the HTTP request received by this page. It uses one of the three RFC 6750 formats. The parameter sc, returned as output, is a status code that indicates whether an error was detected. If the request did not use SSL/TLS, that is an error condition. Also, if the request did not include a valid bearer header, that is an error condition.

  2. Check to see whether the status code is an error.

    If the status is an error, the method should return a suitable error (and not return the requested information).

  3. If the status code is not an error, validate the access token. To do so, use ValidateJWT() or your own custom method. See “Method Details,” in the previous chapter.

  4. Optionally call the GetIntrospection() method for additional information. This method calls the introspection endpoint of the authorization server and obtains claims about the access token. This method is as follows:

    ClassMethod GetIntrospection(applicationName As %String, 
                                 accessToken As %String, 
                                 Output jsonObject As %RegisteredObject) As %Status
    Copy code to clipboard

    The arguments are as follows:

    • applicationName is the name of the client application.

    • accessToken is the access token previously returned.

    • jsonObject, which is returned as output, is a JSON object that contains the claims that the authorization server makes about this access token.

  5. If the preceding steps indicate that the user’s request for information should be granted, perform the requested processing and return the requested information.

For example:

    // This is a dummy resource server which just gets the access token from the request
    // and uses the introspection endpoint to ensure that the access token is valid.
    // Normally the response would not be security related, but would ocntain some interesting
    // data based on the request parameters.
    set accessToken=##class(%SYS.OAuth2.AccessToken).GetAccessTokenFromRequest(.sc)
    if $$$ISOK(sc) {
        set sc=##class(%SYS.OAuth2.AccessToken).GetIntrospection("demo resource",accessToken,.jsonObject)
        if $$$ISOK(sc) {
            write "OAuth 2.0 access token used to authorize resource server (RFC 6749)<br>"
            write "Access token validated using introspection endpoint (RFC 7662)<br>"
            write "   scope='"_jsonObject.scope_"'<br>"
            write "   user='"_jsonObject.username_"'",!
        } else {
            write "Introspection Error="_..EscapeHTML($system.Status.GetErrorText(sc)),!
        }
    } else {
        write "Error Getting Access Token="_$system.Status.GetErrorText(sc),!
    }
    
    Quit $$$OK
Copy code to clipboard

Variations

This chapter primarily discusses the scenario in which the Caché resource server uses the introspection endpoint of the authorization server. This section discusses some possible variations.

Variation: Resource Server Calls Userinfo Endpoint

The resource server can also call the Userinfo endpoint. To do so, the resource server code must use the GetUserinfo() method, discussed in the previous chapter.

Variation: Resource Server Does Not Call Endpoints

If the Caché resource server does not use any endpoints of the authorization server, it is not necessary to create an OAuth 2.0 configuration on this machine.

Also, the resource server does not need to use GetAccessTokenFromRequest(). Instead, it can get the access token directly from the HTTP authorization header and use it as needed.