Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve cds.auth #392

Merged
merged 11 commits into from
Sep 4, 2023
43 changes: 34 additions & 9 deletions node.js/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,11 @@ User-related attributes, for example, from JWT tokens
These correspond to `$user.<x>` in [`@restrict` annotations](../guides/authorization) of your CDS models {.indent}




### <i>DEPRECATED:</i> user.tenant <i> : string </i> {#user-tenant}

[Use `req/msg.tenant` instead.](events#tenant){.learn-more}



### <i>DEPRECATED:</i> user.locale <i> : string </i> {#user-locale}

[Use `req/msg.locale` instead.](events#locale){.learn-more}
Expand All @@ -97,6 +94,22 @@ this.before('*', function (req) {
})
```

Alternatively, you can also use the sealed instance `cds.User.privileged` directly, i.e., `const user = cds.User.privileged`.
sjvans marked this conversation as resolved.
Show resolved Hide resolved


### cds.**User.Anonymous** <i> class </i> { #anonymous-user }

Class `cds.User.Anonymous` allows you to instantiate an anonymous user (`const user = new cds.User.Anonymous`), for example in a [custom authentication](#custom) implementation.

Alternatively, you can also use the sealed instance `cds.User.anonymous` directly, i.e., `const user = cds.User.anonymous`.
sjvans marked this conversation as resolved.
Show resolved Hide resolved
sjvans marked this conversation as resolved.
Show resolved Hide resolved


### cds.**User.default** { #default-user }

If a request couldn't be authenticated, for example due to a missing authorization header, the built-in authentication strategies assign the default user to the request, i.e., `req.user = new cds.User.default`, ensuring that `req.user` is always set.
sjvans marked this conversation as resolved.
Show resolved Hide resolved

By default, `cds.User.default` points to `cds.User.Anonymous`. However, you can override this, for example to be `cds.User.Privileged` in tests, or to be any other class that returns an instance of `cds.User`.


### <i> Authorization Enforcement </i> {.h2 #enforcement }

Expand Down Expand Up @@ -131,16 +144,17 @@ cds.serve ('CustomerService') .with (function(){
})
```


## Authentication Strategies {#strategies}

CAP ships with a few prebuilt authentication strategies, used by default: [`mocked`](#mocked) during development and [`xsuaa`](#xsuaa) in production.
CAP ships with a few prebuilt authentication strategies, used by default: [`mocked`](#mocked) during development and [`jwt`](#jwt) in production.
You can override these defaults and configure the authentication strategy to be used through the `cds.requires.auth` [config option in `cds.env`](./cds-env), for example:

::: code-group
```json [package.json]
"cds": {
"requires": {
"auth": "xsuaa"
"auth": "jwt"
}
}
```
Expand All @@ -167,6 +181,7 @@ This strategy creates a user that passes all authorization checks. It’s meant
```
:::


### Mocked Authentication {.h2 #mocked }

This authentication strategy uses basic authentication with pre-defined mock users during development.
Expand Down Expand Up @@ -206,6 +221,7 @@ You can optionally configure users as follows:
```
:::


#### Pre-defined Mock Users {#mock-users}

The default configuration shipped with `@sap/cds` specifies these users:
Expand Down Expand Up @@ -312,7 +328,6 @@ npm add @sap/xssec

Authentication kind `xsuaa` is a logical extension of kind [`jwt`](#jwt) that additionally offers access to SAML attributes through `req.user.attr` (for example, `req.user.attr.familyName`).


**Prerequisites:** You need to add [@sap/xssec](https://help.sap.com/docs/HANA_CLOUD_DATABASE/b9902c314aef4afb8f7a29bf8c5b37b3/54513272339246049bf438a03a8095e4.html#loio54513272339246049bf438a03a8095e4__section_atx_2vt_vt) to your project:
```sh
npm add @sap/xssec
Expand Down Expand Up @@ -366,8 +381,7 @@ npm add @sap/xssec
:::


### Custom Authentication {#custom }

### Custom Authentication { #custom }

You can configure an own implementation by specifying an own `impl` as follows:

Expand All @@ -379,8 +393,11 @@ You can configure an own implementation by specifying an own `impl` as follows:
}
```

Essentially, custom authentication middlewares must do two things. First, they must [fulfill the `req.user` contract](#cds-user) by assigning an instance of `cds.User` or a look-alike to the incoming request at `req.user`. Second, if running in a multitenant environment, `req.tenant` must be set to a string identifying the tenant that is addressed by the incoming request.
Essentially, custom authentication middlewares must do two things:

First, they _must_ [fulfill the `req.user` contract](#cds-user) by assigning an instance of `cds.User` or a look-alike to the incoming request at `req.user`. Use [new cds.User.default](#default-user) as the fallback option.
sjvans marked this conversation as resolved.
Show resolved Hide resolved

Second, if running in a multitenant environment, `req.tenant` must be set to a string identifying the tenant that is addressed by the incoming request.

```js
module.exports = function custom_auth (req, res, next) {
Expand All @@ -399,6 +416,14 @@ module.exports = function custom_auth (req, res, next) {

[If you want to customize the user ID, please also have a look at this example.](./middlewares#customization-of-req-user){.learn-more}


## Authentication Enforced in Production

In a productive scenario with an authentication strategy configured, for example the default `jwt`, all CAP service endpoints are authenticated by default, regardless of the authorization model. That is, all services without `@restrict` or `@requires` implicitely get `@requires: 'authenticated-user'`.

This can be disabled via feature flag `cds.env.requires.auth.restrict_all_services: false`, or by using [mocked authentication](#mocked) explicitly in production.


## XSUAA in Hybrid Setup {#xsuaa-setup}

### Prepare Local Environment
Expand Down