Skip to content

Commit

Permalink
docs: improve authentication documentation (#1156)
Browse files Browse the repository at this point in the history
* reworked authentication documentation structuring after implementation of `/token` API integration
* improved documentation regarding ICM authentication, SSO and Punchout

Co-authored-by: Silke <s.grueber@intershop.de>
Co-authored-by: MGlatter <m.glatter@intershop.de>
  • Loading branch information
3 people committed Dec 22, 2022
1 parent 4e02efd commit cf89956
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 131 deletions.
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ services:
# FEATURES: |
# - compare
# - rating
# IDENTITY_PROVIDER: 'Auth0'
# IDENTITY_PROVIDERS: |
# Auth0:
# type: auth0
# domain: some-domain.auth0.com
# clientID: ASDF12345
# Punchout:
# type: PUNCHOUT

# <CDN-Example>
# add 127.0.0.1 mypwa.net to your hosts file and
Expand Down Expand Up @@ -81,6 +89,10 @@ services:
# BASIC_AUTH_IP_WHITELIST: |
# # - 172.22.0.1
# - 1.2.3.4
# OVERRIDE_IDENTITY_PROVIDERS: |
# .+:
# - path: /en/punchout
# type: Punchout
MULTI_CHANNEL: |
.+:
- baseHref: /en
Expand Down
6 changes: 4 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ kb_sync_latest_only
- [Guide - Formly](./guides/formly.md)
- [Guide - Field Library](./guides/field-library.md)
- [Concept - Deployment Scenarios for Angular Applications](./concepts/deployment-angular.md)
- [Concept - Single Sign-On (SSO) for PWA](./concepts/sso.md)
- [Concept - Authentication](./concepts/authentication.md)
- [Guide - Authentication by the ICM Server](./guides/authentication_icm.md)
- [Guide - Authentication with Single Sign-On (SSO)](./guides/authentication_sso.md)
- [Guide - Authentication with the Punchout Identity Provider](./guides/authentication_punchout.md)

### Developing

Expand Down Expand Up @@ -80,5 +83,4 @@ kb_sync_latest_only
- [Guide - Client-Side Error Monitoring with Sentry](./guides/sentry-error-monitoring.md)
- [Guide - Extended Product Configurations with Tacton](./guides/tacton-product-configuration.md)
- [Guide - Monitoring with Prometheus](./guides/prometheus-monitoring.md)
- [Guide - SSO with Auth0 for PWA](./guides/sso-auth0.md)
- [Guide - Store Locator with Google Maps](./guides/store-locator.md)
95 changes: 95 additions & 0 deletions docs/concepts/authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<!--
kb_concepts
kb_pwa
kb_everyone
kb_sync_latest_only
-->

# Authentication Concept

## Introduction

Several ICM REST operations require an authenticated user.
Authentication also assures enterprise information security.
In the PWA a user can be verified with the help of an identity provider.
An identity provider (IdP) is a service that stores and manages digital identities.
The following identity providers are supported: The default [ICM server](../guides/authentication_icm.md), the [SSO Auth0](../guides/authentication_sso.md) and the [Punchout](../guides/authentication_punchout.md) identity provider.

## Library angular-oauth2-oidc

There is a lot of functionality related to authentication, e.g., logging a user in and out, registering a new user, keeping the user identified even if the user opens further browser tabs, etc.

The PWA uses the library [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc#readme) to support the implementation of these functionalities.
It can be configured to provide access to identity providers.
You can find the initialization of this library in the [oauth-configuration-service.ts](../../src/app/shared/../core/utils/oauth-configuration/oauth-configuration.service.ts).

## Implementation and Configuration of Identity Providers

To add or change the functionality of an identity provider, the following steps are necessary:

1. Create/change an `<idp>.identity-provider.ts` class that implements the interface [`IdentityProvider`](../../src/app/core/identity-provider/identity-provider.interface.ts). In this interface all methods are declared which have to be implemented in your IdP class.

In the following code you see a typical implementation of the init method of an IdP class.

Note that all authentication-related functionality must not be executed before the oAuth service has been configured.

```typescript
@Injectable({ providedIn: 'root' })
export class ExampleIdentityProvider implements IdentityProvider {
private configured$ = new BehaviorSubject<boolean>(false);

constructor(private oAuthService: OAuthService, private configService: OAuthConfigurationService) {}

init() {
this.configService.config$.subscribe(config => {
this.oAuthService.configure(config);
this.configured.next(true);
});

this.configured
.pipe(
whenTruthy(),
switchMap(() => from(this.oAuthService.fetchTokenUsingGrant('anonymous')))
)
.subscribe();
}
}
```

2. Register the `<idp>.identity-provider.ts` in the [`IdentityProviderModule`](../../src/app/core/identity-provider.module.ts). The `APP_INITIALIZER` injection token is used to configure and initialize the identity provider before app initialization.

3. Set the environment variables `IdentityProviders` and `IdentityProvider` accordingly.

## PWA Initialization

A PWA user has to be identified by the ICM server by a unique authentication token, even if it is an anonymous user.
Once a user opens the PWA for the first time, an authentication token is requested by the [ICM Token REST endpoint](https://support.intershop.com/kb/index.php?c=Display&q1=U29770&q2=Text).
This happens in the [`init()`](../../src/app/core/identity-provider/icm.identity-provider.ts) method of the active identity provider.
Subsequently, this token will be saved as `apiToken` cookie and added to all REST requests in the request header, e.g.:

```typescript
authentication-token: encryption0@PBEWithMD5AndTripleDES:1D7T8HyFqQ0=|k3PQLgujzUq0tudtw+6HLjWnExiwrd4o9/jVU7ZH74kTfTy3RS7/sYadsg7ODRM2
```

This way it is possible to identify users even they are opening a new browser tab or refreshing the PWA in the browser.

If a user opens the PWA and already has a valid apiToken cookie, no new token is requested by the ICM server but this token is used in the header of the REST requests.

## Login, Registration, Token Refreshment, Logout

All these functionalities strongly depend on the implementation of the used identity provider.
This is described in the appropriate identity provider guides in more detail, see [Further References](#further-references) below.

## Vanishing of the apiToken Cookie

The PWA needs to react in case the `apiToken` cookie is not available anymore.
This could happen if a PWA is opened in many tabs and the user logs out, or when users remove the cookie themselves.
When the cookie vanishes, the PWA emits a new value for the [`cookieVanishes$` subject](../../src/app/core/utils/api-token/api-token.service.ts).
The identity provider implementation defines how the application should behave in such a case.
With the ICM identity provider, for example, the user is then automatically logged out and routed to the `/login` page.

## Further References

- [Guide - ICM Identity Provider](../guides/authentication_icm.md)
- [Guide - Punchout Identity Provider](../guides/authentication_punchout.md)
- [Guide - Single Sign-On (SSO) Identity Provider](../guides/authentication_sso.md)
38 changes: 38 additions & 0 deletions docs/guides/authentication_icm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!--
kb_guide
kb_pwa
kb_everyone
kb_sync_latest_only
-->

# Authentication by the ICM Server

This document describes the main authentication mechanism if the ICM server is used as identity provider.
If you need an introduction to this topic, read the [Authentication Concept](../concepts/authentication.md) first.

## Login

If the user wants to login by clicking a login link or navigating to the `/login` route, either a popup or a page is displayed containing a login form.
After the user has entered the credentials (e-mail/user name and password) and could be verified successfully by the ICM server, a new token is fetched from the ICM `/token` REST endpoint.
The token of the registered user is saved as `apiToken` cookie and attached to the request header of the subsequent REST requests.
After logging in, the pgid of the user is requested from the ICM server (`/personalization` REST call) and the action `personalizationStatusDetermined` will be triggered.
If you want to request user-specific non-cached data from the ICM server, use the option `sendPGID` or `sendSPGID`, respectively when you call the _get_ method of the `ApiTokenService`.

## Registration

The registration of a user is similar to the login.
After the user has completed the registration form, the data are validated by the ICM server and a new user will be created.
Afterwards, the authentication token is requested from the server and the user will be logged in, see above.

## Token Lifetime

Each authentication token has a predefined lifetime.
That means, the token has to be refreshed to prevent it from expiring.
Once 75% of the token's lifetime have passed (this time can be configured in the oAuth library), an info event is emitted.
This event is used to call the [refresh mechanism `setupRefreshTokenMechanism$`](../../src/app/core/utils/oauth-configuration/oauth-configuration.service.ts) of the oAuth configuration service and the authentication token will be renewed.
Hence, the token will not expire as long as the user keeps the PWA open in the browser.

## Logout

When the user logs out by clicking the logout link or navigating to the `/logout` route, the configured [`logout()`](../../src/app/core/identity-provider/icm.identity-provider.ts) function will be executed, which will call the [`revokeApiToken()`](../../src/app/core/services/user/user.service.ts) user service in order to deactivate the token on server side.
Besides this, the PWA removes the token on browser side, fetches a new anonymous user token, and sets it as `apiToken` cookie.
79 changes: 79 additions & 0 deletions docs/guides/authentication_punchout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!--
kb_guide
kb_pwa
kb_everyone
kb_sync_latest_only
-->

# Authentication with the Punchout Identity Provider

This document describes the main authentication mechanism if punchout is used as identity provider.
If you need an introduction to this topic, read the [Authentication Concept](../concepts/authentication.md) first.

## Configuration

The PWA must be configured in a correct way to use punchout as an identity provider.
Apart from the enabled `punchout` feature flag, the following configuration can be added to the Angular CLI environment files for development purposes:

```typescript
features: [
'punchout'
],
identityProvider: 'Punchout',
identityProviders: {
'Punchout': {
type: 'PUNCHOUT',
}
},
```

For production, this configuration should be provided to the SSR process via environment variables (see [Building and Running Server-Side Rendering][ssr-startup]).
The usage of identity providers can also be set in the multi-channel configuration (see [Building and Running nginx Docker Image][nginx-startup]).

Additionally, the PWA can be configured to use the punchout identity provider only, when the user enters the punchout route.
In that case the nginx should be configured with the `OVERRIDE_IDENTITY_PROVIDERS` environment variable (see [Override Identity Providers by Path][nginx-startup]).
Nevertheless, the SSR process needs to be provided with the punchout identity provider configuration.

```yaml
pwa:
environment:
IDENTITY_PROVIDERS: |
Punchout:
type: PUNCHOUT
nginx:
environment:
OVERRIDE_IDENTITY_PROVIDERS: |
.+:
- path: /punchout
type: Punchout
```
## Login
A user can login by navigating to the `/punchout` or `/login` route.
For this purpose [specific query params](../../src/app/extensions/punchout/identity-provider/punchout-identity-provider.ts) need to be added to the given route depending on whether the OCI or the cXML punchout should be used.
For the OCI punchout login the user needs to add the `HOOK_URL`, `USERNAME` and `PASSWORD` as query parameters, while the cXML user has to include the `sid` and `access-token`.
In addition, the [cXML punchout tester](https://punchoutcommerce.com/tools/cxml-punchout-tester) could be used to log in a cXML punchout user.
The request [/customers/${CustomersKey}/punchouts/cxml1.2/setuprequest](https://support.intershop.com/kb/index.php/Display/29L952#l1142) to create a new cXML punchout session must be inserted as the URL with the credentials of the cXML punchout user.
When the session is created successfully, the punchout tester will redirect to the ICM configured PWA deployment `/punchout` route.

## Registration

There is currently no possibility to register a new punchout user in the PWA.

## Token Lifetime

Each authentication token has a predefined lifetime.
That means, the token has to be refreshed to prevent it from expiring.
Once 75% of the token's lifetime have passed ( this time can be configured in the oAuth library), an info event is emitted.
This event is used to call the [refresh mechanism `setupRefreshTokenMechanism$`](../../src/app/core/utils/oauth-configuration/oauth-configuration.service.ts) of the oAuth configuration service and the authentication token will be renewed.
Hence, the token will not expire as long as the user keeps the PWA open in the browser.

## Logout

When the user logs out by clicking the logout link or navigating to the `/logout` route, the configured [`logout()`](../../src/app/extensions/punchout/identity-provider/punchout-identity-provider.ts) function will be executed, which will call the [`revokeApiToken()`](../../src/app/core/services/user/user.service.ts) user service in order to deactivate the token on server side.
Besides this, the PWA removes the token and basket-id on browser side, fetches a new anonymous user token, and sets it as `apiToken` cookie.

[ssr-startup]: ../guides/ssr-startup.md
[nginx-startup]: ../guides/nginx-startup.md
55 changes: 38 additions & 17 deletions docs/concepts/sso.md → docs/guides/authentication_sso.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<!--
kb_concepts
kb_guide
kb_pwa
kb_everyone
kb_sync_latest_only
-->

# Single Sign-On (SSO) for PWA
# Authentication with Single Sign-On (SSO)

Intershop Commerce Management supports logging in clients via SSO (see [Concept - Single Sign-On (SSO)][kb-concept-sso]).

Expand All @@ -15,9 +15,9 @@ After setting up the ICM side with the identity provider, an implementation for
For development purposes the configuration can be added to the Angular CLI environment files:

```typescript
identityProvider: 'MyProvider',
identityProvider: 'Auth0',
identityProviders: {
'MyProvider': {
'Auth0': {
type: 'auth0',
domain: 'some-domain.auth0.com',
clientID: 'ASDF12345',
Expand All @@ -28,30 +28,51 @@ For development purposes the configuration can be added to the Angular CLI envir
For production, this configuration should be provided to the SSR process via environment variables (see [Building and Running Server-Side Rendering][ssr-startup]).
The usage of identity providers can also be set in the multi-channel configuration (see [Building and Running nginx Docker Image][nginx-startup]).

## Business cases
```yaml
pwa:
environment:
IDENTITY_PROVIDER: 'Auth0'
IDENTITY_PROVIDERS: |
Auth0:
type: auth0
domain: some-domain.auth0.com
clientID: ASDF12345
```
## SSO with Auth0 for PWA
Follow [this guide](https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/authorization-servers/auth0.html) to set up an application in the Auth0 configuration.
The PWA contains a default SSO with Auth0 identity provider implementation located in the [`Auth0IdentityProvider`](../../src/app/core/identity-provider/auth0.identity-provider.ts).

Use the configuration fields `domain` and `clientID` for configuring the provider.

## Business Cases

### Create new user
### Create New User

| Authentication Provider | Route in ICM email | Behavior of PWA |
| ----------------------- | ------------------ | ------------------------------------------ |
| ICM | /invite | Redirect to /forgotPassword/updatePassword |
| SSO | /invite | Redirect to SSO provider |
| Authentication Provider | Route in ICM e-mail | Behavior of PWA |
| ----------------------- | ------------------- | ------------------------------------------ |
| ICM | /invite | Redirect to /forgotPassword/updatePassword |
| SSO | /invite | Redirect to SSO provider |

### User forgot password
### User Forgot Password

| Authentication Provider | Route in ICM email | Behavior of PWA |
| ----------------------- | ------------------------------ | ------------------------- |
| ICM | /forgotPassword/updatePassword | Show change password form |
| SSO | /forgotPassword/updatePassword | Redirect to SSO provider |
| Authentication Provider | Route in ICM e-mail | Behavior of PWA |
| ----------------------- | ------------------------------ | --------------------------- |
| ICM | /forgotPassword/updatePassword | Show _change password_ form |
| SSO | /forgotPassword/updatePassword | Redirect to SSO provider |

# Further References
## Further References

- PWA
- [Guide - SSO with Auth0 for PWA](../guides/sso-auth0.md)
- [Concept - Authentication](../concepts/authentication.md)
- [Guide - Building and Running Server-Side Rendering][ssr-startup]
- [Guide - Building and Running nginx Docker Image][nginx-startup]
- ICM
- [Concept - Single Sign-On (SSO)][kb-concept-sso]
- General
- [SSO with OAuth 2 and OpenId Connect](https://angular.de/artikel/oauth-odic-plugin/) (in German)

[kb-concept-sso]: https://support.intershop.com/kb/index.php/Display/29A407
[ssr-startup]: ../guides/ssr-startup.md
Expand Down
Loading

0 comments on commit cf89956

Please sign in to comment.