Using OAuth 2.0 and OpenID Connect with Caché
Using a Caché Web Application as an OAuth 2.0 Resource Server
[Home] [Back] [Next]
InterSystems: The power behind what matters   
Class Reference   
Search:    

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:
Configuration Requirements
See Configuration Requirements in the previous chapter, with the following changes when you create the client configuration:
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
    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
    The arguments are as follows:
  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
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.