Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Trusting CDS Clients

Dennis Patterson edited this page Apr 9, 2020 · 4 revisions

CDS Clients must assert their identify when invoking service endpoints by providing a Bearer token in the Authorization header:

Authorization:  Bearer {{JWT}}

As with CORS support, we'll accomplish this by using application-level middleware so we can inspect each request as it comes in. To help with early sections of the tutorial, we'll start out by not requiring a valid token and revisit when we get to the Exercises.

Let's look at the first section of logic:

if (request.method === 'OPTIONS') {
  next();
  return;
}

OPTIONS requests are part of browser preflight requests checking if the CORS protocol is understood. Since we're concerned with authorization for GET and POST methods, we'll allow OPTIONS requests to pass to the next level of middleware.

Now we can get to the section where we'd start authorization logic. The first thing to check is the presence of an Authorization request header. This section contains logic to return a 401 with a WWW-Authenticate response header if no token is supplied. However, as mentioned earlier, we want to allow the ability to call the APIs directly during troubleshooting so this section also defaults a placeholder Bearer token.

const serviceHost = request.get('Host');
const authorizationHeader = request.get('Authorization') || 'Bearer open'; // Default a token until ready to enable auth.

if (!authorizationHeader || !authorizationHeader.startsWith('Bearer')) {
  response.set('WWW-Authenticate', `Bearer realm="${serviceHost}", error="invalid_token", error_description="No Bearer token provided."`)
  return response.status(401).end();
}

If the call has made it this far, we know it contains a token prefixed with Bearer. The next step would be to capture the JWT itself, build the expected aud claim, and leave a placeholder for where our token validation will live.

const token = authorizationHeader.replace('Bearer ', '');
const aud = `${request.protocol}://${serviceHost}${request.originalUrl}`;

const isValid = true; // Verify token validity per https://cds-hooks.org/specification/current/#trusting-cds-client

if (!isValid) {
  response.set('WWW-Authenticate', `Bearer realm="${serviceHost}", error="invalid_token", error_description="The token is invalid."`)
  return response.status(401).end();
}

next();

When you are building your CDS Service for production, you'll want to carefully consider how you implement your authorization logic and how you whitelist which CDS Clients can call your services.

Read up on the following resources for additional information:

Next Step: Discovery Endpoint