Dev Tech
Dev Tech

Reputation: 1

SAP BTP Credential store REST API auth with mtls

So I am using a SAP BTP trial account and trying to make a small node js app that is binded to the cred store service instance. For trial account only mtls auth is possible with a key and certificate.

I try this with standard fetch method but it doesnt work properly.

For reference I follow this its 2 mins read SAP mtls doc for cred store

They provide value of these through VCAP env variable. The problem is I have no experience with this auth and I tried to write the code and think its correct but the only error I receive is "2023-03-13T12:03:30.54+0000 [APP/PROC/WEB/0] ERR Request failed: Authentication failed. Please check your credentials and try again."

Which doesn't explain much, can someone see if my code is correct and suggest changes.

Code:

const express = require('express');
const fetch = require('node-fetch');
const https = require('https');
const app = express();

const port = process.env.PORT || 3000;

const binding = JSON.parse(process.env.VCAP_SERVICES).credstore[0].credentials;
//console.log(binding);

async function fetchWithMtls(url, method, headers, cert, key) {
    try {
        const response = await fetch(url, {
          method,
          headers,
          agentOptions: {
            cert,
            key,
          },
        });
    
        if (!response.ok) {
          let message = `Request failed with status ${response.status}`;
          if (response.status === 401) {
            message = 'Authentication failed. Please check your credentials and try again.';
          }
          throw new Error(message);
        }
    
        return response;
      } catch (error) {
        throw new Error(`Request failed: ${error.message}`);
      }
  }


async function main(){  try {
  const method = 'get';
  const headers = {
    'sapcp-credstore-namespace': 'namespace1',
    'Cache-Control': 'no-cache',
  };

  const response = await fetchWithMtls(`${binding.url}/password?name=${encodeURIComponent('neylux')}`, method, headers, binding.certificate, binding.key);
  const data = await response.json();
  
  console.log('!!!!!!!!!!!!!Response:!!!!!!!!!!!!!!!!!', data);
} catch (error) {
  console.error(error.message);
}

app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});}

main();

Upvotes: 0

Views: 611

Answers (1)

Ezequiel
Ezequiel

Reputation: 37

just in case it will help anyone else, using agent instead of agentOptions like this worked for me:

const agent = new https.Agent({
    cert: cert,
    key: key
});

Then the fetch call

fetch(url, {
    method,
    headers,
    agent
  })

Upvotes: 0

Related Questions