cancel
Showing results for 
Search instead for 
Did you mean: 

CAPM Protect CDS Service with XSUAA

Ben
Participant

Hi There

When following the tutorial https://developers.sap.com/tutorials/xsa-cap-add-uaa.html the srv-Module (srv_api) is protected when called via AppRouter.

But as far as I see, the srv-Module still can be called directly (not via AppRouter) and then, the srv is not protected.

If using a CDS oData Service based on CAPM template, it would be possible to add some annotations for access restriction, for example @(requires:'authenticated-user') --> see https://answers.sap.com/questions/784681/more-info-on-cds-requires-statement-cloud-applicat.html

But if doing so, then the srv-Module can not be called directly or via AppRouter, there will be error message "Forbidden".

Therefore I would like to know how it is possible to secure an oData srv-Module by means that it is protected if called via AppRouter or called directly on the srv-Instance.

Best regards,

Ben

Ben
Participant
0 Kudos

Hi gregorw christian.georgi

In the meantime I found out why the built-in oData server suddenly works with authentication.

The crucial lines of code are in package.json file. There you will have to declare the dependencies to the following libraries (be aware that there are two package.json files, add lines to both of them😞

	"@sap/xsenv": "^2.0.0",
	"@sap/xssec": "^2.2.2",
	"passport": "^0.4.0"

See here for example in your project https://github.com/gregorwolf/bookshop-nodejs/blob/master/srv/package.json#L7,L13

Without those 3 libraries, the authentication is not working. This is the final solution for my question.

As a workaround one can also use a custom Node.js server like you demonstrated in the github project.

Best regards,

Ben

Ben
Participant
0 Kudos

Hi gregorw christian.georgi

Unfortunately I found an exception / strange behaviour with the above solution.

It looks like after adding the three libraries to the package.json, all services are protected! Even the services which are not annotated with @(requires)..

Means that you get "forbidden" or "unauthorized" error message for all services..

I would still be interested in a "proper" solution where authorization works exactly as defined with annotations in cds service..

Best regards,

Ben

Ben
Participant
0 Kudos

Also following annotation is not working.. The oData Service now blocks all requests.

@(requires:'any')

Looks like a bug?

Ben
Participant
0 Kudos

Hi gregorw and christian.georgi

Sorry for the SPAM, this will be my last comment today I promise 🙂

The above issue that all services / entities are now blocked by authentication can be reproduced in your GITHUB Repo https://github.com/gregorwolf/bookshop-nodejs

Just build / start the db and srv service, then make some GET requests to the admin and catalog service.

As you will encounter, all requests will fail with "unauthorized" error message. See log:

Application is starting
Application is running
> bookshop-nodejs-srv@1.0.0 start /home/vcap/app
> node ./node_modules/@sap/cds/bin/cds.js serve gen/csn.json
[cds] - connect to datasource - hana:gen/csn.json
[cds] - serving AdminService at /admin
[cds] - serving CatalogService at /catalog
[cds] - service definitions loaded from:
gen/csn.json
[cds] - server listens at http://localhost:59318 ... (terminate with ^C)
[cds] - launched in: 5390.165ms
GET /admin/Authors
{ user: '10.0.136.0', ip: '10.0.136.0' }
GET /catalog/Authors
{ user: '10.0.136.0', ip: '10.0.136.0' }
GET /catalog/Books
{ user: '10.0.136.0', ip: '10.0.136.0' }
GET /catalog/Currencies
{ user: '10.0.136.0', ip: '10.0.136.0' }
GET /catalog/Orders
{ user: '10.0.136.0', ip: '10.0.136.0' }

According to the service definition, the GET requests to Catalog Service Entities "Books" and "Authors" should work without authentication. Here I also added annotation "@requires: 'any'" for "Authors" entity just to point out that this not working as well.

using my.bookshop as db from '../db/data-model';

service CatalogService {

  @readonly entity Books as projection on db.Books excluding {
    createdBy, modifiedBy
  };

  @requires: 'any'
  @readonly entity Authors as projection on db.Authors excluding {
    createdBy, modifiedBy
  };

  @requires: 'authenticated-user'
  @insertonly entity Orders as projection on db.Orders;
}

I hope this will help you to analyze the issue.

Looking forward for a solution.

Best regards,

Ben

View Entire Topic
0 Kudos

Nearby one year ago and I'm facing the same problem. As Benjamin told:

JWT token is not delivered to or recognized from the srv-Module because when I call the oData Service (srv-Module) via AppRouter, I am routed to the login page and after successful login, the oData response still is "forbidden".

Are there new ideas, solutions ? I tried a lot, but unfortunately nothing works.

gregorw
Active Contributor
0 Kudos

Hi Stefan,

maybe my debug handlers in server.js help.

Best regards
Gregor