Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

SAP Developer Challenge - APIs - Task 9 - Create a service key for API endpoints and auth info

qmacro
Developer Advocate
Developer Advocate

(Check out the SAP Developer Challenge - APIs blog post for everything you need to know about the challenge to which this task relates!)

This task follows on from the previous task and moves you one step closer in your steady journey of enlightenment, moving towards calling an API endpoint on SAP BTP.

Background

In the previous task, you created an instance of the SAP Cloud Management Service. Why? Because this service provides facilities to manage resources on SAP BTP, and those facilities include the APIs you've been learning about in previous tasks in this group. But merely having an instance of the service isn't going to get you far.

To consume a service's facilities, more is needed. In an application context, an app is bound to a service instance, and, once bound, can consume those facilities. The same goes for API calls. What's needed are a couple of things - endpoint information and credential information.

So. You've done step 1 of the steps introduced in the previous task. Now you're tackling step 2.

  1. create an instance of the SAP Cloud Management Service, with a plan that contains the appropriate scope(s) that you need
  2. create a service key based on that instance
  3. use the details in the service key to request an access token
  4. use the access token thus obtained to authenticate a call to the API endpoint

Endpoint information

First, you need some information on the API endpoints. This is because information you found on the SAP Business Accelerator Hub for the endpoint you're going to call:

GET /accounts/v1/directories/{directoryGUID}

only presents a relative path (/accounts/v1/directories/{directoryGUID}). For it to be a callable endpoint it needs of course to be prefixed with the rest of the URL - the scheme and fully qualified domain name, at least.

To be precise, the http (or https) part of a URL is known as the "scheme". See the List of URI schemes Wikipedia page for more information. And while we're in precision mode, are you wondering about the difference between URL and URI? They're not the same. URLs are a subset of URIs. A URI (Uniform Resource Identifier) is just a string that identifies a resource. A URL (Uniform Resource Locator) identifies a resource, but also allows you to locate that resource. Yes, the clue really is in the name(s) 🙂

Credential information

As well as endpoint information, you also need access, in the form of authentication. What form that takes, and how it's used, is sometime service-specific. But generally there will be a requirement to provide credentials in the API call itself.

You've done this already in a previous task, in that you provided an API key in an "APIKey" header, when you made the call to the country date format API endpoint in Task 5 - Call the country date format API endpoint

More commonly, the standard Authorization HTTP header is used to convey the credentials. The value for this header is usually made up of two parts, and formed like this:

Authorization: <auth scheme> <auth details>

In the bad (good?) old days, you may well have used Basic Authentication, i.e. provided a username and password, joined with a colon, and encoded in Base64. Here's an example of that:

Authorization: Basic d2VsbC1kb25lOnlvdXItY3VyaW9zaXR5LWlzLWdyZWF0IQ==

Note that encoding != encrypting, which means that this approach was somewhat insecure, in that anyone who could see the HTTP request headers could obtain those credentials. Moreover, obtaining credentials as fundamental as username and password means a world of pain if they are ever compromised.

This is why OAuth, which focuses on obtaining and using tokens as credentials, is a far better approach for managing the request and use of credentials. Generally, tokens are obtained up front (sometimes requiring username and password style information) and then also eventually expire (they can be refreshed using a similar but simpler approach to the original way they were obtained). Expired tokens are no use to anyone, and if a token is compromised, it can be expired a lot easier, and with far fewer side effects (on other consumers using the same credential approach) than expiring or invalidating a compromised username and password.

Anyway, getting back to this Authorization header, there are other more secure auth schemes that are standard and used with this header, and you'll be working towards using such a scheme in the next task.

Service keys

This endpoint and credential information, essential to consume a service's facilities, is provisioned in so-called "service keys", that relate to an instance of a service.

Creating a service key effectively brings about the creation of credentials that are then valid for use by the consumer. Once a service key has been created, it can be retrieved, and will contain the credentials, plus information on the endpoints.

When an app is bound to a service instance, similar information is created (this is why one can equate the term "service key" with "binding" and why different cloud platform runtimes use these terms almost interchangeably).

Your task

Your task, then, is to create a service key for the instance of the SAP Cloud Management Service you created in the previous task. You should use the cf CLI to do this. You'll have to give the service key a name; it doesn't really matter too much what you call it; the name "sk" will do fine for the purpose of this task, but in the end, you can choose.

Once you have created a service key, you should retrieve it, and take a look at the information, which will be in JSON. You'll need to compose a value (to send to the hash service) based on some of the property names in this JSON data.

That value should be a sorted list of the endpoint property names (not their values), separated by commas. To be clear, these endpoint property names are the keys of the key/value pairs inside the credentials.endpoints node, and they all end in _url.

Once you have composed that value, you should hash it and share as a new reply to this discussion thread, as always, and as described in Task 0.

Oh, and while it's not part of this task's requirements, you might as well save the JSON in in a file, too, because you're going to need it again in the next task!

Hints and tips

You're strongly encouraged to use the cf CLI for this task. This is for the usual obvious reasons, which are:

  • the command line is an extremely powerful and flexible environment
  • using and combining tools in a command line (shell) context is the ultimate in power and flexibility
  • you can script usage of such tools, embracing the facilities of the command line to build automation
  • it helps you get closer to the metal, to explore the details of the services and runtimes you're consuming

If, however, you do wish to use the GUI, in the form of the SAP BTP Cockpit, then go ahead. The cockpit, or any GUI for that matter, is great for one-off and occasional tasks, but it's no match for the power of the command line. You may wish to read the blog post Managing resources on SAP BTP – what tool do I choose? which touches on this topic.

If you're using the cf CLI, you'll want to avail yourself of the commands within the "Services integration" section.

Services integration:
  marketplace,m        create-user-provided-service,cups
  services,s           update-user-provided-service,uups
  create-service,cs    create-service-key,csk
  update-service       delete-service-key,dsk
  delete-service,ds    service-keys,sk  service              service-key
  bind-service,bs      bind-route-service,brs
  unbind-service,us    unbind-route-service,urs

Note that once you've created your service key, and are looking at its output with:

cf service-key <service-instance> <service-key>

you'll notice that the output is JSON. Great! You can parse it and programatically generate the value you need to send to the hash service for your task reply.

However, note that the command is not entirely well-behaved, emitting "helpful" information just before the JSON itself. This is ultimately against the spirit of the UNIX command line philosophy. Here's an example of the output of such a command (some of the properties in the JSON have been removed for brevity):

Getting key cis-central-sk for service instance cis-central as dj.adams@sap.com...

{
  "credentials": {
    "endpoints": "..."
    "grant_type": "user_token",
    "sap.cloud.service": "com.sap.core.commercial.service.central",
    "uaa": {
      "uaadomain": "authentication.eu10.hana.ondemand.com",
      "xsappname": "ut-f86082c9-7fbf-4e1e-8310-f5d018dab542-clone!b254751|cis-central!b42",
      "xsmasterappname": "cis-central!b42",
      "zoneid": "7da58aab-6c60-4492-a95b-b1ed3139e242"
    }
  }
}

The first two lines ("Getting key ...", and the empty line) are not JSON. This means you will have to clean up the output of the command before processing it as JSON (and saving it to a file).

Note that the value of the endpoints property in the above output example is given as "..." - this is just for brevity in illustration; the value is in fact an object, containing properties, the names of which should be of interest to you for this task!

Note also that this example output also reminds us of one of the breaking changes between version 7 and version 8 of the cf CLI that were mentioned in the previous task. It's the advent of version 8 that brought along the outermost wrapping of the data within a new credentials property. Before version 8, that node does not exist in the JSON.

57 REPLIES 57

Ruthiel
Product and Topic Expert
Product and Topic Expert
0 Kudos

04a33063cb7f98dacdf0f9a51bb5808c3bfb8a3af01dc8b7238a421443cd85bb

martinstenzig
Contributor
0 Kudos

6f83f2f23e2e189505e0f501ed2b5b86d1fcb30a42a6ca3ca757a734826e4ded

MarcelloUrbani
Active Contributor
0 Kudos

0d4ccfcdf82476ce4658f3ca28e557fa45b3609c9e9f6af938f3ab59a6437638

johna69
Product and Topic Expert
Product and Topic Expert
0 Kudos

b277b8f3b481289db00135df80908b77b7d9ba8a05ca12d6e1ec10e6092bd39a

johna69
Product and Topic Expert
Product and Topic Expert
0 Kudos

The CF service key call returns 2 lines prior to the json service key. I could not find an option to disable it. I'm hoping one exists. I took to  <output> | sed 1,2d | jq ......, as what feels like a hack. Anyone have a more elegant solution?

Getting key cis_key for service instance cis as email@me.com...{
"credentials": {
"endpoints": {

qmacro
Developer Advocate
Developer Advocate
0 Kudos

Unfortunately this seems to be standard behaviour for the cf CLI, i.e. not well-behaved. See this section of the CodeJam on the btp CLI and APIs https://github.com/SAP-samples/cloud-btp-cli-api-codejam/blob/main/exercises/06-core-services-api-cr... where I use exactly the same approach.

cguttikonda24
Participant
0 Kudos

63db4578741f156bbb6d688899bbf7242f78166a694d2af85bb9445c5d7f36a6

ecem_yalim
Explorer
0 Kudos

7c0b91fa975e2c1a85c1aba9e0300bfb748bf4a3cc4eee03764ffc86cdb3f020

nex
Explorer
0 Kudos

fad1df8c04464ee2aef105fb1229dca92b2e7b91b7a8db42d7689df998d2b3b8

flo_conrad
Explorer
0 Kudos

46f570eb3cc2217d1da4f16bef2206cba8a12fffc9e7b4fa25d8e2f6ee09af37

RaulVega
Participant
0 Kudos

b0770fd1ee5184112b73a799f29f92bf1620b0b2b0a622368b9217319ff5426c

andrew_chiam
Explorer
0 Kudos

e394c0c7ecf44e1a015e1114d76db5a14409abe448a5507e22351b0d3df363de

OlgenH
Participant
0 Kudos

ae43f50c3614dcce868007fa5dc3ee9fbdef9e75ea4f0b49e50d24a5d841d071

qmacro
Developer Advocate
Developer Advocate
0 Kudos

Hey everyone! The challenge to which this task belongs is now officially closed. Head over to the original blog post SAP Developer Challenge – APIs to check out the closing info and final statistics, and to see your name in lights! 🎉  And we thank you all for participating, you made this challenge great!

devrajsinghr
Active Participant
0 Kudos

e751a03e3bbbabefd3a9641d7f90e926fd21d024db4b406e4c3eb74e7ea03e42

Dont forget to URL encode

adrian-ngo
Explorer
0 Kudos
681d803b870a9c83e129b5906a74f661f2be74fc6d86cec60cc4f11780dc49e8

satya-dev
Participant
0 Kudos

d19d4a6db5bb0ec5df40951ca2498b715bcbb7cb1f827e94c775e833add37de4

buz
Explorer
0 Kudos
fd33303e8ec8e0df029b2fc54e90d4852fdb635a8374a1eefb598a779f488a06