cancel
Showing results for 
Search instead for 
Did you mean: 

SAP Cloud SDK for JavaScript: Error integrating XSSEC with NestJS

former_member231229
Participant
0 Kudos

Hello all,
following what ttrapp and dhem were discussing here I did some research about how to (within my best effort and skills) integrate the usage of JWTStrategy from xssec library into the Passport implementation of NestJS, which is what we get when initializing a new project using the Sap Cloud SDK CLI.

I "almost" got there, but I am now stuck in an issue which I really cannot resolve.

I created a simple repository sapcloudsdk-nestjs-xsuaa to replicate the issue, but here's briefly what I did:

  1. Prepare XSUAA instance and Destination instance on CF
  2. Add the approuter to the project (using CLI's add approuter command)
  3. Properly configure default-env.json files, both in the approuter folder and in the root folder for local testing
  4. Install necessary dependencies: @nestjs/passport passport passport-jwt @sap/xssec @sap/xsenv

Generate a new "auth" module, the custom strategy class and a custom guard to protect endpoints:

  1. nest generate module auth/auth

  2. nest generate class auth/xsuaa.strategy
  3. nest generate guard auth/xsuaa.guard

The setup compiles and the application starts. Assuming that you are using default ports, calling http://localhost:5000/yourendpoint lands to the XSUAA login page.

Do the login and:

[Nest] 17174   - 2020-03-15 21:48:43   [ExceptionsHandler] this._secretOrKeyProvider is not a function +15597ms
TypeError: this._secretOrKeyProvider is not a function
    at XsuaaStrategy.JwtStrategy.authenticate (/Users/stevebob/Desktop/SAP/CLOUD SDK/xsuua-test/node_modules/passport-jwt/lib/strategy.js:99:10)
    at attempt (/Users/stevebob/Desktop/SAP/CLOUD SDK/xsuua-test/node_modules/passport/lib/middleware/authenticate.js:366:16)
    at authenticate (/Users/stevebob/Desktop/SAP/CLOUD SDK/xsuua-test/node_modules/passport/lib/middleware/authenticate.js:367:7)
    at Promise (/Users/stevebob/Desktop/SAP/CLOUD SDK/xsuua-test/node_modules/@nestjs/passport/dist/auth.guard.js:84:3)
    at new Promise (<anonymous>)
    at /Users/stevebob/Desktop/SAP/CLOUD SDK/xsuua-test/node_modules/@nestjs/passport/dist/auth.guard.js:76:83
    at XsuaaGuard.<anonymous> (/Users/stevebob/Desktop/SAP/CLOUD SDK/xsuua-test/node_modules/@nestjs/passport/dist/auth.guard.js:48:36)
    at Generator.next (<anonymous>)
    at /Users/stevebob/Desktop/SAP/CLOUD SDK/xsuua-test/node_modules/@nestjs/passport/dist/auth.guard.js:20:71
    at new Promise (<anonymous>)

I think it is related on how the strategy is being configured: the "secretOrKeyProvider" parameter expect a callback function (and not a new JWTStrategy instance)

If anyone has an idea, I'll be happy to contribute - and learn 🙂

Thanks a lot,

Roberto.

gregorw
Active Contributor
0 Kudos

Hi Roberto,

I would be interested to learn from daniel.hutzel and henning.heitkoetter about the reasons why SAP Cloud Application Programming Model uses just plain Express and SAP Cloud SDK adds NestJS to the game. Wouldn't it be an option for you to stick with CAP to provide your service including authorizations and Cloud SDK for the backend calls?

Best regards
Gregor

former_member231229
Participant
0 Kudos

Hello Gregor,

Yes, I could stick to CAP, but my use case fits perfectly with the SDK purpose (and I really like the NestJS approach), so I wanted to learn 🙂

There’s a way to make authentication and authorization work by using plain ExpressJS middleware, let’s say my question was more related on how to completely embrace Nest and - most of all - share the idea and my findings!

Thank you!

Roberto

dhem
Active Participant

Hi Roberto, hi Gregor,

I have not used the xssec library myself before, therefore I cannot definitively comment on this issue. Before investigating the issue, let me start with a question: What exactly are you trying to achieve? For which reason are you trying to integrate xssec? If it's only about protecting your backend from unauthorized access, you may find simpler solutions. But given that you've also mentioned local development, I have a feeling your requirements are a little more specific than that.

@Gregor: Fair question. When you generate a new project using the "@sap-cloud-sdk/cli", we currently generate a project based on Nest.js. When deciding what lib/framework to use there, I did initially have the same concerns you seem to have. Express does seem to be the lowest common denominator that probably won't offend anyone. However, Nest.js does use Express under the hood by default (or, to phrase it from a different perspective, Nest.js is just a wrapper over Express). That means that anything that you can do in Express (e.g. use CAP) you can also do in Nest.js. IIRC we did even try using CAP in Nest before switching to it.
Apart from that, we as SAP Cloud SDK do not officially endorse Nest.js as the definitive technology for building web applications (we might need to make this more explicit in our docs, to be fair). We have found that Nest offers many things out of the box that we'd need to build/integrate ourselves otherwise, but at the same time we also did not look at every aspect yet.

@Roberto: That being said, I'd like to second Gregor's question here: have you checked whether there's something in CAP that already solves this for you? (Or more general: have you looked at CAP in general?).

I will try to find out whether someone from the xssec team can chime on this issue (depending on what the actual problem turns out to be).

former_member231229
Participant
0 Kudos

Hello Dennis,
It' much more simple then that actually 🙂
I'm working on a SuccessFactors extension app, no persistence and no OData service exposure (the UI will be developer by the customer, who doesn't know (and doesn't want to learn) OData).
My service will get data, do something on the fly, and give back plain json resources.

The SDK seemed the best option to me, the OData generator now works perfectly and with a few calls I have my service up and running.

Given that the SDK provides a NestJs application out of the box, I did try to learn it at my best. I've previous Angular experience, so I felt a little bit at home with Nest.

When it came to security, I followed the common Nest approach of Passport+Strategies and came across this problem (as already asked by others here).

To answer you, yes I've looked into CAP and it can solve the problem and yes, using plain ExpressJs middleware works as well.
On the other side, I can simply switch to the Java version of the SDK and use Spring Security.

This is not really a requirement, I just wanted to share my findings when trying to integrate XSSec into Nest: maybe this could be useful whenever Nest becomes the de-facto standard for the SDK, or maybe not 🙂

Thank you both for your comments!

dhem
Active Participant
0 Kudos

Hi Roberto, thanks for the feedback! Just for my personal understanding, can you quickly elaborate on the security concept for your app? I'd guess that callers will have to provide a user token (JWT) on which you want to check scopes?

former_member231229
Participant

Hi Dennis,
In the end the security concept is quite simple.
Ideally, the application is hosted in a subaccount for which the IdP is SuccessFactors itself, so that after login, Role-Based dynamic authorization checks will be performed directly in the platform.

From the extension point of view, I just need to check the user scope against 3 possible values, which are the usual ESS/MSS/XSS of an HCM application.

Depending on the user scope, or a combination of them, the application will react accordingly (disable updates, etc..).

Cheers,
R.

PS: i did some more digging on the interaction between xssec and NestJS passport strategy approach, I'll be more than happy to share my findings if you think they'll be useful.

dhem
Active Participant
0 Kudos

Hi Roberto, I'd be happy to take a look at your findings (and I can imagine other users will be, too)!

former_member231229
Participant
0 Kudos

Hello Dennis, I'll write something down, maybe in a blog, in which I would like to share my feelings about the great experience I am having working with the SDK 🙂

I'm closing this thread for the time being.

Accepted Solutions (0)

Answers (0)