Skip to content

History

New page
Showing with 1,175 additions and 6,922 deletions.
  1. +15 −71 Adaptive-Authentication:-How-to-Improve-Security-Without-Annoying-Users.md
  2. +19 −216 Authentication-in-a-Single‐Page-Application-via-OpenAM-using-OAuth2-OIDC-Protocol.md
  3. +4 −35 Authentication-modules.md
  4. +28 −32 Captcha-module.md
  5. +5 −5 Config-OpenAM-as-OAuth2-Service-Provider.md
  6. +25 −165 Configuring-authentication-in-OpenAM-via-Yandex-Cloud-using-the-SAML-protocol.md
  7. +42 −42 Home.md
  8. +33 −39 How-OpenAM-Works-Simple-Explanation.md
  9. +1 −1 How-To-Guides.md
  10. +19 −241 How-To-Run-OpenAM-in-Kubernetes.md
  11. +9 −47 How-To-Setup-Active-Directory-Authentication-In-OpenAM.md
  12. +21 −333 How-to-Add-Authorization-and-Protect-Your-Application-With-OpenAM-and-OpenIG-Stack.md
  13. +17 −299 How-to-Create-Custom-OpenAM-DataStore-Integration.md
  14. +13 −166 How-to-Customise-OpenAM.md
  15. +41 −484 How-to-Devleop-a-Custom-Authentication-Module.md
  16. +21 −501 How-to-Protect-Model-Context-Protocol-(MCP)-Servers-with-OpenAM-and-OpenIG.md
  17. +15 −64 How-to-Setup-2FA-with-Google-Authenticator-in-OpenAM.md
  18. +19 −168 How-to-Setup-Active-Directory-Authentication-in-a-Spring-Boot-Application.md
  19. +27 −185 How-to-Setup-OAuth2-OIDC-Federation-in-OpenAM.md
  20. +31 −165 How-to-Setup-SAMLv2-Federation-in-OpenAM.md
  21. +23 −43 How-to-Setup-Two-Factor-Authentication-in-OpenAM.md
  22. +31 −106 How-to-Setup-WebAuthn-Authentication-in-OpenAM.md
  23. +15 −105 How-to-Start-OpenAM-and-OpenDJ-in-Separate-Docker-Contaners.md
  24. +27 −93 How-to-Use-Apache-Cassandra-as-User-and-Session-DataStore-in-OpenAM.md
  25. +20 −26 How-to-disable-XUI-by-default.md
  26. +5 −1 How-to-make-OpenAM-log-more-verbose.md
  27. +19 −50 How-to-setup-Kerberos-Authentication-with-OpenAM.md
  28. +17 −34 Login-and-Password-Authentication.md
  29. +23 −101 Login-via-"Госуслуги-РФ"-OAuth2-Identity-Provider.md
  30. +29 −42 Login-via-Facebook-OAuth2-Identity-Provider.md
  31. +29 −42 Login-via-Odnoklassniki-OAuth2-Identity-Provider.md
  32. +29 −42 Login-via-VK-OAuth2-Identity-Provider.md
  33. +49 −205 Migrate-OpenAM-to-Apache-Cassandra-without-Single-Point-of-Failure.md
  34. +13 −93 OpenAM-Monitoring-Using-Prometheus.md
  35. +19 −55 OpenAM-QR-Authentication-Module.md
  36. +11 −155 OpenAM-and-Spring-Boot-3-Integration-via-OIDC-OAuth2-Protocol.md
  37. +13 −223 OpenAM-and-Spring-Boot-3-Integration-via-OpenAM-Cookie.md
  38. +29 −182 OpenAM-and-Spring-Boot-3-Integration-via-SAMLv2-Protocol.md
  39. +35 −485 OpenAM-and-Zero-Trust:-Confirming-Critical-Operations.md
  40. +49 −132 OpenAM-vs-Keycloak.md
  41. +23 −78 Passwordless-Authenticaion-Methods.md
  42. +27 −61 Persistent-Cookie-module.md
  43. +23 −131 Quick-Start-Guide.md
  44. +25 −197 SAML-Authentication-in-WordPress-via-OpenAM.md
  45. +29 −106 SAML-Authentication-in-Yandex-Cloud-via-OpenAM.md
  46. +27 −295 SSO-Configuration:-OpenIG-as-SAML-Service-Provider-for-OpenAM.md
  47. +17 −46 Setup-Tracing-with--OpenTelemetry-and-Jaeger.md
  48. +21 −26 Stateful-vs-Stateless-Authentication.md
  49. +3 −124 TIP:-Bootstrap-OpenAM-and-OpenDJ-Docker-Containers.md
  50. +3 −7 TIP:-How-to-Enable-CORS.md
  51. +3 −6 TIP:-How-to-Pass-Additional-System-Property-to-CATALINA_OPTS-to-OpenAM-Docker-Container.md
  52. +3 −35 TIP:-How-to-Persist-OpenAM-Docker-Container-Data-Between-Restarts.md
  53. +3 −65 TIP:-Quick-OpenAM-Docker-Configuration-From-a-Command-Line.md
  54. +21 −74 Using-Google-Authenticator-with-OpenAM.md
  55. +21 −80 Using-Microsoft-Authenticator-with-OpenAM.md
  56. +7 −11 What-is-Single-Sign-On-and-How-does-it-Work.md
  57. +29 −106 Аутентификация-по-протоколу-SAML-с-помощью-OpenAM-на-примере-Yandex-Cloud.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,29 @@
- [Introduction](#introduction)
- [How Adaptive Authentication Works](#how-adaptive-authentication-works)
- [Adaptive Authentication Factors](#adaptive-authentication-factors)
- [Adaptive Authentication Policy Setup](#adaptive-authentication-policy-setup)
This article has moved to the Open Identity Platform documentation site:

# Introduction
[Adaptive Authentication: How to Improve Security Without Annoying Users](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users).

Your applications will be attacked sooner or later. Especially if they have become popular and your users don't particularly care about information security.
Please use the documentation site for the current version.

In my 10 years of developing authentication systems, I've seen a constant battle between security requirements and a positive user experience. The easier it is for a user to log into a service, the less annoyed they are. On the other hand, the more complex the authentication process, the easier it is for an attacker to break into the system. Is there a compromise possible here?
<a name="introduction"></a>

In my opinion, yes. An adaptive authentication system can recognize a potential attacker and make the authentication process much complex on the fly to prevent hacking.
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users#adaptive-authentication-how-to-improve-security-without-annoying-users-introduction)**

# How Adaptive Authentication Works
<a name="how-adaptive-authentication-works"></a>

If the user used the application before, logged in from the same IP address and used the same device or browser, and used the same device or browser, you can log in the user without asking for credentials.
**[How Adaptive Authentication Works](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users#adaptive-authentication-how-to-improve-security-without-annoying-users-how-adaptive-authentication-works)**

If the user is trying to login using an unknown device or browser, or user's IP address in another country since the moment of the previous login, the user probably is an attacker.
<a name="adaptive-authentication-factors"></a>

Attackers come in several types - bots or real people, who use social engineering for attacks. For each type of attacker. For each type of attacker, you have to react differently.
**[Adaptive Authentication Factors](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users#adaptive-authentication-how-to-improve-security-without-annoying-users-adaptive-authentication-factors)**

If an attacker is a bot, you must use a method that only humans can pass - captcha. The most common types of captchas are images of text or certain objects. To authenticate, the user must enter the text from the image, or mark certain objects.
<a name="adaptive-authentication-policy-setup"></a>

An alternative authentication option is one-time-password (OTP) authentication. The random code is sent to the user via SMS, email, or push notification in a mobile application. In that case, an attacker will not be able to access the application, unless he has access to the user's phone or email. This method is more expensive than captcha but can protect against both bots or real people.
**[Adaptive Authentication Policy Setup](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users#adaptive-authentication-how-to-improve-security-without-annoying-users-adaptive-authentication-policy-setup)**

If there is a high probability of hacking, authentication should be disabled for IP address or user account.
<a name="manual-configuration"></a>

To figure out if a user is an attacker, during the authentication process you must collect certain data that can be used to detect attack risk level. This data is called authentication factors.
**[Manual Configuration](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users#adaptive-authentication-how-to-improve-security-without-annoying-users-manual-configuration)**

So what factors can be collected during the authentication process?
<a name="automatic-policy-configuration-using-machine-learning"></a>

# Adaptive Authentication Factors

**IP address.** Using an IP address you can determine several factors:

**If the IP address belongs to a cloud provider.** Hackers use cloud servers to deploy attackers bots or use a cloud server as a VPN server.

**If the IP address is an exit node or anonymous network.** Hackers can use anonymous internet, for example, TOR, for attacks to hide their real location.

**User geographical location.** If the location of current authentication is uncommon for most of your users it could be a hacker attack.

**User speed.** If the user tries to authenticate from one country and five minutes later from another country, this is likely an attack. A real person can't cover such distance so fast.

**The number of unsuccessful authentication attempts for a certain time.** If there are more than 10 unsuccessful authentication attempts in a minute, it is suspected that there is a password brute force attempt.

**The number of unsuccessful authentication attempts per time for an IP address.** If there are more than 100 unsuccessful authentication attempts per minute, there is a suspicion of an attack attempt.

**Unknown or known device or browser.** After successful authentication, the service sets a special tag (cookie) for a device or browser. The tag is transmitted at the next login attempts and allows to determine whether the device is known or not.

**A time from the start of the authentication process to entering your username and password.** A human will not be able to enter credentials and press the "Login" button in a fraction of a second

**A time since the last successful authentication.** If the user has not logged in for several months, it may be worth requesting additional data from the user.

## Adaptive Authentication Policy Setup

Adaptive authentication policies could be determined by security requirements and configured manually. The second option is to use machine learning methods.

## Manual Configuration

You determine by yourself which factors are the most potentially dangerous. For example, it is critical to you that when using a new device or browser, the user must additionally confirm his or her identity. When using a known device, you can log the user in without authentication.

Advantages

- Transparency - you determine which security policy is acceptable to you and configure it accordingly
- Easy maintenance
- Low consumption of computing resources

Disadvantages

- To setup policy experience in the subject area is required

## Automatic Policy Configuration Using Machine Learning

I intentionally do not use the hype terms "artificial intelligence" or "neural networks" because classification methods or decision trees are sufficient for adaptive authentication. Besides, the result of training neural networks cannot be interpreted. So, you will not be able to determine which authentication factors are most important in attack detection.

Advantages

- Machine learning algorithms can identify factors or combinations of authentication factors that are not obvious to the expert
- The possibility of continuous learning while accumulating authentication data and automatic algorithm adjustment when the logic of the authentication services changes

Disadvantages

- Requires qualified personnel to set up
- Cold start problem - the system cannot work until enough data has been collected for machine learning
- Using multiple models simultaneously increases the consumption of computing resources in the process, especially while training the models.
**[Automatic Policy Configuration Using Machine Learning](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users#adaptive-authentication-how-to-improve-security-without-annoying-users-automatic-policy-configuration-using-machine-learning)**
Original file line number Diff line number Diff line change
@@ -1,234 +1,37 @@
# Introduction
This article has moved to the Open Identity Platform documentation site:

This article is intended for developers of single-page applications (SPAs) who seek to configure user authentication. The authentication process will utilize the OAuth2/OIDC protocol with PKCE for enhanced security. OpenAM will serve as a designated authentication server.
[Authentication in a Single‐Page Application via OpenAM using OAuth2 OIDC Protocol](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol).

## OpenAM Configuration
Please use the documentation site for the current version.

## Install OpenAM
<a name="introduction"></a>

Let OpenAM hostname is `openam.example.org` Before starting, add the hostname and IP address to the `hosts` file, for example `127.0.0.0.1 openam.example.org`.
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-introduction)**

On Windows systems, the `hosts` file is located at `C:Windows/System32/drivers/etc/hosts` , on Linux and Mac it is located at `/etc/hosts`.
<a name="openam-configuration"></a>

Next, start the OpenAM Docker container. Run the following command:
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-openam-configuration)**

```bash
docker run -h openam.example.org -p 8080:8080 --name openam openidentityplatform/openam
```
<a name="install-openam"></a>

There is no need to configure OpenAM manually via UI. The following command helps to automate the process:
**[Install OpenAM](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-install-openam)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
<a name="oauth2oidc-provider-configuration"></a>

After successful configuration, you can proceed with further customization.
**[OAuth2/OIDC Provider Configuration](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-oauth2oidc-provider-configuration)**

# OAuth2/OIDC Provider Configuration
<a name="oauth2oidc-configuration"></a>

Go to the OpenAM administrator console at
**[OAuth2/OIDC Configuration](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-oauth2oidc-configuration)**

http://openam.example.org:8080/openam/XUI/#login/
<a name="cors-setup"></a>

In the login field enter the value `amadmin`, in the password field enter the value from the `ADMIN_PWD` parameter of the setup command, in this case `passw0rd`.
**[CORS Setup](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-cors-setup)**

## OAuth2/OIDC Configuration
<a name="react-based-example-spa-application"></a>

Select the desired realm. In the Dashboard section, click the Configure OAuth Provider item.
**[React-Based Example SPA Application](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-react-based-example-spa-application)**

![OpenAM Configure OAuth2 Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/0-configure-oauth2-provider.png)
<a name="test-solution"></a>

Next, Configure OpenID Connect

![OpenAM Configure OpenID Connect](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/1-configure-openid-connect.png)

In the opened form, leave all settings unchanged and click the `Create` button

![OpenAM Configure OpenID Connect Properties](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/2-configure-openid-connect-props.png)

Now let's create an OAuth2/OIDC client that will use SPA application for authentication.

Go to the admin console, select the required realm, select Applications and then OAuth 2.0 from the left menu

In the Agents table click the `New` button

![OpenAM Agents Table](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/3-agents-table.png)

- Enter the Name (client_id) `test_client_id` and Password (client_secret) `changeit` of the new application
- Open the application settings
- Set Client type to Public
- Add the URI of your SPA application to the list of Redirection URIs. In our case, it will be http://localhost:5173/
- Add the `openid` value to the scope list, this is to get the user ID from the returned `id_token` object.
- Token Endpoint Authentication Method, set `client_secret_post`.


## CORS Setup

SPA performs cross-domain queries to get access_token and id_token. To prevent these requests from being blocked by the browser, you need to enable [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/CORS) support in OpenAM.

Open the administrator console. In the top menu, select Configure → Global Services.

![OpenAM Global Services](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/4-global-services.png)

Next, go to CORS Settings and enable CORS support

![OpenAM CORS settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/5-cors-settings.png)

Pres the `Save Changes` button.

# React-Based Example SPA Application

As an example, we will use a React application. For simplicity, we will not validate the state parameter, verify the correctness of the signature of the returned id_token, and so on. However, in a production environment, we highly recommend doing so.

To create a new application, execute the following command in the console:

```bash
npm create vite@latest react-openam-example -- --template react
```

Add the CryptoJS library to the dependencies. It will be needed for `code_challenge` generation.

```bash
cd react-openam-example
npm install crypto-js
```

Replace the contents of the `react-openam-example/src/App.jsx` file with the following code:

```javascript
import { useEffect, useState } from 'react'

import CryptoJS from 'crypto-js';

import './App.css'

const OPENAM_URL = "http://openam.example.org:8080/openam";
const OAUTH2_ENDPOINT = OPENAM_URL + "/oauth2";
const OAUTH2_AUTHORIZE_ENDPOINT = OAUTH2_ENDPOINT + "/authorize";
const OAUTH2_TOKEN_ENDPOINT = OAUTH2_ENDPOINT + "/access_token";
const CLIENT_ID = "test_client";
const SCOPE = "openid";

function App() {

const [user, setUser] = useState("");

//TODO should be randomly generated, saved and then restored in production evironment
const codeVerifier = "a116cb8c-5a1e-4918-a164-255ae3d8f1b1";

useEffect(() => {
const params = new URLSearchParams(window.location.search)
const code = params.get('code')
if(!code) {
return;
}
getToken(code)
}, [])

const getToken = async (code) => {
const resp = await fetch(OAUTH2_TOKEN_ENDPOINT, {
method: "POST",
mode: "cors",
cache: "no-cache",
credentials: "include",
headers: {'content-type': 'application/x-www-form-urlencoded'},
redirect: "follow",
referrerPolicy: "no-referrer",
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: CLIENT_ID,
code_verifier: codeVerifier,
code: code,
redirect_uri: window.location.origin
}),
});
if(resp.ok) {
const accessToken = await resp.json()
//TODO verify id_token signature
const idToken = accessToken['id_token'];
const parts = idToken.split('.')
const payload = parts[1];
const jsonPayload = JSON.parse(atob(payload));
const sub = jsonPayload["sub"]
setUser(sub)
console.log(sub, "authenticated")
} else {
console.log(resp.status)
}
}


const authOpenAM = () => {
const state = "state";
const codeChallenge = CryptoJS.SHA256(codeVerifier).toString(CryptoJS.enc.Base64url);
console.log(codeChallenge);
const queryString = "?redirect_uri=" + encodeURIComponent(window.location.origin) +
"&client_id=" + CLIENT_ID +
"&response_type=code" +
"&state=" + state +
"&scope=" + encodeURIComponent(SCOPE) +
"&code_challenge=" + codeChallenge +
"&code_challenge_method=S256";
window.location = OAUTH2_AUTHORIZE_ENDPOINT + queryString;
}

const getComponent = () => {
if (!user) {
return <>
<div>
<h1>Not authenticated</h1>
</div>
<button onClick={authOpenAM}>Login</button>
</>
} else {
return <h1>User {user} authenticated</h1>
}
}
return getComponent()
}

export default App
```

# Test Solution

Start the SPA with the following command:
```bash
npm run dev
```

Open the application in your browser by URL http://localhost:5173/

![SPA not authenticated](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/7-spa-no-authenticated.png)

Click the `Login` button. You will be redirected to OpenAM authentication. Enter the user login `demo` and password `changeit`.

![OpenAM demo user authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/8-demo-user-authentication.png)

Confirm consent to access the data

![OpenAM demo user consent](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/9-user-consent.png)

After that, the browser will redirect back to the SPA application and successfully authenticate the user. If everything is configured correctly, the SPA application will display a message about successful authentication:

![SPA user demo authenticated](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/10-spa-demo-user-authenticated.png)
**[Test Solution](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol#authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol-test-solution)**
39 changes: 4 additions & 35 deletions Authentication-modules.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,5 @@
* [[Active Directory module]]
* [[Adaptive Risk module]]
* [[Anonymous module]]
* [[Captcha module]]
* [[Certificate module]]
* [[Check channel over send and verify one time code module]]
* [[Confirmation module]]
* [[Data Store module]]
* [[Device Id (Save) module]]
* [[Federation module]]
* [[Authenticator (OATH) module]]
* [[Authenticator (Push) module]]
* [[Authenticator (Push) Registration module]]
* [[HOTP module]]
* [[HTTP Basic module]]
* [[HTTP Header Enrichment module]]
* [[JDBC module]]
* [[LDAP module]]
* [[Membership module]]
* [[NTLM module]]
* [[OATH module]]
* [[OAuth 2.0 / OpenID Connect module]]
* [[OAuth-2 (auth) module]]
* [[OAuth-2 (sso) module]]
* [[OAuth-2 (token) module]]
* [[OpenID Connect id_token bearer module]]
* [[Persistent Cookie module]]
* [[RADIUS module]]
* [[reCaptcha module]]
* [[SAE module]]
* [[SAML2 module]]
* [[Windows Desktop SSO module]]
* [[Windows NT module]]
* [[WSSAuth module]]
This article has moved to the Open Identity Platform documentation site:

How-to [[Write a custom authentication module]]
[Authentication modules](https://doc.openidentityplatform.org/openam/how-to/authentication-modules).

Please use the documentation site for the current version.
60 changes: 28 additions & 32 deletions Captcha-module.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
This article has moved to the Open Identity Platform documentation site:

# ReCaptcha Authentication Module
ReCaptcha authentication module allows use Google ReCaptcha to make sure that authenticating user is a real person and not a Robot.
[Captcha module](https://doc.openidentityplatform.org/openam/how-to/captcha-module).

This module included in OpenAM distribution since [14.1.1 version](https://github.com/OpenIdentityPlatform/OpenAM/releases/tag/14.1.1)
Please use the documentation site for the current version.

To use this module, at first you should receive recevie ReCaptcha's **key** and **secret key** from **Google**.
<a name="recaptcha-authentication-module"></a>

## Setup Authentication Module Gobally
To configure the [[reCaptcha module]] globally in the AM console, navigate to [[Configuration]] > [[Authentication]], and then, click **ReCaptcha**.
Module settings are shown on the picture below:
![ReCaptcha Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/recaptcha/recaptcha-settings.png)
**[ReCaptcha Authentication Module](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-recaptcha-authentication-module)**

## Setup Authentication Chain
<a name="setup-authentication-module-gobally"></a>

![ReCaptcha Authentication Chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/recaptcha/recaptcha-auth-chain.png)
In this picture, at first, user solves recaptcha, and then recaptcha module allows him to authenticate in DataStore authentication module.
As there is no Pricipal at authentication chain start, if user solves ReCaptcha, it returns ignore and skips user to DataStore authentication module.
If users does not solve ReCaptcha, authentication starts over.
**[Setup Authentication Module Gobally](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-setup-authentication-module-gobally)**

## [[ssoadm]] service name: **sunAMAuthReCaptchaService**
<a name="setup-authentication-chain"></a>

### Key
Specifies the key, obtained from Google in ReCaptcha administartion console
**[Setup Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-setup-authentication-chain)**

[[ssoadm]] attribute: **org.openidentityplatform.openam.authentication.modules.recaptcha.ReCaptcha.key**
<a name="ssoadm-service-name-sunamauthrecaptchaservice"></a>

### Secret Key
Specifies the secret key, obtained from Google in ReCaptcha administartion console
**[
ssoadm service name: sunAMAuthReCaptchaService
](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-ssoadm-service-name-sunamauthrecaptchaservice)**

[[ssoadm]] attribute: **org.openidentityplatform.openam.authentication.modules.recaptcha.ReCaptcha.secret**
<a name="key"></a>

### ReCaptcha JavaScript URL
Google's ReCaptcha JavaScript library URL
**[Key](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-key)**

[[ssoadm]] attribute: **org.openidentityplatform.openam.authentication.modules.recaptcha.ReCaptcha.jsUrl**
<a name="secret-key"></a>

### ReCaptcha Verify URL
Google's ReCaptcha verification endpoint
**[Secret Key](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-secret-key)**

[[ssoadm]] attribute: **org.openidentityplatform.openam.authentication.modules.recaptcha.ReCaptcha.verifyUrl**
<a name="recaptcha-javascript-url"></a>

### ReCaptcha Verify URL connect timeout
Google's ReCaptcha verification endpoint connect timeout (default 1500 ms)
**[ReCaptcha JavaScript URL](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-recaptcha-javascript-url)**

[[ssoadm]] attribute: **org.openidentityplatform.openam.authentication.modules.recaptcha.ReCaptcha.connect.timeout**
<a name="recaptcha-verify-url"></a>

### ReCaptcha Verify URL read timeout
Google's ReCaptcha verification endpoint read timeout (default 2500 ms)
**[ReCaptcha Verify URL](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-recaptcha-verify-url)**

[[ssoadm]] attribute: **org.openidentityplatform.openam.authentication.modules.recaptcha.ReCaptcha.read.timeout**
<a name="recaptcha-verify-url-connect-timeout"></a>

**[ReCaptcha Verify URL connect timeout](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-recaptcha-verify-url-connect-timeout)**

<a name="recaptcha-verify-url-read-timeout"></a>

**[ReCaptcha Verify URL read timeout](https://doc.openidentityplatform.org/openam/how-to/captcha-module#captcha-module-recaptcha-verify-url-read-timeout)**
10 changes: 5 additions & 5 deletions Config-OpenAM-as-OAuth2-Service-Provider.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
* [[Login via Facebook OAuth2 Identity Provider]]
* [[Login via MSLiveID OAuth2 Identity Provider]]
* [[Login via VK OAuth2 Identity Provider]]
* [[Login via Odnoklassniki OAuth2 Identity Provider]]
* [[Login via "Госуслуги РФ" OAuth2 Identity Provider]]
This article has moved to the Open Identity Platform documentation site:

[Config OpenAM as OAuth2 Service Provider](https://doc.openidentityplatform.org/openam/how-to/config-openam-as-oauth2-service-provider).

Please use the documentation site for the current version.
Original file line number Diff line number Diff line change
@@ -1,189 +1,49 @@
This article has moved to the Open Identity Platform documentation site:

## Introduction
[Configuring authentication in OpenAM via Yandex Cloud using the SAML protocol](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol).

In this article, we will configure authentication in OpenAM using user accounts via Yandex Cloud. This will allow you to configure authentication in your corporate applications via OpenAM using Yandex Cloud as the Identity Provider (IdP) and OpenAM as the Service Provider (SP).
Please use the documentation site for the current version.

## Configuring Yandex Cloud
<a name="introduction"></a>

1. Go to the [Yandex Cloud Organization](https://org.cloud.yandex.ru/) service.
2. Open the **Identity Hub** tab.
3. In the left pane, select the [Applications](https://center.yandex.cloud/organization/apps) section.
4. Click the **Create Application** button
5. Select the SAML (Security Assertion Markup Language) application type
6. Enter the application name, for example, **openam-saml**
7. Click the **Create Application** button
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-introduction)**

<a name="configuring-yandex-cloud"></a>

![Yandex Cloud Create New App](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/0-yandex-cloud-new-app.pngg)
**[Configuring Yandex Cloud](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-configuring-yandex-cloud)**

After creating the application, open its settings and click the **Download Certificate** button. We will need it for further configuration of OpenAM.
<a name="service-provider-configuration"></a>

### Service Provider Configuration
**[Service Provider Configuration](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-service-provider-configuration)**

1. Open the Yandex settings for the **openam-saml** application and configure the settings:
1. **SP Entity ID:** `http://localhost:8080/openam`
2. **ACS URL:** `http://localhost:8080/openam/Consumer/metaAlias/sp`
2. Save the changes.
<a name="adding-users"></a>

![Yandex Cloud Application Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/1-yandex-cloud-app-settings.png)
**[Adding users](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-adding-users)**

### Adding users
<a name="configuring-openam"></a>

Add a user pool:
**[Configuring OpenAM](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-configuring-openam)**

1. In the **Identity Hub** section, select **User Pools** from the menu on the left.
2. Click the **Create User Pool** button.
3. Enter the pool details and click **Create User Pool**.
<a name="installing-openam"></a>

![Yandex Clound New User Pool](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/2-yandex-cloud-new-user-pool.png)
**[Installing OpenAM](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-installing-openam)**

Add a user to the pool
<a name="realm-configuration"></a>

1. In the **Identity Hub** section of the left-hand menu, select **Users**
2. Click the **Add User** button
3. In the pop-up menu, select **Create New User**
4. Remember the password, as you will need it to log in to OpenAM
5. Enter the user details and click **Add User**
**[Realm Configuration](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-realm-configuration)**

![Yandex Cloud New User](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/3-yandex-cloud-new-user.png)
<a name="configuring-the-service-provider"></a>

## Configuring OpenAM
**[Configuring the Service Provider](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-configuring-the-service-provider)**

### Installing OpenAM
<a name="configuring-the-identity-provider"></a>

For simplicity, deploy OpenAM in a Docker container with the command
**[Configuring the Identity Provider](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-configuring-the-identity-provider)**

```bash
docker run -p 8080:8080 --name openam openidentityplatform/openam
```
<a name="verifying-the-solution"></a>

And perform the initial setup
**[Verifying the solution](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-verifying-the-solution)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://localhost:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=localhost
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=localhost
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
<a name="whats-next"></a>

Add the certificate you downloaded earlier for the Yandex Cloud application you created to the OpenAM keystore.

To do this, copy the certificate to the container.

```bash
docker cp openam-saml.cer openam:/usr/openam/config/openam
```

The password for the keystore is located in the file `/usr/openam/config/openam/.storepass`.

You can view it using the command

```bash
docker exec openam bash -c 'cat /usr/openam/config/openam/.storepass'
```

Import the certificate into the OpenAM keystore

```bash
docker exec -it -w '/usr/openam/config/openam' openam bash -c 'keytool -importcert \
-alias "yandex-cloud-cert" \
-keystore keystore.jceks \
-storetype JCEKS \
-file openam-saml.cer'
```

Enter the password and confirm that the certificate is trusted.

Restart the OpenAM container.

```bash
docker restart openam
```

### Realm Configuration

Log in to the administrator console at [http://localhost:8080/openam](http://localhost:8080/openam/). Use the login `amadmin` and password `passw0rd` respectively.

1. Open **Top Level Realm.**
2. In the menu on the left, go to **Authentication → Settings**.
3. Go to the **User Profile** tab and set the **User Profile** setting to **Ignore**.
4. Click **Save Changes.**

![OpenAM Realm Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/4-openam-realm-settings.png)


### Configuring the Service Provider

1. In the administrator console, select **Top Level Realm**
2. On the **Common Tasks** panel, click **Configure SAMLv2 Provider**
3. Next, click **Create Hosted Service Provider**
4. Enter any name for **Circle Of Trust**, for example, `openam-yandex`, and click **Configure.**

![OpenAM Create SAML Service Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/5-openam-create-saml-sp.png)

5. OpenAM will prompt you to configure Remote Identity Provider. Click Yes.

![OpenAM Configure IDP Request](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/6-openam-configure-idp-request.png)

### Configuring the Identity Provider

1. Enter the metadata URL from the Yandex application settings and click Configure.

![OpenAM Configure Remote IDP](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/7-openam-remote-idp.png)

2. Reopen Top Level Realm
3. In the left pane, navigate to **Applications → SAML 2.0**
4. In the **Entity Providers** list, open **http://localhost:8080/openam**
5. On the **Assertion Content** tab, find the **Authentication Context** section
6. Set the **Default Authentication Context** setting to `Password`
7. In the **Authentication Context** table, select the values `Password` and `Password Protected Password`
8. Click **Save**
9. Go to the **Assertion Processing** tab
10. In the **Attribute Mapper** section, set the **Attribute Map** setting to `emailaddress=mail`
11. In the **Auto Federation** section, select the Enabled checkbox and set Attribute to `emailaddress`.
12. Click **Save**.
13. Go to the **Services** tab.
14. In the **SP Service Attributes** section, in the **Assertion Consumer Service** table, select `HTTP-POST`.

![OpenAM Assertion Consumer Service](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/8-openam-assertion-consumer-service.png)

15. Click **Save**

## Verifying the solution

1. Exit the admin console, Yandex console, or open your browser in incognito mode.
2. Follow the authentication link: [http://localhost:8080/openam/spssoinit?metaAlias=/sp&idpEntityID=https%3A%2F%2Fauth.yandex.cloud%2Fsaml%2Fek0pduu9hrclvnque14v&RelayState=http%3A%2F%2Flocalhost%3A8080%2Fopenam](http://localhost:8080/openam/spssoinit?metaAlias=/sp&idpEntityID=https%3A%2F%2Fauth.yandex.cloud%2Fsaml%2Fek0pduu9hrclvnque14v&RelayState=http%3A%2F%2Flocalhost%3A8080%2Fopenam)
3. The Yandex Cloud authentication window will open.
4. In the email field, enter your user ID: `demo-saml@openam-saml.idp.yandexcloud.net` and click →
5. In the password field, enter the corresponding password for your account
6. Click →
![Yandex Cloud Authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/9-yandex-cloud-auth.png)

7. After successful authentication, you will be redirected to the OpenAM console with your Yandex Cloud credentials.

![OpenAM User Profile](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/yandex-cloud-idp-saml/10-openam-user-profile.png)

## What's next

For production use, OpenAM must be deployed using a secure SSL connection, for example on a host and using an FQDN, such as https://openam.example.org/openam.

Next, you can use the OpenIG authorization gateway to set up single sign-on (SSO) for your applications.

For more details on configuring OpenAM and OpenIG, please refer to the documentation at [https://doc.openidentityplatform.org/openam](https://doc.openidentityplatform.org/openam) and [https://doc.openidentityplatform.org/openig](https://doc.openidentityplatform.org/openig).
**[What's next](https://doc.openidentityplatform.org/openam/how-to/configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol#configuring-authentication-in-openam-via-yandex-cloud-using-the-saml-protocol-whats-next)**
84 changes: 42 additions & 42 deletions Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* [OpenAM Contributing](https://github.com/OpenIdentityPlatform/OpenAM/pulls)

### Documentation
* [[Quick Start Guide]]
* [Quick Start Guide](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide)
* [[Installation Guide]]
* [[Upgrade Guide]]
* [[Administration Guide]]
Expand All @@ -20,49 +20,49 @@
* [[Web Policy Agent User’s Guide]]
* [.Net SDK and IIS policy agent](https://github.com/OpenIdentityPlatform/OpenAM-.Net-Agent/blob/master/README.md)

### How To Guides
* [[How OpenAM Works Simple Explanation]]
* [[What is Single Sign On and How does it Work]]
* [[Login and Password Authentication]]
* [[Passwordless Authenticaion Methods]]
* [[Stateful vs Stateless Authentication]]
* [[Adaptive-Authentication: How to Improve Security Without Annoying Users]]
* [How to Add Authorization and Protect Your Application With OpenAM and OpenIG Stack](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-Add-Authorization-and-Protect-Your-Application-With-OpenAM-and-OpenIG-Stack)
* [[How to Setup OAuth2 OIDC Federation in OpenAM]]
* [[How to Setup SAMLv2 Federation in OpenAM]]
* [[How to Setup 2FA with Google Authenticator in OpenAM]]
* [[How to Setup Two Factor Authentication in OpenAM]]
* [Config OpenAM as OAuth2 Service Provider](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Config-OpenAM-as-OAuth2-Service-Provider)
* [[Authentication in a Single‐Page Application via OpenAM using OAuth2 OIDC Protocol]]
* [How To Setup Active Directory Authentication In OpenAM](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-To-Setup-Active-Directory-Authentication-In-OpenAM)
* [How to setup Kerberos Authentication with OpenAM](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-setup-Kerberos-Authentication-with-OpenAM)
* [How to Setup WebAuthn Authentication in OpenAM](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-Setup-WebAuthn-Authentication-in-OpenAM)
* [[SAML Authentication in Yandex Cloud via OpenAM]]
* [[SAML Authentication in WordPress via OpenAM]]
### [How-To Guides](https://doc.openidentityplatform.org/openam/how-to/index)
* [How OpenAM Works Simple Explanation](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation)
* [What is Single Sign On and How does it Work](https://doc.openidentityplatform.org/openam/how-to/what-is-single-sign-on-and-how-does-it-work)
* [Login and Password Authentication](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication)
* [Passwordless Authentication Methods](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods)
* [Stateful vs Stateless Authentication](https://doc.openidentityplatform.org/openam/how-to/stateful-vs-stateless-authentication)
* [Adaptive Authentication: How to Improve Security Without Annoying Users](https://doc.openidentityplatform.org/openam/how-to/adaptive-authentication-how-to-improve-security-without-annoying-users)
* [How to Add Authorization and Protect Your Application With OpenAM and OpenIG Stack](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack)
* [How to Setup OAuth2 OIDC Federation in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam)
* [How to Setup SAMLv2 Federation in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam)
* [How to Setup 2FA with Google Authenticator in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam)
* [How to Setup Two Factor Authentication in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam)
* [Config OpenAM as OAuth2 Service Provider](https://doc.openidentityplatform.org/openam/how-to/config-openam-as-oauth2-service-provider)
* [Authentication in a Single‐Page Application via OpenAM using OAuth2 OIDC Protocol](https://doc.openidentityplatform.org/openam/how-to/authentication-in-a-single-page-application-via-openam-using-oauth2-oidc-protocol)
* [How To Setup Active Directory Authentication In OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-openam)
* [How to setup Kerberos Authentication with OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam)
* [How to Setup WebAuthn Authentication in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam)
* [SAML Authentication in Yandex Cloud via OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam)
* [SAML Authentication in WordPress via OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam)
* [Build OpenAM from source](https://github.com/OpenIdentityPlatform/OpenAM#how-to-build-openam-from-source)
* [[How to Customise OpenAM]]
* [How to disable XUI by default](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-disable-XUI-by-default)
* [How to make OpenAM log more verbose](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-make-OpenAM-log-more-verbose)
* [How to Start OpenAM and OpenDJ in Separate Docker Contaners](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-Start-OpenAM-and-OpenDJ-in-Separate-Docker-Contaners)
* [How To Run OpenAM in Kubernetes](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-To-Run-OpenAM-in-Kubernetes)
* [How to Pass Additional System Property to CATALINA_OPTS to OpenAM Docker Container](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP%3A-How-to-Pass-Additional-System-Property-to-CATALINA_OPTS-to-OpenAM-Docker-Container)
* [Quick OpenAM Docker Configuration From a Command Line](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP%3A-Quick-OpenAM-Docker-Configuration-From-a-Command-Line)
* [How to Persist OpenAM Docker Container Data Between Restarts](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP%3A-How-to-Persist-OpenAM-Docker-Container-Data-Between-Restarts)
* [How to Enable CORS](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP%3A-How-to-Enable-CORS)
* [Migrate OpenAM to Apache Cassandra without Single Point of Failure](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Migrate-OpenAM-to-Apache-Cassandra-without-Single-Point-of-Failure)
* [[How to Use Apache Cassandra as User and Session DataStore in OpenAM]]
* [[How to Devleop a Custom Authentication Module]]
* [[How to Create Custom OpenAM DataStore Integration]]
* [[OpenAM QR Authentication Module]]
* [[Persistent Cookie module]]
* [ReCaptcha Authentication Module](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Captcha-module)
* [OpenAM Monitoring Using Prometheus](https://github.com/OpenIdentityPlatform/OpenAM/wiki/OpenAM-Monitoring-Using-Prometheus)
* [Setup Tracing with OpenTelemetry and Jaeger](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Setup-Tracing-with--OpenTelemetry-and-Jaeger)
* [How to Customise OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-customise-openam)
* [How to disable XUI by default](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default)
* [How to make OpenAM log more verbose](https://doc.openidentityplatform.org/openam/how-to/how-to-make-openam-log-more-verbose)
* [How to Start OpenAM and OpenDJ in Separate Docker Containers](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers)
* [How To Run OpenAM in Kubernetes](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes)
* [How to Pass Additional System Property to CATALINA_OPTS to OpenAM Docker Container](https://doc.openidentityplatform.org/openam/how-to/how-to-pass-additional-system-property-to-catalina-opts-to-openam-docker-container)
* [Quick OpenAM Docker Configuration From a Command Line](https://doc.openidentityplatform.org/openam/how-to/quick-openam-docker-configuration-from-a-command-line)
* [How to Persist OpenAM Docker Container Data Between Restarts](https://doc.openidentityplatform.org/openam/how-to/how-to-persist-openam-docker-container-data-between-restarts)
* [How to Enable CORS](https://doc.openidentityplatform.org/openam/how-to/how-to-enable-cors)
* [Migrate OpenAM to Apache Cassandra without Single Point of Failure](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure)
* [How to Use Apache Cassandra as User and Session DataStore in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam)
* [Creating a Custom Authentication Module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module)
* [How to Create Custom OpenAM DataStore Integration](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration)
* [OpenAM QR Authentication Module](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module)
* [Persistent Cookie module](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module)
* [Captcha module](https://doc.openidentityplatform.org/openam/how-to/captcha-module)
* [OpenAM Monitoring Using Prometheus](https://doc.openidentityplatform.org/openam/how-to/openam-monitoring-using-prometheus)
* [Setup Tracing with OpenTelemetry and Jaeger](https://doc.openidentityplatform.org/openam/how-to/setup-tracing-with-opentelemetry-and-jaeger)
* [IAM Benchmark: OpenAM vs WSO2 vs SimpleSAMLphp vs Shibboleth](https://thehftguy.com/2015/10/14/iam-benchmarks-openam-vs-wso2-vs-simplesamlphp-vs-shibboleth-2/)
* [LDAP Benchmark: 10 million users with OpenAM](https://thehftguy.com/2015/10/23/10-millions-users-accounts-with-ldap-yes-we-can/)

### Spring Boot Integraion Examples
* [[How to Setup Active Directory Authentication in a Spring Boot Application]]
* [[OpenAM and Spring Boot 3 Integration via OIDC OAuth2 Protocol]]
* [[OpenAM and Spring Boot 3 Integration via SAMLv2 Protocol]]
* [[OpenAM and Spring Boot 3 Integration via OpenAM Cookie]]
* [How to Setup Active Directory Authentication in a Spring Boot Application](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application)
* [OpenAM and Spring Boot 3 Integration via OIDC OAuth2 Protocol](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol)
* [OpenAM and Spring Boot 3 Integration via SAMLv2 Protocol](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol)
* [OpenAM and Spring Boot 3 Integration via OpenAM Cookie](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-openam-cookie)
72 changes: 33 additions & 39 deletions How-OpenAM-Works-Simple-Explanation.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,53 @@
- [Introduction](#introduction)
- [OpenAM Ecosystem](#openam-ecosystem)
- [How Resource Protection Works](#how-resource-protection-works)
- [How User Authentication Works](#how-user-authentication-works)
- [Conclusion](#conclusion)
This article has moved to the Open Identity Platform documentation site:

## Introduction
It’s not obvious to understand how to setup Access Management and (Single Sign On) SSO with OpenAM at glance. There’s an explanation of how OpenAM SSO and authentication works in the article below.
[How OpenAM Works Simple Explanation](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation).

## OpenAM Ecosystem
Please use the documentation site for the current version.

There are several components in the Open Identity Platform in addition to OpenAM to setup Access Management system.
### Components
#### OpenAM
The core component of the authentication management system. It is responsible for the authentication process, user management, session, and access policy management.
<a name="introduction"></a>

#### Configuration DataStore
Stores OpenAM configuration data - general settings, realms, authentication modules and so on. For storage, its configuration data OpenAM uses OpenDJ - open source directory server, the part of Open Identity Platform.
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-introduction)**

#### Web Agent
It could be a web server plugin or a standalone web application. Web agent works as PEP (Policy Enforcement Point). Web server plugin should be installed on the server, which process requests to protected resources. Web Agent decides whether an authenticated user could access to a certain resource or not.
<a name="openam-ecosystem"></a>

Open Identity Platform provides Web Agent as a standalone web application - OpenIG and some web server plugins - for Microsoft Internet Information Services, Apache Tomcat, and Apache HTTP Server.
**[OpenAM Ecosystem](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-openam-ecosystem)**

#### User Data Store
Storage for the different kinds of identities, which OpenAM uses for authentication. By default, OpenAM uses OpenDJ as a user data store, but also could use Microsoft Active Directory, or any LDAP compatible server. OpenAM also supports any relational database via JDBC and Cassandra as a user data store.
<a name="components"></a>

#### Session Data Store
Persistent storage for session information. If OpenAM restarts or a request switch to another instance of OpenAM, then session information could be restored from the session data store.
### Scheme
Simple OpenAM scheme shown on the picture below.
**[Components](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-components)**

![OpenAM Scheme](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-simple/openam-scheme.png)
<a name="openam"></a>

## How Resource Protection Works
User tries to access a protected resource, Web Agent asks OpenAM whether user request satisfies the security policy or not.
**[OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-openam)**

If the request satisfies policy OpenAM returns session to Web Agent. Web Agent enriches the user request with session data and forwards request to the protected resource and proxies protected server response back to the user.
<a name="configuration-datastore"></a>

If the user is not authenticated or the user session violates a policy, Web Agent redirects the user to authentication to the OpenAM server for authentication or additional authorization.
**[Configuration DataStore](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-configuration-datastore)**

The process is shown on the image below:
<a name="web-agent"></a>

![OpenAM Scheme](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-simple/openam-protected-access.png)
**[Web Agent](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-web-agent)**

## How User Authentication Works
While authentication OpenAM asks the user to provide his credentials. OpenAM checks if the user exists User Data Store and validates credentials.
<a name="user-data-store"></a>

If provided credentials are valid, OpenAM creates a new authenticated session in the Session Data Store and enriches the session with user data and authentication process details.
**[User Data Store](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-user-data-store)**

If credentials are invalid, OpenAM denies authentication.
<a name="session-data-store"></a>

After successful authentication, the user is redirected to the protected resource.
This process is shown in the diagram below.
**[Session Data Store](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-session-data-store)**

![OpenAM Scheme](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-simple/openam-authentication.png)
<a name="scheme"></a>

## Conclusion
Of course, this document does not fully cover all OpenAM functionality as Federation Authentication, adaptive authentication, how to organize high availability and many more other functionalities. Its purpose just is just to make a more familiar and basic understanding of how OpenAM works.
**[Scheme](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-scheme)**

<a name="how-resource-protection-works"></a>

**[How Resource Protection Works](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-how-resource-protection-works)**

<a name="how-user-authentication-works"></a>

**[How User Authentication Works](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-how-user-authentication-works)**

<a name="conclusion"></a>

**[Conclusion](https://doc.openidentityplatform.org/openam/how-to/how-openam-works-simple-explanation#how-openam-works-simple-explanation-conclusion)**
2 changes: 1 addition & 1 deletion How-To-Guides.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
see https://github.com/OpenIdentityPlatform/OpenAM/wiki#how-to-guides
See [OpenAM How-To Guides](https://doc.openidentityplatform.org/openam/how-to/index).
260 changes: 19 additions & 241 deletions How-To-Run-OpenAM-in-Kubernetes.md
Original file line number Diff line number Diff line change
@@ -1,259 +1,37 @@
## Preface
This article has moved to the Open Identity Platform documentation site:

This article describes how to deploy [OpenAM](https://github.com/OpenIdentityPlatform/OpenAM) with embedded [OpenDJ](https://github.com/OpenIdentityPlatform/OpenDJ) on Kubernetes.
We will use OpenAM Docker image from Docker Hub Registry
[https://hub.docker.com/r/openidentityplatform/openam/](https://hub.docker.com/r/openidentityplatform/openam/)
[How To Run OpenAM in Kubernetes](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes).

In this tutorial, we will use Minikube as a local Kubernetes cluster.
`kubectl` should also be installed
Please use the documentation site for the current version.

Start Minikube with at least 4 cores, and 8 GB of memory to avoid insufficient resources errors.
<a name="preface"></a>

```
minikube start --cpus=4 --memory=8g
```
**[Preface](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-preface)**

## Create OpenAM Service
<a name="create-openam-service"></a>

The following service will be used for DNS lookups between OpenAM Pods and clients.
**[Create OpenAM Service](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-create-openam-service)**

Create `openam-service.yaml` file with the following contents:
<a name="create-openam-statefulset"></a>

**`openam-service.yaml`**:
```yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: openam
name: openam
spec:
clusterIP: None
ports:
- port: 8080
selector:
app: openam
```
**[Create OpenAM StatefulSet](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-create-openam-statefulset)**

Then create service in Kubernetes using `kubectl`:
```
kubectl apply -f openam-service.yaml
```
Make sure the service has been created:
<a name="openam-setup-and-configuration"></a>

```
kubectl get svc openam-service
**[OpenAM Setup and Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-openam-setup-and-configuration)**

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
openam-service ClusterIP None <none> 8080/TCP 7s
```
<a name="add-external-access-via-ingress"></a>

## Create OpenAM StatefulSet
**[Add External Access via Ingress](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-add-external-access-via-ingress)**

Create `openam-statefulset.yaml` file with the following contents:
<a name="preparation"></a>

**`openam-statefulset.yaml`**:
```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: openam
labels:
app: openam
spec:
serviceName: openam
replicas: 1
selector:
matchLabels:
app: openam
template:
metadata:
labels:
app: openam
spec:
containers:
- name: openam
image: openidentityplatform/openam
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 4444
protocol: TCP
- containerPort: 50389
protocol: TCP
env:
- name: CATALINA_OPTS
value: "-Xmx2048m -server -Dcom.iplanet.services.configpath=/home/openam/openam -Dcom.sun.identity.configuration.directory=/home/openam/openam"
livenessProbe:
failureThreshold: 3
httpGet:
path: /openam/isAlive.jsp
port: 8080
scheme: HTTP
initialDelaySeconds: 120
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 3
readinessProbe:
failureThreshold: 3
httpGet:
path: /openam/isAlive.jsp
port: 8080
scheme: HTTP
initialDelaySeconds: 120
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 3
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- name: openam-data
mountPath: /usr/openam/config
volumeClaimTemplates:
- metadata:
name: openam-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 5Gi
```
**[Preparation](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-preparation)**

Create OpenAM StatefulSet in Kubernetes
```
kubectl apply -f openam-statefulset.yaml
```
<a name="setup-ingress"></a>

Check if StatefulSet is wokring
```
kubectl get statefulset openam
**[Setup ingress](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-setup-ingress)**

NAME READY AGE
openam 1/1 5m
```
Wait for pod is created
<a name="test-access"></a>

Get created Pods
```
kubectl get pods -l="app=openam"
NAME READY STATUS RESTARTS AGE
openam-0 1/1 Running 0 5m
```

## OpenAM Setup and Configuration

Lets check OpenAM pod status
```
$ kubectl exec -it openam-0 -- curl -v http://localhost:8080/openam/isAlive.jsp
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /openam/isAlive.jsp HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 302
< Location: http://localhost:8080/openam/config/options.htm
< Content-Length: 0
< Date: Mon, 16 Dec 2019 07:23:26 GMT
<
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
```

isAlive response redirects to the configuration page, that means OpenAM is not configured.
Let's configure the instance.

In `/etc/hosts` file add the following entry:
```
127.0.0.1 openam-0.openam.default.svc.cluster.local
```
Then forward OpenAM port from the service
```
kubectl port-forward svc/openam 8080
```

Open [http://openam-0.openam.default.svc.cluster.local:8080/openam/](http://openam-0.openam.default.svc.cluster.local:8080/openam/) url in your browser.

You will be redirected to the configuration screen
![OpenAM Configuration Start](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-conf-start.png)

Click __Create Default Configuration__.

![OpenAM License Agreement](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-conf-license.png)

Accept License Agreement

![OpenAM Set Passwords](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-conf-passwords.png)

Set password for default admin user and policy agent

Press __Create Configuration__.
After configuration successfully created, press __Proceed to Login__ or open [http://openam-0.openam.default.svc.cluster.local:8080/openam/console](http://openam-0.openam.default.svc.cluster.local:8080/openam) link in browser.

## Add External Access via Ingress

### Preparation

For example you need OpenAM address be [http://openam.acme.org/openam](http://openam.acme.org/openam)

Goto OpenAM console, __Deployment__ -> __Sites__ and create new site, for example,
http://openam.acme.org:80/openam

![OpenAM Add Site](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/kubernetes/openam-add-site.png)

Then goto OpenAM console, __Configure__ -> __Global Services__ -> __Platform__
and add Cookie domain as shown on the picture below

![OpenAM Add Cookie Domain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/kubernetes/openam-add-cookie-domain.png)

### Setup ingress

To make OpenAM accessible form external network we will use Ingress

If you use Minikube, enable ingress using the following command
```
minikube addons enable ingress
```
Create `openam-ingerss.yaml` file

**`openam-ingress.yaml`**:
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: openam-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /openam
spec:
rules:
- http:
paths:
- path: /openam
backend:
serviceName: openam
servicePort: 8080
```
And create Ingress for OpenAM service in Kubernetes
```
kubectl apply -f openam-ingress.yaml
```
### Test Access

Get your minikube IP
```
echo $(minikube ip)
192.168.64.15
```

And add the following entry to your `/etc/hosts` file
```
192.168.64.15 openam.acme.org
```

Then open [http://openam.acme.org/openam](http://openam.acme.org/openam) url in your browser, and you should see authentication screen
**[Test Access](https://doc.openidentityplatform.org/openam/how-to/how-to-run-openam-in-kubernetes#how-to-run-openam-in-kubernetes-test-access)**
56 changes: 9 additions & 47 deletions How-To-Setup-Active-Directory-Authentication-In-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,17 @@
## Preface
This article has moved to the Open Identity Platform documentation site:

If your organization uses Microsoft Active Directory for user storage, it is a good practice to use Active Directory user accounts to authenticate in all your enterprise applications. OpenAM supports Microsoft Active Directory
[How To Setup Active Directory Authentication In OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-openam).

But setting up Microsoft Active Directory as a user data store could be tricky. In this article, we'll help you to set up user data store in OpenAM
Please use the documentation site for the current version.

## Setup Active Directory User Data Store
<a name="preface"></a>

Enterprise users should be in a separate realm.
**[Preface](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-openam#how-to-setup-active-directory-authentication-in-openam-preface)**

---
<a name="setup-active-directory-user-data-store"></a>

**NOTE**
**[Setup Active Directory User Data Store](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-openam#how-to-setup-active-directory-authentication-in-openam-setup-active-directory-user-data-store)**

*Of course, you can use an existing realm or even use different data stores in a single realm in OpenAM. But in this manual, we will create a separate realm and a sigle data store for employees*

---

So login in OpenAM console as amadmin and create realm `/staff`. Delete default user Data Store in `/staff` realm.

Then create Active Directory data store with type Active Directory.

There are the most important settings in a table below:

| Setting | Value|
|-|-|
|**Ldap Server**| AD host and port, for example: ad.example.com:389 |
|**LDAP Bind DN** | Bund DN or user name for AD, for example `EXAMPLE\Administrator` |
|**LDAP Bind Password** | Bind DN password|
|**LDAP Organization DN** | DN where users are located DC=ad,DC=example,DC=com|
|**LDAP Connection Pool Maximum Size** | 128|
|**Attribute Name Mapping** | uid=sAMAccountName <br> userPassword=unicodePwd|
|**LDAPv3 Plug-in Supported Types and Operations** | user=read <br> group=read <br> realm=read |
|**LDAP Users Search Attribute:** | sAMAccountName |
|**LDAP Users Search Filter** | (objectclass=person)|
|**DN Cache** | Enabled |


## Test Data Store and Authentication

If you set all settings correctly, you should see user account form your active directory, in Subjects tab in the realm.

Then test authentication:
Open OpenAM URL in your browser, for example

For XUI:

[http://openam.example.org:8080/openam/XUI/?org=/staff#login/](http://openam.example.org:8080/openam/XUI/?org=/staff#login/)

For legacy UI:

[http://openam.example.org:8080/openam/UI/Login?org=/staff](http://openam.example.org:8080/openam/UI/Login?org=/staff)

Enter your Active Directory credentials, and you should be successfully authenticated
<a name="test-data-store-and-authentication"></a>

**[Test Data Store and Authentication](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-openam#how-to-setup-active-directory-authentication-in-openam-test-data-store-and-authentication)**
Original file line number Diff line number Diff line change
@@ -1,353 +1,41 @@
# Introduction
This article has moved to the Open Identity Platform documentation site:

In the following article, we will set up centralized authentication with OpenAM and set up gateway access to a test application with OpenIG. OpenIG will use an authentication session issued by OpenAM for authorization.
We will use an application developed using Spring Boot and Spring Security as the protected application.
The source code of the application is located on [GitHub](https://github.com/OpenIdentityPlatform/openam-openig-springboot-example).
For the demonstration purposes, we will run services in Docker containers with the `docker compose` tool.
[How to Add Authorization and Protect Your Application With OpenAM and OpenIG Stack](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack).

The authorization diagram is in the picture below:
Please use the documentation site for the current version.

![OpenAM OpenIG auth scheme](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig/openam-openig-auth-scheme.png)
<a name="introduction"></a>

# Run the Test Application
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-introduction)**

Create a `docker-compose.yaml` file and add `spring-service` to the services section.
Map the 8081 port to test for a functional check
<a name="run-the-test-application"></a>

`docker-compose.yaml`
```yaml
services:
spring-service:
container_name: spring-service
image: openidentityplatform/spring-security-openam-example
restart: always
ports:
- "8081:8081"
environment:
JAVA_OPTS: -Dspring.profiles.active=jwt
networks:
openam_network:
aliases:
- spring-service
**[Run the Test Application](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-run-the-test-application)**

networks:
openam_network:
driver: bridge
```
<a name="openam-setup"></a>

Once the application is running, let's check access to the API for which we need to add authentication.
**[OpenAM Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-openam-setup)**

```bash
curl http://localhost:8081/api/protected-jwt | json_pp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 105 0 105 0 0 12684 0 --:--:-- --:--:-- --:--:-- 13125
{
"error" : "Unauthorized",
"path" : "/protected-jwt",
"status" : 401,
"timestamp" : "2024-04-16T06:01:25.331+00:00"
}
```
For successful authentication, a valid JWT must be passed to the API in the Authorization HTTP header. This is what the OpenAM and OpenIG stack will be responsible for. Shut down the test service with the `docker compose down` command for now.
<a name="sts-setup"></a>

## OpenAM Setup
**[STS Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-sts-setup)**

Let's configure the OpenAM authentication service. It will be responsible for authentication and converting the authentication token to JWT (see below).
<a name="setting-up-a-test-user"></a>

Add the OpenAM and OpenIG hostnames to the `hosts` file, for example `127.0.0.1 openam.example.org openig.example.org`.
On Windows systems, the hosts file is located at `C:\Windows\System32\drivers\etc\hosts`, on Linux and Mac it is located at `/etc/hosts`.
Add the OpenAM service to the `docker-compose.yaml` file:
**[Setting up a test user](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-setting-up-a-test-user)**

```yaml
...
openam:
image: openidentityplatform/openam:latest
container_name: openam
ports:
- "8080:8080"
networks:
openam_network:
aliases:
- openam.example.org
...
```
<a name="openig-setup"></a>

Start OpenAM with the `docker compose up openam` command. Once OpenAM is running, configure using the following command:
**[OpenIG Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-openig-setup)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
And wait for the command execution to complete.
<a name="test-the-solution"></a>

## STS Setup
STS (Security Token Service) converts an OpenAM token to a JWT. After authentication, OpenAM returns an authentication token, which is a randomly generated sequence of characters. The STS service is responsible for converting the authentication token into a JWT, which contains information about the authenticated user. OpenIG will use STS for authorization.
To configure STS, go to the administrator console URL
[http://openam.example.org:8080/openam/XUI/#login/](http://openam.example.org:8080/openam/XUI/#login/)
In the login field enter the `amadmin` value, in the password field enter the value from the `ADMIN_PWD` parameter of the setup command, in this case, `passw0rd`.
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-test-the-solution)**

![OpenAM Console Realm](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig/openam-console-realm.png)
<a name="test-the-api-authorization"></a>

In the left menu click **STS** and create a new **STS Instance** with the following settings:
**[Test the API Authorization](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-test-the-api-authorization)**

| Setting | Value |
|--|--|
|Supported Token Transforms|OPENAM->OPENIDCONNECT;don't invalidate interim OpenAM session|
|Deployment Url Element|jwt|
|The id of the OpenID Connect Token Provider| https://openam.example.org/openam|
|Client secret | changeme|
|Confirm client secret | changeme |
|The audience for issued tokens | https://openam.example.org/openam|
<a name="test-the-ui-authorization"></a>

Then press the **Create** button

## Setting up a test user
In the OpenAM admin console, navigate to the root realm and select `Subjects` from the left menu. Set the password for the `demo` user. To do this, select it in the list of users, and click the `Edit` link under Password. Enter and save the new password. Next, log out of the administrator console.

# OpenIG Setup

OpenIG is responsible for authorization policies for back-end services. It converts the authentication token to a JWT in the OpenAM service and after successful authorization, passes the JWT to the back-end services in the HTTP Authorization header.

Create an `openig-config` folder and add two files to it: `admin.json`
```json
{
"prefix" : "openig",
"mode": "PRODUCTION"
}
```

and `config.json`:
```json
{
"heap": [
],
"handler": {
"type": "Chain",
"config": {
"filters": [

],
"handler": {
"type": "Router",
"name": "_router",
"capture": "all"
}
}
}
}
```

Next, add a route that will proxy user requests to the test application, enriching the request with an Authorization header with a JWT token obtained from OpenAM.
Create a folder `openig-config/routes/` and add the `10-protected.json` file to the folder.

`10-protected.json`
```json
{
"name": "${matches(request.uri.path, '^/api/protected-jwt') || matches(request.uri.path, '^/protected-jwt')}",
"condition": "${matches(request.uri.path, '^/api/protected-jwt') || matches(request.uri.path, '^/protected-jwt')}",
"monitor": true,
"timer": true,
"handler": {
"type": "Chain",
"config": {
"filters": [
{
"type": "ConditionalFilter",
"config": {
"condition": "${empty contexts.sts.issuedToken and not empty request.cookies['iPlanetDirectoryPro'][0].value}",
"delegate": {
"type": "TokenTransformationFilter",
"config": {
"openamUri": "${system['openam']}",
"realm": "/",
"instance": "jwt",
"from": "OPENAM",
"to": "OPENIDCONNECT",
"idToken": "${request.cookies['iPlanetDirectoryPro'][0].value}"
}
}
}
},
{
"type": "ConditionalFilter",
"config": {
"condition": "${not empty contexts.sts.issuedToken}",
"delegate": {
"type": "HeaderFilter",
"config": {
"messageType": "REQUEST",
"remove": [
"Authorization",
"JWT"
],
"add": {
"Authorization": [
"Bearer ${contexts.sts.issuedToken}"
]
}
}
}
}
},
{
"type": "ConditionEnforcementFilter",
"config": {
"condition": "${not empty contexts.sts.issuedToken}",
"failureHandler": {
"type": "StaticResponseHandler",
"config": {
"status": 302,
"reason": "Found",
"headers": {
"Content-Type": [
"application/json"
],
"Location": [
"${system['openam']}/UI/Login?org=/&goto=${urlEncode(contexts.router.originalUri)}"
]
},
"entity": "{ \"Redirect\": \"${system['openam']}/UI/Login?org=/&goto=${urlEncode(contexts.router.originalUri)}\"}"
}
}
}
}
],
"handler": "EndpointHandler"
}
},
"heap": [
{
"name": "EndpointHandler",
"type": "DispatchHandler",
"config": {
"bindings": [
{
"handler": "ClientHandler",
"capture": "all",
"baseURI": "${matchingGroups(system['spring-service'],\"((http|https):\/\/(.[^\/]*))\")[1]}"
}
]
}
}
]
}
```
This route authorizes two endpoints: API - `/api/protected-jwt` and UI - `/protected-jwt`.
Add the OpenIG service to the `docker-compose.yaml` file and remove the port mapping from the `spring-service`. Now this service is available only through OpenIG.

```yaml
services:
openam:
image: openidentityplatform/openam:latest
container_name: openam
ports:
- "8080:8080"
networks:
openam_network:
aliases:
- openam.example.org

openig:
image: openidentityplatform/openig:latest
container_name: openig
volumes:
- ./openig-config:/usr/local/openig-config:ro
environment:
CATALINA_OPTS: -Dopenig.base=/usr/local/openig-config -Dspring-service=http://spring-service:8081 -Dopenam=http://openam.example.org:8080/openam
ports:
- "8081:8080"
networks:
openam_network:
aliases:
- openig.example.org

spring-service:
container_name: spring-service
image: openidentityplatform/spring-security-openam-example
restart: always
# ports:
# - "8081:8081"
environment:
JAVA_OPTS: -Dspring.profiles.active=jwt
networks:
openam_network:
aliases:
- spring-service

networks:
openam_network:
driver: bridge
```
Start OpenIG and the demo application services with the `docker compose up openig spring-service` command.

# Test the Solution

## Test the API Authorization

Get the OpenAM authentication token for the `demo` user:

```bash
curl -X POST -H "X-OpenAM-Username: demo" -H "X-OpenAM-Password: passw0rd" \
-H "Content-Type: application/json" -H "Accept-API-Version: resource=2.1" \
http://openam.example.org:8080/openam/json/realms/root/authenticate | json_pp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 159 100 159 0 0 4197 0 --:--:-- --:--:-- --:--:-- 4297
{
"realm" : "/",
"successUrl" : "/openam/console",
"tokenId" : "AQIC5wM2LY4Sfcze3DbBXVSXggTyZNpGfwOoFPLnHwmqLG0.*AAJTSQACMDEAAlNLABM2MTY1Mjg2MzI5Mzc4ODM0MzQ5AAJTMQAA*"
}
```

Call with the received token `/api/protected-jwt` endpoint:

```bash
curl --cookie "iPlanetDirectoryPro=AQIC5wM2LY4Sfcze3DbBXVSXggTyZNpGfwOoFPLnHwmqLG0.*AAJTSQACMDEAAlNLABM2MTY1Mjg2MzI5Mzc4ODM0MzQ5AAJTMQAA*" \
"http://openig.example.org:8081/api/protected-jwt" | json_pp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 30 0 30 0 0 1071 0 --:--:-- --:--:-- --:--:-- 1111
{
"method" : "JWT",
"user" : "demo"
}
```

OpenIG, via OpenAM, converted the authentication token passed in the `iPlanetDirectoryPro` cookie into a JWT and passed this JWT to the `spring-service` test application. The test application retrieved the user information from the JWT and returned a successful response.

## Test the UI Authorization

Log out of the OpenAM administrator console or open the browser in Incognito mode
Open the [http://openig.example.org:8081/protected-jwt](http://openig.example.org:8081/protected-jwt) URL in your browser. OpenIG will not find the authentication token cookie and will redirect the browser to OpenAM authentication. Enter the login `demo`, and password and click the `Log In` button.

![OpenAM demo login](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig/openam-demo-login.png)

After successful authentication, the gateway will redirect the request to the Spring Boot application. It will receive a cookie with an authentication token from the http request, convert the token in OpenAM in STS service to JWT, and pass the received JWT to the demo application. The demo application will verify the JWT and return a successful response.

![OpenAM demo login](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig/protected-app.png)

The source code for the demo application is available at [https://github.com/OpenIdentityPlatform/spring-security-openam-example](https://github.com/OpenIdentityPlatform/spring-security-openam-example).

The source code for the docker compose configuration and OpenIG routes for the article can be found at [https://github.com/OpenIdentityPlatform/openam-openig-springboot-example](https://github.com/OpenIdentityPlatform/openam-openig-springboot-example).
**[Test the UI Authorization](https://doc.openidentityplatform.org/openam/how-to/how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack#how-to-add-authorization-and-protect-your-application-with-openam-and-openig-stack-test-the-ui-authorization)**
316 changes: 17 additions & 299 deletions How-to-Create-Custom-OpenAM-DataStore-Integration.md
Original file line number Diff line number Diff line change
@@ -1,315 +1,33 @@
This article has moved to the Open Identity Platform documentation site:

- [Introduction](#introduction)
- [Custom IdRepo Implementation](#custom-idrepo-implementation)
- [Service Schema](#service-schema)
- [Add Schema to OpenAM Distribution](#add-schema-to-openam-distribution)
- [Add Schema to an Exististing OpenAM Deployment](#add-schema-to-an-exististing-openam-deployment)
- [IdRepo Plugin in Action](#idrepo-plugin-in-action)
- [Conclusion](#conclusion)
[How to Create Custom OpenAM DataStore Integration](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration).

## Introduction
Please use the documentation site for the current version.

OpenAM already have implementations for variuos user data sources - LDAP, Active Directiry, relational databases via JDBC driver and Apache Cassandra. But there are databases that are not integratied into OpenAM. The following manual shows how to implement a custom data source to use for authentication.
We will write together MongoDB integration to authenticate users in MongoDB datastore. The implementations will support only read users from the datastore and won't support write operation or groups, but it would be enough for get the point.
<a name="introduction"></a>

## Custom IdRepo Implementation
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration#how-to-create-custom-openam-datastore-integration-introduction)**

To write your own integration with a custom data source you should extend [com.sun.identity.idm.IdRepo](https://github.com/OpenIdentityPlatform/OpenAM/blob/master/openam-core/src/main/java/com/sun/identity/idm/IdRepo.java) abstract class.
<a name="custom-idrepo-implementation"></a>

To simplify the example our repository will be only able to show users, and authenticate against database.
**[Custom IdRepo Implementation](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration#how-to-create-custom-openam-datastore-integration-custom-idrepo-implementation)**

Lets create `org.openidentityplatform.openam.mongodb.Repo` that extends `com.sun.identity.idm.IdRepo` class. Override `getSupportedOperations`, `getSupportedTypes` and `supportsAuthentication` functions.
<a name="service-schema"></a>

**[Service Schema](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration#how-to-create-custom-openam-datastore-integration-service-schema)**

```java
public class Repo extends IdRepo {
<a name="add-schema-to-openam-distribution"></a>

@Override
public Set<IdOperation> getSupportedOperations(IdType type) {
return Collections.singleton(IdOperation.READ);
}
**[Add Schema to OpenAM Distribution](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration#how-to-create-custom-openam-datastore-integration-add-schema-to-openam-distribution)**

@Override
public Set<IdType> getSupportedTypes() {
return Collections.singleton(IdType.USER);
}
<a name="add-schema-to-an-exististing-openam-deployment"></a>

@Override
public boolean supportsAuthentication() {
return true;
}
**[Add Schema to an Exististing OpenAM Deployment](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration#how-to-create-custom-openam-datastore-integration-add-schema-to-an-exististing-openam-deployment)**

<a name="idrepo-plugin-in-action"></a>

}
```
**[IdRepo Plugin in Action](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration#how-to-create-custom-openam-datastore-integration-idrepo-plugin-in-action)**

Then add MongoDB connection settings and override the `initialize` function.
<a name="conclusion"></a>


```java
private static final String MONGODB_SERVER =
"sun-idrepo-ldapv3-config-ldap-server";

private static final String MONGODB_DATABASE =
"sun-idrepo-ldapv3-config-organization_name";

private static final String USER_PASSWORD_ATTRIBUTE = "userpassword";

String mongoDbUrl;

MongoDatabase mongoDatabase;

String databaseName;

String usersMongoCollection = "users";

@Override
public void initialize(Map<String, Set<String>> configParams) throws IdRepoException {
super.initialize(configParams);
mongoDbUrl = "mongodb://".concat(String.join(",", configParams.get(MONGODB_SERVER)));
databaseName = CollectionHelper.getMapAttr(configParams, MONGODB_DATABASE);
MongoClient mongoClient = MongoClients.create(mongoDbUrl);
mongoDatabase = mongoClient.getDatabase(databaseName);
}
```

Override the functions responsible to search and retrieve attributes from a database:

```java
@Override
public RepoSearchResults search(SSOToken token, IdType type, CrestQuery crestQuery, int maxTime, int maxResults,
Set<String> returnAttrs, boolean returnAllAttrs, int filterOp,
Map<String, Set<String>> avPairs, boolean recursive) throws IdRepoException, SSOException {

final Map<String, Map<String,Set<String>>> result = new HashMap<>();

FindIterable<Document> findIterable = mongoDatabase.getCollection(usersMongoCollection).find().limit(maxResults);
if(CollectionUtils.isNotEmpty(returnAttrs)) {
Bson projection = Projections.fields(Projections.include(new ArrayList<>(returnAttrs)));
findIterable = findIterable.projection(projection);
}

if(MapUtils.isNotEmpty(avPairs)) {
Bson filters = Filters.empty();
for(Map.Entry<String, Set<String>> entry: avPairs.entrySet()) {
List<Bson> entryFilters = entry.getValue().stream().map(v -> Filters.eq(entry.getKey(), v)).collect(Collectors.toList());
Bson entryFilter = Filters.or(entryFilters);
filters = Filters.and(entryFilter);
}
findIterable = findIterable.filter(filters);
}

try(MongoCursor<Document> iterator = findIterable.iterator()) {
while (iterator.hasNext()) {
Document doc = iterator.next();
String id = doc.getObjectId("_id").toHexString();
Map<String, Set<String>> attributesValues = documentToUserAttributes(doc);
result.put(id, attributesValues);
}
}

int errCode = (maxResults > 0 && result.size() > maxResults) ? RepoSearchResults.SIZE_LIMIT_EXCEEDED : RepoSearchResults.SUCCESS;
return new RepoSearchResults(result.keySet(), errCode, result,type);
}

@Override
public Map<String, Set<String>> getAttributes(SSOToken token, IdType type, String name) throws IdRepoException, SSOException {
return getAttributes(token, type, name, null);
}

@Override
public Map<String, Set<String>> getAttributes(SSOToken token, IdType type, String name, Set<String> attrNames) throws IdRepoException, SSOException {
try {
final Bson filter = Filters.eq("_id", new ObjectId(name));
Bson projection = Projections.exclude();
if(attrNames != null) {
projection = Projections.fields(Projections.include(new ArrayList<>(attrNames)));
}
Document doc = mongoDatabase.getCollection(usersMongoCollection).find(filter).projection(projection).first();
if (doc == null) {
return Collections.emptyMap();
}
return documentToUserAttributes(doc);

} catch (Exception e) {
throw new IdRepoException(e.getMessage());
}
}

@Override
public boolean isExists(SSOToken token, IdType type, String name) throws IdRepoException, SSOException {
try {
final Bson filter = Filters.eq("_id", new ObjectId(name));
Document doc = mongoDatabase.getCollection(usersMongoCollection).find(filter).first();
return doc != null;
} catch (Exception e) {
throw new IdRepoException(e.getMessage());
}
}

@Override
public boolean isActive(SSOToken token, IdType type, String name) throws IdRepoException, SSOException {
return true; //consider all identities are active
}
```

Then implement authenticate function, which is responsible to authenticate users against a database. Password hashing is not supported, but should be implemented for production.

```java
@Override
public boolean authenticate(Callback[] credentials) throws IdRepoException, AuthLoginException {
String userName = null;
String password = null;
for (Callback callback : credentials) {
if (callback instanceof NameCallback) {
userName = ((NameCallback) callback).getName();
} else if (callback instanceof PasswordCallback) {
password = new String(((PasswordCallback) callback).getPassword());
}
}
if (userName == null || password == null) {
throw new IdRepoException(IdRepoErrorCode.UNABLE_TO_AUTHENTICATE,Repo.class.getName());
}
try {
Map<String, Set<String>> res = getAttributes(null, IdType.USER, userName, Collections.singleton(USER_PASSWORD_ATTRIBUTE));
if (res!=null && res.containsKey(USER_PASSWORD_ATTRIBUTE) && res.get(USER_PASSWORD_ATTRIBUTE).size() > 0) {
final String storedPassword=res.get(USER_PASSWORD_ATTRIBUTE).iterator().next();
return storedPassword.equals(password);
}
} catch (SSOException e) {
throw new AuthLoginException(e);
}
return false;
}

```

Remaining functions should return default result or throw `IdRepoException`, for example
```java
private final static IdRepoException OPERATION_NOT_SUPPORTED_EXCEPTION = new IdRepoException("operation not supported");

@Override
public Map<String, byte[][]> getBinaryServiceAttributes(SSOToken token, IdType type, String name, String serviceName, Set<String> attrNames) throws IdRepoException, SSOException {
return Collections.emptyMap();
}

@Override
public void modifyService(SSOToken token, IdType type, String name, String serviceName, SchemaType sType, Map<String, Set<String>> attrMap) throws IdRepoException, SSOException {
throw OPERATION_NOT_SUPPORTED_EXCEPTION;
}
```

Build the class and include it into classpath of OpenAM war file as desctibed in [How to Customise OpenAM](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-Customise-OpenAM) article. Dependencies for the maven project

```xml
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
```
## Service Schema

OpenAM MongoDM service sub-schema will look like this.

```xml
<SubSchema i18nKey="MongoDB" inheritance="multiple"
maintainPriority="no" name="MongoDBRepo"
supportsApplicableOrganization="no" validate="yes">
<AttributeSchema cosQualifier="default"
isSearchable="no" name="RequiredValueValidator" syntax="string"
type="validator">
<DefaultValues>
<Value>com.sun.identity.sm.RequiredValueValidator</Value>
</DefaultValues>
</AttributeSchema>
<AttributeSchema any="required" cosQualifier="default"
i18nKey="a4010" isSearchable="no" name="sunIdRepoClass" syntax="string"
type="single" validator="RequiredValueValidator">
<DefaultValues>
<Value>org.openidentityplatform.openam.mongodb.Repo</Value>
</DefaultValues>
</AttributeSchema>
<AttributeSchema any="required" cosQualifier="default"
i18nKey="Servers" isSearchable="no"
name="sun-idrepo-ldapv3-config-ldap-server" syntax="string" type="list"
validator="RequiredValueValidator">
<DefaultValues>
<Value>localhost:27017</Value>
</DefaultValues>
</AttributeSchema>
<AttributeSchema cosQualifier="default" i18nKey="Database"
isSearchable="no" name="sun-idrepo-ldapv3-config-organization_name" syntax="string"
type="single">
<DefaultValues>
<Value>authentication</Value>
</DefaultValues>
</AttributeSchema>
</SubSchema>
```

## Add Schema to OpenAM Distribution

To let OpenAM know about the new Data Source, the subschema should be added to OpenAM `sunIdentityRepositoryService` service configuration.
If you plan to add the repository plugin to OpenAM distribution and/or make a contribution to [OpenAM](https://github.com/OpenIdentityPlatform/OpenAM).
Add MongoDB subschema to subschema list to [openam-server-only/src/main/resources/services/idRepoService.xml](https://github.com/OpenIdentityPlatform/OpenAM/blob/master/openam-server-only/src/main/resources/services/idRepoService.xml) file.

## Add Schema to an Exististing OpenAM Deployment

If you have an existing OpenAM deployment, connect to OpenDJ instance for OpenAM configuration in any LDAP client Application, for example, Apache Directory Studio, and add sub schema to `sunIdentityRepositoryService` xml configuration as shown in the picture below. Then restart OpenAM instance.

![Add ID Repo to OpenDJ](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-idrepo/idrepo-ldap.png)

## IdRepo Plugin in Action

After we have added a new datastore to the schema, create a new MongoDB Data Store in OpenAM and see it in action.

Run MongoDB in docker container in a local environment:

```bash
docker run -p 27017:27017 --name test-mongo mongo:latest
```
Add a couple of users to the MongoDB with the following script:

```javascript
db = connect( 'mongodb://localhost:27017/authentication');
db.users.insertMany([
{
cn: 'John Doe',
sunidentitymsisdnnumber: "123-456-78-90",
userpassword: 'passw0rd',
},
{
cn: 'Jane Doe',
sunidentitymsisdnnumber: "123-456-78-91",
userpassword: 'passw0rd',
},
])
```
Open the OpenAM console, create a new realm `/clients`, remove the existing DataStore, and add a new MongoDB DataStore to the realm.

![MongoDB IdRepo](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-idrepo/idrepo-mongodb.png)

Open the Subjects tab and see if there are user entries:


![MongoDB User Entries](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-idrepo/idrepo-subjects.png)

Test authentication via API, using Universal Id value as login and password from the script above.

```bash
% curl --location --request POST 'http://localhost:8080/openam/json/authenticate?realm=/clients' \
--header 'X-OpenAM-Username: 64994f6b8beb1a6fbe461660' \
--header 'X-OpenAM-Password: passw0rd' \
--header 'Content-Type: application/json'

{"tokenId":"AQIC5wM2LY4Sfcx71mFbrHLrhHsv5hFyLEM_7S-nbKBNrVg.*AAJTSQACMDEAAlNLABI0OTk2NDUxMTgwNTY4NTQ1NjUAAlMxAAA.*","successUrl":"/openam/console","realm":"/clients"}
```

## Conclusion
In the following article, we have developed a very simple User Data Store without any modification, just to understand how it works. For a production environment password hashing connection pooling etc, should be implemented.
**[Conclusion](https://doc.openidentityplatform.org/openam/how-to/how-to-create-custom-openam-datastore-integration#how-to-create-custom-openam-datastore-integration-conclusion)**
179 changes: 13 additions & 166 deletions How-to-Customise-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,178 +1,25 @@
- [Introduction](#introduction)
- [Create Maven Project](#create-maven-project)
- [Run and Debug War File Locally](#run-and-debug-war-file-locally)
- [Customisation Example](#customisation-example)
- [Conclusion](#conclusion)
This article has moved to the Open Identity Platform documentation site:

# Introduction
[How to Customise OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-customise-openam).

OpenAM is a reliable and mature product itself out of the box, have rich functionality and a good extension potential. But there is always a question - how to develop and debug the extensions? In the following article we will create a maven project and do simple OpenAM customisation.
Please use the documentation site for the current version.

# Create Maven Project
<a name="introduction"></a>

Create a maven project with the following `pom.xml` file:
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-customise-openam#how-to-customise-openam-introduction)**

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.openidentityplatform.openam</groupId>
<artifactId>openam</artifactId>
<version>14.7.1</version>
</parent>
<repositories>
<repository>
<id>ossrh-releases</id>
<name>Sonatype OSS</name>
<url>https://oss.sonatype.org/content/repositories/releases/</url>
</repository>
</repositories>
<artifactId>openam-extended</artifactId>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
```
<a name="create-maven-project"></a>

The parent project will be `org.openidentityplatform.openam:openam` so in the following project we can use proper OpenAM dependencies in our project.
**[Create Maven Project](https://doc.openidentityplatform.org/openam/how-to/how-to-customise-openam#how-to-customise-openam-create-maven-project)**

Project packaging should be war, as we build a web application that extends OpenAM server application.
<a name="run-and-debug-war-file-locally"></a>

To override OpenAM server add `org.openidentityplatform.openam:openam-server` dependency to the build section and overlay to `maven-war-plugin`
**[Run and Debug War File Locally](https://doc.openidentityplatform.org/openam/how-to/how-to-customise-openam#how-to-customise-openam-run-and-debug-war-file-locally)**

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.openidentityplatform.openam</groupId>
<artifactId>openam</artifactId>
<version>14.7.1</version>
</parent>
<repositories>
<repository>
<id>ossrh-releases</id>
<name>Sonatype OSS</name>
<url>https://oss.sonatype.org/content/repositories/releases/</url>
</repository>
</repositories>
<artifactId>openam-extended</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.openidentityplatform.openam</groupId>
<artifactId>openam-server</artifactId>
<type>war</type>
</dependency>
</dependencies>
<a name="customisation-example"></a>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<overlays>
<overlay>
<groupId>org.openidentityplatform.openam</groupId>
<artifactId>openam-server</artifactId>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
</project>
```
**[Customisation Example](https://doc.openidentityplatform.org/openam/how-to/how-to-customise-openam#how-to-customise-openam-customisation-example)**

Run `mvn package` command and after a successful build, you can see `openam-extended-14.7.1.war` file. This file you can use this instead of the default OpenAM server war file.
<a name="conclusion"></a>

# Run and Debug War File Locally

Add to the maven pom to the plugins section `cargo-maven2-plugin`:

```xml
...
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<container>
<containerId>tomcat9x</containerId>
<type>embedded</type>
<systemProperties>
<!--configuration directory path-->
<com.iplanet.services.configpath>${basedir}/config</com.iplanet.services.configpath>
<com.sun.identity.configuration.directory>${basedir}/config</com.sun.identity.configuration.directory>
</systemProperties>
</container>
<configuration>
<properties>
<!--openam port-->
<cargo.servlet.port>8080</cargo.servlet.port>
<cargo.rmi.port>8206</cargo.rmi.port>
<cargo.jvmargs> ${java.surefire.options} -Xms4g -Xmx4g</cargo.jvmargs>
</properties>
</configuration>
<deployables>
<deployable>
<type>war</type>
<properties>
<context>openam</context>
</properties>
<pingURL>http://localhost:8080/openam</pingURL>
</deployable>
</deployables>
</configuration>
</plugin>
...
```

Add desired OpenAM FQDN to your hosts file like this:

```
127.0.0.1 openam.example.com
```

To repackage and run war file execute the following command: `mvn package cargo:run`

You should see in the console something like this

```
[INFO] [beddedLocalContainer] Tomcat 9.x Embedded started on port [8080]
[INFO] Press Ctrl-C to stop the container...
```

Open OpenAM console in the browser with the following link [http://openam.example.com:8080/openam](http://openam.example.com:8080/openam) and OpenAM will prompt you to configure a new instance. How to configure a new OpenAM instance is described in [Quick Start Guide](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Quick-Start-Guide). After OpenAM configuration you will be able to use OpenAM locally within your development environment.

OpenAM configuration and log files will be stored in your project in `/config` directory

# Customisation Example

After configuring OpenAM, let’s do something simple to demonstrate customisation. We will modify the default OpenAM login page. We will add Acme corp logo instead of standard OpenAM logo.

The header template is in `XUI/templates/common/LoginHeaderTemplate.html` file. Create `src/main/webapp/XUI/templates/common/LoginHeaderTemplate.html` file in the project root folder. Then add the following contents:

```html
<h1>ACME corp.</h1>
```

Start OpenAM and navigate to the login page.
We can see that OpenAM uses the custom header. You can deploy the custom war file on your production web server

# Conclusion

This article has only shown a simple setup in order to demonstrate the overall approach. In future articles we will show a more complex setup, such as developing a custom authentication module.
**[Conclusion](https://doc.openidentityplatform.org/openam/how-to/how-to-customise-openam#how-to-customise-openam-conclusion)**
525 changes: 41 additions & 484 deletions How-to-Devleop-a-Custom-Authentication-Module.md
Original file line number Diff line number Diff line change
@@ -1,524 +1,81 @@
# Creating a Custom Authentication Module
This article has moved to the Open Identity Platform documentation site:

Source code: [OpenAM Sample Custom Authentication Module](https://github.com/OpenIdentityPlatform/OpenAM/tree/master/openam-samples/custom-authentication-module)
[Creating a Custom Authentication Module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module).

OpenAM comes complete with a wide variety of built-in custom [[authentication modules]], but sometimes customer requirements step outside the functionality provided by the built-in modules. In these instances, it is time to consider writing your own custom authentication module. The OpenAM developer can use the source of the built-in modules as their starting point or start from scratch. If the customer requirement is a very close match to existing functionality then using a built-in module as a starting point will be a good idea. The OpenAM developer should start from scratch if the customer requirements does not match any of the built-in modules.
In this HowTo we look at how to create and configure custom authentication modules.
Please use the documentation site for the current version.

## Requirements for Sample Authentication module
<a name="creating-a-custom-authentication-module"></a>

Our sample authentication module takes username and password as input from the user. This data along with a service specific attribute and the program logic is used to authenticate the user. During this process some errors can occur which will be shown to user in detail. All texts displayed during the authentication must be easily configurable and translatable.
**[Creating a Custom Authentication Module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module)**

In short - we have following requirements
* User will be asked for name and password
* Module has one specific attribute which needs to be configured via OpenAM web-interface
* The authentication UI is configurable and translatable
* Some errors have to be displayed to user in detail
<a name="requirements-for-sample-authentication-module"></a>

## Prepare your development environment
**[Requirements for Sample Authentication module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-requirements-for-sample-authentication-module)**

We will stick with using the basic complier in this HowTo to keep things simple. In order to compile your custom authentication module either on the command line or in your favourite IDE you will need the following OpenAM jar files.
* openam-core*.jar
<a name="prepare-your-development-environment"></a>

In addition you will also require the J2EE Servlet API, you can obtain these from within your favourite container or here.
If you use tomcat then you can find the Servlet API files in the TOMCAT_HOME/lib/servlet-api.jar file.
**[Prepare your development environment](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-prepare-your-development-environment)**

## Design your custom authentication module
<a name="design-your-custom-authentication-module"></a>

First important decision is to pick a name for our authentication module. We decide to call our module SampleAuth.
An OpenAM custom authentication module is comprised of the following components:
**[Design your custom authentication module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-design-your-custom-authentication-module)**

* Authentication logic (SampleAuth.java) which extends the com.sun.identity.authentication.spi.AMLoginModule abstract class
* Principal (SampleAuthPrincipal.java) which implements the java.security.Principal interface
* Callbacks XML file (SampleAuth.xml) which describes the states of authentication logic and the user input needed during those states
* Service configuration XML file (amAuthSampleAuth.xml) which defines how service is configured on OpenAM side
* Authentication module properties file (amAuthSampleAuth.properties)
<a name="the-callbacks-xml-file"></a>

### The Callbacks XML file
**[The Callbacks XML file](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-the-callbacks-xml-file)**

The custom authentication module is designed to ask the user a series of questions in order assert their identity. The order and detail of these questions is set out in the Callbacks XML file. The structure of the XML file is defined in the OPENAM_WAR/WEB-INF/Auth_Module_Properties.dtd file.
<a name="the-custom-authentication-module"></a>

All of the built-in modules XML files are located in the OPENAM_WAR/config/auth/default directory. The OpenAM developer can use these as a starting point for their own callback XML file.
**[The custom authentication module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-the-custom-authentication-module)**

### The custom authentication module
<a name="openam-service-and-properties-file"></a>

All custom authentication modules must extend from the com.sun.identity.authentication.spi.AMLoginModule abstract class. The abstract methods that must be implemented in the custom authentication module are listed below and the OpenAM Javadoc provides useful reference information.
**[OpenAM Service and Properties file](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-openam-service-and-properties-file)**

``` java
public void init(Subject subject, Map sharedState, Map options)
<a name="implement-your-custom-authentication-module"></a>

public int process(Callback[] callbacks, int state)
throws LoginException
**[Implement your custom authentication module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-implement-your-custom-authentication-module)**

public Principal getPrincipal()
```
<a name="sample-callback-xml-file"></a>

The init method is called once by OpenAM when the module is created. The process method is called into when the user submits callbacks back via the Authentication interface. The process method determines what happens next in the authentication process; success, failure or the next state (order) in the XML file. The getPrincipal method is called by OpenAM and must return an implementation of the java.security.Principal interface.
**[Sample Callback XML file](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-sample-callback-xml-file)**

OpenAM does not reuse authentication module instances. This means that we can store information specific to the authentication process in the instance.
<a name="sample-module-code"></a>

### OpenAM Service and Properties file
**[Sample Module Code](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-sample-module-code)**

The OpenAM administration will require a way to configure any custom authentication modules. OpenAM mandates that all authentication modules; built-in or custom are configured in the same way by means of an OpenAM service. At the bare minimum the service should contain an authentication level attribute.
<a name="service-configuration-xml"></a>

The module can find the value of these attributes in the options Map passed as a parameter to the init method.
The properties file is a standard Java properties file that contains the description of the attributes that will be displayed in the console.
**[Service configuration XML](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-service-configuration-xml)**

## Implement your custom authentication module
<a name="properties-file"></a>

### Sample Callback XML file
**[Properties file](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-properties-file)**

Simple callbacks file might look like:
<a name="compile-your-custom-authentication-module"></a>

``` xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ModuleProperties PUBLIC "=//iPlanet//Authentication Module Properties XML Interface 1.0 DTD//EN"
"jar://com/sun/identity/authentication/Auth_Module_Properties.dtd">
**[Compile your custom authentication module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-compile-your-custom-authentication-module)**

<ModuleProperties moduleName="SampleAuth" version="1.0" >
<Callbacks length="2" order="1" timeout="600" header="Please Login" >
<NameCallback isRequired="true">
<Prompt> User Name: </Prompt>
</NameCallback>
<PasswordCallback echoPassword="false" >
<Prompt> Password: </Prompt>
</PasswordCallback>
</Callbacks>
</ModuleProperties>
```
<a name="install-your-custom-authentication-module"></a>

This file defines authentication module SampleAuth with one possible state (order 1) in which 2 pieces of information are asked from the user. All strings that are used to draw the UI are typed into this file.
**[Install your custom authentication module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-install-your-custom-authentication-module)**

According to our requirements we need a little-bit more sophisticated callbacks file. We need dynamic text and we need error state. Following callbacks file achieves this:
<a name="copy-the-service-properties-file"></a>

``` xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ModuleProperties PUBLIC "=//iPlanet//Authentication Module Properties XML Interface 1.0 DTD//EN"
"jar://com/sun/identity/authentication/Auth_Module_Properties.dtd">
**[Copy the service properties file](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-copy-the-service-properties-file)**

<ModuleProperties moduleName="SampleAuth" version="1.0" >
<Callbacks length="0" order="1" timeout="600" header="#WILL NOT BE SHOWN#" />
<Callbacks length="2" order="2" timeout="600" header="#WILL BE SUBSTITUTED#" >
<NameCallback isRequired="true">
<Prompt>#USERNAME#</Prompt>
</NameCallback>
<PasswordCallback echoPassword="false" >
<Prompt>#PASSWORD#</Prompt>
</PasswordCallback>
</Callbacks>
<Callbacks length="1" order="3" timeout="600" header="#WILL BE SUBSTITUTED#" error="true" >
<NameCallback>
<Prompt>#THE DUMMY WILL NEVER BE SHOWN#</Prompt>
</NameCallback>
</Callbacks>
</ModuleProperties>
```
<a name="copy-the-authentication-module-xml-file"></a>

Few comments:
* We need order 1 with 0 callbacks to change all UI strings for following orders. The trial-and-error shows that this dummy state is necessary to achieve dynamic UI-strings.
* The placeholders '#FOO BAR#' have no real meaning, this is just to show that those texts get replaced.
* The order 3 has attribute error set to "true". If the authentication module state machine reaches this order then the authentication has failed. The NameCallback is actually not used and not displayed to user, but the callbacks with length at least 1 is necessary, otherwise the OpenAM won't let us to substitute the header. So it's yet another hack forced upon us.
**[Copy the authentication module XML file](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-copy-the-authentication-module-xml-file)**

### Sample Module Code
<a name="register-the-module-and-the-service-with-openam"></a>

``` java
package com.forgerock.openam.examples;
**[Register the module and the service with OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-register-the-module-and-the-service-with-openam)**

import com.sun.identity.shared.datastruct.CollectionHelper;
import com.sun.identity.authentication.spi.AMLoginModule;
import com.sun.identity.authentication.spi.AuthLoginException;
import com.sun.identity.authentication.spi.InvalidPasswordException;
import com.sun.identity.authentication.util.ISAuthConstants;
import com.sun.identity.shared.debug.Debug;
import java.security.Principal;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
<a name="configure-your-custom-authentication-module"></a>

import java.util.ResourceBundle;
import com.sun.identity.shared.locale.AMResourceBundleCache;

public class SampleAuth extends AMLoginModule {

// Name for the debug-log
private final static String DEBUG_NAME = "SampleAuth";

// Name of the resource-bundle
private final static String amAuthSampleAuth = "amAuthSampleAuth";

// usernames for authentication logic
private final static String USERNAME = "test";
private final static String ERROR_1_NAME = "test1";
private final static String ERROR_2_NAME = "test2";

// orders defined in the callbacks file
private final static int STATE_BEGIN = 1;
private final static int STATE_AUTH = 2;
private final static int STATE_ERROR = 3;


private final static Debug debug = Debug.getInstance(DEBUG_NAME);

private Map options;
private ResourceBundle bundle;

public SampleAuth() {
super();
}

@Override
// In this method we store service attributes and localized properties
// for later use
public void init(Subject subject, Map sharedState, Map options) {
if (debug.messageEnabled()) {
debug.message("SampleAuth::init");
}
this.options = options;
bundle = amCache.getResBundle(amAuthSampleAuth, getLoginLocale());
}

@Override
public int process(Callback[] callbacks, int state) throws LoginException {

if (debug.messageEnabled()) {
debug.message("SampleAuth::process state: " + state);
}

switch (state) {

case STATE_BEGIN:
// No time wasted here - simply modify the UI and
// proceed to next state
substituteUIStrings();
return STATE_AUTH;

case STATE_AUTH:

// Get data from callbacks. Refer to callbacks xml file!
NameCallback nc = (NameCallback) callbacks[0];
PasswordCallback pc = (PasswordCallback) callbacks[1];
String username = nc.getName();
String password = new String(pc.getPassword());

// First errorstring is stored in "sampleauth-error-1" property
if (username.equals(ERROR_1_NAME)) {
setErrorText("sampleauth-error-1");
return STATE_ERROR;
}

// Second errorstring is stored in "sampleauth-error-2" property
if (username.equals(ERROR_2_NAME)) {
setErrorText("sampleauth-error-2");
return STATE_ERROR;
}

if (username.equals(USERNAME) && password.equals("password")) {
return ISAuthConstants.LOGIN_SUCCEED;
}

throw new InvalidPasswordException("password is wrong", USERNAME);

case STATE_ERROR:
return STATE_ERROR;
default:
throw new AuthLoginException("invalid state");

}
}

@Override
public Principal getPrincipal() {
return new SampleAuthPrincipal(USERNAME);
}


private void setErrorText(String err) throws AuthLoginException
{
// Receive correct string from properties and substitute the
// header in callbacks order 3.
substituteHeader(STATE_ERROR, bundle.getString(err));
}

private void substituteUIStrings() throws AuthLoginException
{
// Get service specific attribute configured in OpenAM
String ssa = CollectionHelper.getMapAttr(options, "sampleauth-service-specific-attribute");

// Get property from bundle
String new_hdr = ssa + " " + bundle.getString("sampleauth-ui-login-header");
substituteHeader(STATE_AUTH, new_hdr);

Callback[] cbs_phone = getCallback(STATE_AUTH);

replaceCallback(STATE_AUTH, 0,
new NameCallback(bundle.getString("sampleauth-ui-username-prompt")));

replaceCallback(STATE_AUTH, 1,
new PasswordCallback(bundle.getString("sampleauth-ui-password-prompt"), false));
}

}
```

You will notice the code above allows the user "test" to log in with a password of "password". In order for this to work you will need to create a user called test in the OpenAM administration pages. This is because the code goes on to retrieve the user profile for the user, and if one doesn't exist, it will be this subsequent step that will fail and prevent you from logging in.

In the OpenAM console, logged in as amadmin, select "Access Control", Top Level Realm, "Subjects" and click "New…"

Here is the code for the principal implementation

``` java
package com.forgerock.openam.examples;

import java.io.Serializable;
import java.security.Principal;

/**
*
* @author Steve Ferris steve.ferris@forgerock.com
*/
public class SampleAuthPrincipal implements Principal, Serializable {
private String name;
private final static String CLASSNAME = "SampleAuthPrincipal";
private final static String COLON = " : ";

public SampleAuthPrincipal(String name) {
if (name == null) {
throw new NullPointerException("illegal null input");
}

this.name = name;
}

/**
* Return the LDAP username for this <code> SampleAuthPrincipal </code>.
*
* <p>
*
* @return the LDAP username for this <code> SampleAuthPrincipal </code>
*/
public String getName() {
return name;
}

/**
* Return a string representation of this <code> SampleAuthPrincipal </code>.
*
* <p>
*
* @return a string representation of this <code>TestAuthModulePrincipal</code>.
*/
@Override
public String toString() {
return new StringBuilder().append(CLASSNAME).append(COLON).append(name).toString();
}

/**
* Compares the specified Object with this <code> SampleAuthPrincipal </code>
* for equality. Returns true if the given object is also a
* <code> SampleAuthPrincipal </code> and the two SampleAuthPrincipal
* have the same username.
*
* <p>
*
* @param o Object to be compared for equality with this
* <code> SampleAuthPrincipal </code>.
*
* @return true if the specified Object is equal equal to this
* <code> SampleAuthPrincipal </code>.
*/
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}

if (this == o) {
return true;
}

if (!(o instanceof SampleAuthPrincipal)) {
return false;
}
SampleAuthPrincipal that = (SampleAuthPrincipal) o;

if (this.getName().equals(that.getName())) {
return true;
}
return false;
}

/**
* Return a hash code for this <code> SampleAuthPrincipal </code>.
*
* <p>
*
* @return a hash code for this <code> SampleAuthPrincipal </code>.
*/
@Override
public int hashCode() {
return name.hashCode();
}
}
```

### Service configuration XML

``` xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ServicesConfiguration
PUBLIC "=//iPlanet//Service Management Services (SMS) 1.0 DTD//EN"
"jar://com/sun/identity/sm/sms.dtd">

<ServicesConfiguration>
<Service name="iPlanetAMAuthSampleAuthService" version="1.0">
<Schema
serviceHierarchy="/DSAMEConfig/authentication/iPlanetAMAuthSampleAuthService"
i18nFileName="amAuthSampleAuth"
revisionNumber="10"
i18nKey="sampleauth-service-description"
resourceName="iPlanetAutSampleAuthService">
<Organization>
<AttributeSchema name="iplanet-am-auth-sampleauth-auth-level"
type="single"
syntax="number_range" rangeStart="0" rangeEnd="2147483647"
i18nKey="a500"
resourceName="iplanetamauthsampleautlevel">
<DefaultValues>
<Value>1</Value>
</DefaultValues>
</AttributeSchema>

<AttributeSchema name="sampleauth-service-specific-attribute"
type="single"
syntax="string"
validator="no"
i18nKey="a501"
resourceName="sampleauthservicespecattr">
<DefaultValues>
<Value></Value>
</DefaultValues>
</AttributeSchema>

<SubSchema name="serverconfig" inheritance="multiple" resourceName="USE-PARENT">
<AttributeSchema name="iplanet-am-auth-sampleauth-auth-level"
type="single"
syntax="number_range" rangeStart="0" rangeEnd="2147483647"
i18nKey="a500"
resourceName="iplanetamauthsampleautlevel">
<DefaultValues>
<Value>1</Value>
</DefaultValues>
</AttributeSchema>

<AttributeSchema name="sampleauth-service-specific-attribute"
type="single"
syntax="string"
validator="no"
i18nKey="a501"
resourceName="sampleauthservicespecattr">
<DefaultValues>
<Value></Value>
</DefaultValues>
</AttributeSchema>

</SubSchema>
</Organization>
</Schema>
</Service>
</ServicesConfiguration>
```

* The service must have a name: **'iPlanetAMAuth' + modulename + 'Service'**
* The service must have a description
* i18nFileName refers to the properties file and i18nKey to the key in the properties file
* sampleauth-service-specific-attribute configurable via OpenAM is defined here

The 'iplanet-am-auth-sampleauth-auth-level' is the obligatory authentication level attribute. Here naming is very important. The name of the attribute must be: 'iplanet-am-auth-' + lowercase(modulename) + '-auth-level'. If the attribute name does not follow the pattern your authentication module will not function the way you want it to. (There is also a second naming convention - please refer to the source code (wink) )

### Properties file

```
sampleauth-service-description=Sample Authentication Module
a500=Authentication Level
a501=Service Specific Attribute
sampleauth-ui-login-header=Login
sampleauth-ui-username-prompt=User Name:
sampleauth-ui-password-prompt=Password:
sampleauth-error-1=Error 1 occured during the authentication
sampleauth-error-2=Error 2 occured during the authentication
```

It's a simple properties file. Be careful to match all the identifier.

## Compile your custom authentication module

Next we need to compile the custom authentication module.

``` bash
$ javac -d ../classes/ -classpath lib/servlet-api.jar:lib/amserver.jar:lib/opensso-sharedlib.jar:lib/opensso.jar SampleAuth.java SampleAuthPrincipal.java
```
**[Configure your custom Authentication module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-configure-your-custom-authentication-module)**

This will create our class file that we need to install into OpenAM. Next we should package the classes files up into a jar file.
<a name="test-your-custom-module"></a>

``` bash
$ cd classes
$ jar cf ../sampleauth.jar .
```

## Install your custom authentication module

###Copy the jar file

We copy the jar file into the WEB-INF/lib directory within the openam web application deployed into Tomcat.

``` bash
$ cp sampleauth.jar $TOMCAT_HOME/webapps/openam/WEB-INF/lib/
```

### Copy the service properties file

We copy the properties file into the WEB-INF/classes directory within the openam web application deployed into Tomcat.

``` bash
$ cp amAuthSampleAuth.properties $TOMCAT_HOME/webapps/openam/WEB-INF/classes/
```

### Copy the authentication module XML file

We copy the properties file into the config/auth/default directory within the openam web application deployed into Tomcat.

``` bash
$ cp SampleAuth.xml $TOMCAT_HOME/webapps/openam/config/auth/default
```

### Register the module and the service with OpenAM

Use the [[ssoadm]] command to register the service and the module with OpenAM. The service can only be registered with OpenAM using ssoadm.

``` bash
$ ssoadm create-svc -u amadmin -f pwdfile -X /path/to/amAuthSampleAuth.xml
$ ssoadm register-auth-module -u amadmin -f pwdfile -a com.forgerock.openam.examples.SampleAuth
```
Note the service definition file is only needed for creating the service. When calling ssoadm create-svc, be sure to pass the full path to your service definition file.

Also following subcommands might be useful to you during the testing: [[delete-auth-cfgs]], [[delete-auth-instances]], [[delete-svc]], [[list-auth-cfgs]], [[list-auth-instances]], [[remove-svc-realm]], [[show-auth-modules]], [[show-realm-svcs]], [[unregister-auth-module]], [[update-svc]]

It is a good idea at this point to restart Tomcat (or whatever container you are using) to ensure the Authentication Module and service definition can be loaded.

## Configure your custom Authentication module

Log into the Console and navigate to Access Control >> Realm >> Authentication and click New under [[Authentication modules]]. Name your module and select the custom authentication module type from the list. Click OK. You should now see your custom module listed, you can select it and configure it as appropriate.

## Test your custom module

The final step is to test out your custom authentication module. To do this you just need to login successfully to the realm where the custom authentication module is configured. This URL should do the trick:

http://hostname.domainname/openam/UI/Login?module=auth_module_name

You should be presented with the login screen and asked for the credentials required by your custom authentication module.

**[Test your custom module](https://doc.openidentityplatform.org/openam/how-to/how-to-develop-a-custom-authentication-module#how-to-develop-a-custom-authentication-module-test-your-custom-module)**
Original file line number Diff line number Diff line change
@@ -1,521 +1,41 @@
## Introduction
This article has moved to the Open Identity Platform documentation site:

Large language model (LLM) agents can perform various tasks, from writing code or texts to booking airline tickets. Agents consist of a client that interacts with the user and a server that performs the required tasks. The interaction between the client, server, and LLM occurs via the Model Context Protocol [MCP](https://modelcontextprotocol.io/docs/getting-started/intro).
[How to Protect Model Context Protocol (MCP) Servers with OpenAM and OpenIG](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig).

MCP servers often have access to sensitive information, such as an internal source code repository or a customer database. Of course, not all users should have access to this data, even through an agent. To protect against unauthorized access, the Model Context Protocol specification describes the possibility of authorization based on OAuth 2.1: [https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization).
Please use the documentation site for the current version.

In this article, we will deploy a simple MCP server developed based on [Spring AI](https://spring.io/projects/spring-ai) and close it with the [OpenIG](https://github.com/OpenIdentityPlatform/OpenIG) authorization gateway. The [OpenAM](https://github.com/OpenIdentityPlatform/OpenAM) authentication service will be responsible for authentication.
<a name="introduction"></a>

We will use VS Code with the Copilot extension as the MCP client.
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-introduction)**

## Project description
<a name="project-description"></a>

The source code for the OpenAM, OpenIG, and MCP server configuration is available at: [https://github.com/OpenIdentityPlatform/openam-openig-mcp-example](https://github.com/OpenIdentityPlatform/openam-openig-mcp-example)
**[Project description](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-project-description)**

The project consists of three services described in the `docker-compose.yml` file.
<a name="preparing-for-launch"></a>

```yaml
services:
openig:
build:
context: ./openig-docker
dockerfile: Dockerfile
container_name: openig
volumes:
- ./openig-config:/usr/local/openig-config:ro
ports:
- "8081:8080"
environment:
CATALINA_OPTS: -Dopenig.base=/usr/local/openig-config -Dopenam=http://openam.example.org:8080/openam
networks:
openam_network:
aliases:
- openig.example.org

openam:
build:
context: ./openam-docker
dockerfile: Dockerfile
container_name: openam
restart: always
hostname: openam.example.org
ports:
- "8080:8080"
volumes:
- openam-data:/usr/openam/config
networks:
openam_network:
aliases:
- openam.example.org

time-mcp-server:
build:
context: ./timeserver
dockerfile: Dockerfile
container_name: time-mcp-server
ports:
- "8082:8080"
networks:
openam_network:
aliases:
- timeserver.example.org
networks:
openam_network:
driver: bridge
**[Preparing for launch](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-preparing-for-launch)**

volumes:
openam-data:
```
<a name="mcp-server"></a>

## Preparing for launch
**[MCP Server](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-mcp-server)**

For example, the host name for OpenAM will be `openam.example.org`, and for OpenIG it will be `openig.example.org`. Open the `hosts` file and add the host names and IP addresses to it, for example
<a name="configuring-openam"></a>

```
127.0.0.1 openam.example.org openig.example.org
```
**[Configuring OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-configuring-openam)**

On Windows systems, the hosts file is located in the `C:\Windows/System32/drivers/etc/hosts` directory, and on Linux or Mac OS in `/etc/hosts`.
<a name="configuring-oauth-2-in-openam"></a>

## MCP Server
**[Configuring OAuth 2 in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-configuring-oauth-2-in-openam)**

The MCP server has a method for returning the current time in ISO 8601 format.
<a name="configuring-openig"></a>

```java
@Service
public class TimeService {
**[Configuring OpenIG](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-configuring-openig)**

@Tool(name = "current_time_service", description = "Returns current time in ISO 8601 format")
public String getTime() {
return Instant.now().toString();
}
}
```
<a name="proxying-requests-to-the-mcp-server"></a>

For more details on creating an MCP server, please refer to the [documentation](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html) or in the Spring AI [blog](https://spring.io/blog/2025/09/16/spring-ai-mcp-intro-blog).
**[Proxying requests to the MCP server.](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-proxying-requests-to-the-mcp-server)**

Start the OpenAM, OpenIG, and MCP server Docker containers with the command:
<a name="conclusion"></a>

```bash
docker compose up --build
```

Check the availability of the running MCP server with the command:

```bash
curl -X POST --location "http://localhost:8082/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 0,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {}
}
}'

{
"id": 0,
"jsonrpc": "2.0",
"result": {
"capabilities": {
"completions": {},
"prompts": {
"listChanged": false
},
"resources": {
"listChanged": false,
"subscribe": false
},
"tools": {
"listChanged": false
}
},
"protocolVersion": "2025-03-26",
"serverInfo": {
"name": "time-server-mcp",
"version": "0.0.1"
}
}
}
```

Let's check the availability of tools in the MCP server:

```bash
curl -X POST --location "http://localhost:8082/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "current_time_service",
"description": "Returns current time in ISO 8601 format",
"inputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}
}
]
}
}
```

## Configuring OpenAM

OpenAM will be responsible for user authentication, issuing OAuth 2 `access_token` tokens, and validating them.

If you have not yet configured OpenAM, perform a quick setup by running the command:

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```

### Configuring OAuth 2 in OpenAM

Open the OpenAM console at [http://openam.example.org:8080/openam/console](http://openam.example.org:8080/openam/console). Enter the administrator login and password in the `User Name` and `Password` fields. In this case, they will be `amadmin` and `passw0rd`, respectively.

Select `Top Level Realm` from the Realm list.

![OpenAM Realms List](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/0-openam-realms-list.png)

Next, `Configure OAuth Provider`.

![OpenAM Configure OAuth Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/1-openam-configure-oauth-provider.png)

Then select `Configure OAuth 2.0`.

![OpenAM Configure OAuth 2.0](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/2-openam-configure-oauth2.png)

In the form that opens, you can leave the default settings unchanged. Click `Create`.

![OpenAM Configure OAuth 2.0 Step 2](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/3-openam-configure-oauth2-step-2.png)

In the Realm settings, select Services from the menu on the left and open the OAuth2 Provider settings.

![OpenAM Realm Services](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/4-openam-realm-services.png)

Add the value `profile` to the `Scopes` and `Default Clients Scopes` settings. This scope will allow you to obtain basic information about the user. Enable the `Issue Refresh Tokens` and `Issue Refresh Tokens on Refreshing Access Tokens` options. Also, allow dynamic client registration by enabling the `Allow Open Dynamic Client Registration` option. This will allow the MCP client (VS Code) to automatically register with OpenAM without requiring any additional action from the user.

For more information on configuring OpenAM, please refer to the [documentation](https://doc.openidentityplatform.org/openam/).

## Configuring OpenIG

OpenIG will be responsible for authorizing requests. It will check the validity of `access_token` issued by OpenAM and proxy requests to OpenAM and the MCP server.

Now let's check the OpenIG route configuration for proxying requests.

### Proxying requests to the MCP server.

The route will receive the `access_token` issued by OpenAM, passed in the `Authorization` header. If the `access_token` is valid, it will pass the request to the MCP server and return a response. If the `access_token` is invalid, OpenIG will return HTTP status 401.

`openig-config/config/routes/10-mcp.json`

```json
{
"name": "${matches(request.uri.path, '^/mcp')}",
"condition": "${matches(request.uri.path, '^/mcp')}",
"monitor": true,
"timer": true,
"handler": {
"type": "Chain",
"config": {
"filters": [
{
"type": "OAuth2ResourceServerFilter",
"config": {
"requireHttps": false,
"providerHandler": "ClientHandler",
"scopes": [
"profile"
],
"tokenInfoEndpoint": "${system['openam'].concat('/oauth2/tokeninfo')}"
}
},
{
"type": "ConditionEnforcementFilter",
"config": {
"condition": "${not empty contexts['oauth2']}",
"failureHandler": "RequireAuth"
}
}
],
"handler": "EndpointHandler"
}
},
"heap": [
{
"name": "RequireAuth",
"type": "StaticResponseHandler",
"config": {
"status": 401,
"headers": {
"WWW-Authenticate": [
"Bearer realm=\"OpenIG\""
]
},
"entity": "Authentication required"
}
},
{
"name": "EndpointHandler",
"type": "DispatchHandler",
"config": {
"bindings": [
{
"handler": "ClientHandler",
"baseURI": "http://time-mcp-server:8080/mcp"
}
]
}
}
]
}
```

The route consists of two filters. The first filter, `OAuth2ResourceServerFilter`, validates the `access_token` and, if successful, writes the data received from the `access_token` to the request context. The second filter, `ConditionEnforcementFilter`, checks the context and, if successful, forwards the request to the MCP server. Otherwise, it returns HTTP status 401.

Let's make an unauthorized request to the MCP server and verify that OpenIG requires authorization.

```bash
curl -v http://openig.example.org:8081/mcp
* Trying 127.0.0.1:8081...
* Connected to openig.example.org (127.0.0.1) port 8081 (#0)
> GET /mcp HTTP/1.1
> Host: openig.example.org:8081
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/1.1 401
< WWW-Authenticate: Bearer realm="OpenIG"
< Content-Length: 0
< Date: Mon, 22 Sep 2025 08:00:48 GMT

```
Proxying to `.well-known` endpoints
According to the MCP specification, the client obtains data about the authorization server from endpoints located at the URL `<MCP server host>/.well-known/*`. The endpoints are located on OpenAM at the URL `<OpenAM host>/openam/.well-known`. The route for forwarding HTTP requests to MCP on OpenAM is as follows:
`openig-config/config/routes/20-well-known.json`
```json
{
"name": "${matches(request.uri.path, '^/.well-known/.*}",
"condition": "${matches(request.uri.path, '^/.well-known/.*')}",
"monitor": true,
"timer": true,
"handler": {
"type": "Chain",
"config": {
"filters": [
{
"type": "HeaderFilter",
"config": {
"messageType": "REQUEST",
"add": {
"Host": [
"${matchingGroups(system['openam'],\"(http|https):\/\/(.[^\/]*)\")[2]}"
]
},
"remove": [
"Host",
"Origin"
]
}
}
],
"handler": "EndpointHandler"
}
},
"heap": [
{
"name": "EndpointHandler",
"type": "DispatchHandler",
"config": {
"bindings": [
{
"expression": "${matches(request.uri.path, '^/.well-known/openid-configuration$')}",
"handler": "ClientHandler",
"baseURI": "${system['openam'].concat('/oauth2/.well-known/openid-configuration')}"
}
]
}
}
]
}
```
The `HeaderFilter` filter adds the OpenAM Host HTTP header specified in the `openam` system parameter in the `docker-compose.yaml` file, and the `EndpointHandler` handler forwards the request to the `/openam/.well-known/openid-configuration` endpoint deployed in the `openam` Docker container.
Let's check the endpoint operation:
```bash
curl -v http://openig.example.org:8081/.well-known/openid-configuration
{
"acr_values_supported" : [],
"authorization_endpoint" : "http://openam.example.org:8080/openam/oauth2/authorize",
"check_session_iframe" : "http://openam.example.org:8080/openam/oauth2/connect/checkSession",
"claims_parameter_supported" : false,
"claims_supported" : [],
"device_authorization_endpoint" : "http://openam.example.org:8080/openam/oauth2/device/code",
"end_session_endpoint" : "http://openam.example.org:8080/openam/oauth2/connect/endSession",
"id_token_encryption_alg_values_supported" : [
"RSA-OAEP",
"RSA-OAEP-256",
"A128KW",
"RSA1_5",
"A256KW",
"dir",
"A192KW"
],
"id_token_encryption_enc_values_supported" : [
"A256GCM",
"A192GCM",
"A128GCM",
"A128CBC-HS256",
"A192CBC-HS384",
"A256CBC-HS512"
],
"id_token_signing_alg_values_supported" : [
"ES384",
"HS256",
"HS512",
"ES256",
"RS256",
"HS384",
"ES512"
],
"issuer" : "http://openam.example.org:8080/openam/oauth2",
"jwks_uri" : "http://openam.example.org:8080/openam/oauth2/connect/jwk_uri",
"registration_endpoint" : "http://openam.example.org:8080/openam/oauth2/connect/register",
"response_types_supported" : [
"code",
"code token",
"token"
],
"scopes_supported" : [],
"subject_types_supported" : [
"public"
],
"token_endpoint" : "http://openam.example.org:8080/openam/oauth2/access_token",
"token_endpoint_auth_methods_supported" : [
"client_secret_post",
"private_key_jwt",
"none",
"client_secret_basic"
],
"userinfo_endpoint" : "http://openam.example.org:8080/openam/oauth2/userinfo",
"version" : "3.0"
}
```
For more details on configuring OpenIG, please refer to the documentation.
Configuring VS Code to work with the MCP server
You must have the extensions for working with Copilot, GitHub Copilot, and GitHub Copilot Chat installed and configured. Instructions on how to do this are available at: [https://code.visualstudio.com/docs/copilot/setup](https://code.visualstudio.com/docs/copilot/setup).
Add the MCP server to VS Code.
For example, to add MCP to your workspace, create a file named `mcp.json` in the `.vscode` directory of your workspace:
`mcp.json`:
```json
{
"servers": {
"time-mcp-server": {
"type": "http",
"url": "http://openig.example.org:8081/mcp"
}
}
}
```
Other ways to add an MCP server are described at: [https://code.visualstudio.com/docs/copilot/customization/mcp-servers#_add-an-mcp-server](https://code.visualstudio.com/docs/copilot/customization/mcp-servers#_add-an-mcp-server)
In the VS Code extensions list, click on the settings for the added MCP server and select `Start Server` from the menu that appears.
![VS Code Start MCP Server](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/5-vscode-mcp-start-server.png)
Allow the MCP server to authenticate on the OpenIG host
![VS Code MCP Authenticate](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/6-vscode-mcp-authenticate.png)
A browser window with authentication will open.
![OpenAM Login](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/7-openam-login.png)
Enter the login and password for the test user: `demo` and `changeit`, respectively
Confirm access to data for the Visual Studio Code application. If you want to disable the data access confirmation dialog, enable `Allow clients to skip consent` in the OAuth2 Provider settings in OpenAM.
![OpenAM OAuth2 Consent](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/8-openam-oauth2-consent.png)
After confirming, you will be redirected back to VS Code.
Open the chat with GitHub Copilot. To do this, select **Show and Run Commands** from the command menu:
![OpenAM Run Commands](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/9-openam-run-commands.png)
Then select **Chat: New Chat**:
![OpenAM New Chat](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/10-copilot-new-chat.png)
In the chat window that opens, enter the question: `What is the current time?` . Copilot will respond that it does not have access to the current time:
![OpenAM Time Request](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/11-copolot-time-request.png)
Now switch the chat to Agent mode at the bottom and ask the question again:
![Copilot Set the Agent Mode](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/12-copulot-set-agent-mode.png)
Allow access to the function for obtaining the current time in the MCP server:
![Copilot Allow MCP Call](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/13-copilot-allow-mcp-call.png)
Copilot will receive information about the current time from the MCP server and return the correct response.
![Copilot Successful response](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-mcp/14-copilot-successful-response.png)
## Conclusion
In this article, we demonstrated the practical integration of OpenAM and OpenIG to provide secure access to the MCP server based on OAuth 2.1. OpenAM acts as a reliable authentication and authorization center, issuing and validating tokens, while OpenIG filters requests, blocking unauthorized access and proxying traffic to protected resources. This approach minimizes the risk of sensitive data leaks - from internal repositories to customer databases.
Download the source code from GitHub, test the configuration, and integrate it into your projects. For in-depth study, refer to the official documentation: [OpenAM](https://doc.openidentityplatform.org/openam/) and [OpenIG](https://doc.openidentityplatform.org/openig/).
**[Conclusion](https://doc.openidentityplatform.org/openam/how-to/how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig#how-to-protect-model-context-protocol-mcp-servers-with-openam-and-openig-conclusion)**
79 changes: 15 additions & 64 deletions How-to-Setup-2FA-with-Google-Authenticator-in-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,78 +1,29 @@
- [Introduction](#introduction)
- [OpenAM Setup](#openam-setup)
* [Setup Authentication Module](#setup-authentication-module)
* [Setup Authentication Chain](#setup-authentication-chain)
* [Setup User Accounts](#setup-user-accounts)
- [Test Solution](#test-solution)
This article has moved to the Open Identity Platform documentation site:

# Introduction
Google Authenticator is one of the most commonly used applications for two-factor authentication (2FA). It runs both on Android and iOS devices. In the following article, we will describe how to set up 2FA in OpenAM with Google Authenticator.
[How to Setup 2FA with Google Authenticator in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam).

# OpenAM Setup
## Setup Authentication Module
For example, we have realm `staff` where we want to set up 2FA with Google Authenticator. Login into admin console as `amadmin` user, go to realm `staff`, and create new `OATH` module `google-authenticator` with the following settings:
Please use the documentation site for the current version.

![New Google Authenticator Module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/google-authenticator/new-google-authenticator-module.png)
<a name="introduction"></a>

![Google Authenticator Module Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/google-authenticator/google-authenticator-module-settings.png)
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam#how-to-setup-2fa-with-google-authenticator-in-openam-introduction)**

There are some important settings:
* **One Time Password Length**: Should be 6 as in Google Authenticator by default
* **Secret Key Attribute Name**: User attribute in where a secret key is stored.
* **OATH Algorithm to Use**: For Google Authenticator should be [TOTP](https://tools.ietf.org/html/rfc6238)
* **Last Login Time Attribute**: User attribute, where users last login time in UNIX format is stored.
<a name="openam-setup"></a>

* **Maximum Allowed Clock Drift**: Should be greater than TOTP time steps, so in the following example it is 3.
**[OpenAM Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam#how-to-setup-2fa-with-google-authenticator-in-openam-openam-setup)**

## Setup Authentication Chain
By default, there is `ldapService` authentication chain, which uses only `DataStore` authentication module. Add `google-authenticator` module in the chain.
<a name="setup-authentication-module"></a>

![Authentication Chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/google-authenticator/authentication-chain.png)
**[Setup Authentication Module](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam#how-to-setup-2fa-with-google-authenticator-in-openam-setup-authentication-module)**

## Setup User Accounts
The next part would be a little bit tricky. To authenticate in Google Authenticator we need to set up user accounts first. Then generate for each user account shared secret. As an example, we will take `test` account and for this account shared secret will be `s3cr3tw0rd`.
<a name="setup-authentication-chain"></a>

Encode into Base16. You can or use online service [https://simplycalc.com/base16-encode.php](https://simplycalc.com/base16-encode.php) either use the following Java function:
**[Setup Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam#how-to-setup-2fa-with-google-authenticator-in-openam-setup-authentication-chain)**

```java
private String toBase16(String str) {
return String.format("%x", new BigInteger(1, str.getBytes(Charset.defaultCharset())));
}
```
Base16 encoded value is `73336372337477307264`.
<a name="setup-user-accounts"></a>

Open User account properties in Apache Directory Studio (or any other LDAP client application) and add `sunIdentityServerPPEncryptKey` value `73336372337477307264` as shown on the picture below.
**[Setup User Accounts](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam#how-to-setup-2fa-with-google-authenticator-in-openam-setup-user-accounts)**

![Apache DS User Properties](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/google-authenticator/apache-ds-user-properties.png)

Then generate a QR code to register the user in the Google Authenticator application. QR for Google Authenticator is URI in the following format `otpauth://totp/<account id>@<issuer>?secret=<base32 encoded secret>&issuer=<Issuer Name>`

Encode secret as Base32. You can use or online service [https://simplycalc.com/base32-encode.php](https://simplycalc.com/base32-encode.php), ether following Java function:

```java
import org.apache.commons.codec.binary.Base32;

private String toBase32(String str) {
return new Base32().encodeAsString(str.getBytes());
}
```
Base32 encoded value is `OMZWG4RTOR3TA4TE`

The final URI will be:
`otpauth://totp/test@openam.openidentityplatform.org?secret=OMZWG4RTOR3TA4TE&issuer=Open+Identity+Platform`

Let's use the online service [https://www.the-qrcode-generator.com](https://www.the-qrcode-generator.com) to generate a QR code image:

![Google Authenticator QR Code](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/google-authenticator/qr-code.png)

Scan QR in Google Authenticator application. A new account will be added.

# Test Solution
Let’s sign in into realm `staff` с with `test` account:
![Auth Staff Login Password](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/google-authenticator/auth-staff-login-password.png)
You will be prompted for OTP from Google Authenticator.

![Auth Staff OTP 2FA](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/google-authenticator/login-staff-otp.png)

Enter the code from Google Authenticator, and you will be successfully authenticated.
<a name="test-solution"></a>

**[Test Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-2fa-with-google-authenticator-in-openam#how-to-setup-2fa-with-google-authenticator-in-openam-test-solution)**
Original file line number Diff line number Diff line change
@@ -1,186 +1,37 @@
# Introduction
This article has moved to the Open Identity Platform documentation site:

Almost every organization uses [Active Directory](https://ru.wikipedia.org/wiki/Active_Directory) to manage employee accounts. And using existing accounts to access corporate applications is a recommendend practice. In this article, we will configure authentication in the [demo Spring Boot application](https://github.com/OpenIdentityPlatform/spring-security-openam-example) via an Active Directory server in [OpenAM](https://github.com/OpenIdentityPlatform/OpenAM).
[How to Setup Active Directory Authentication in a Spring Boot Application](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application).

Please use the documentation site for the current version.

## OpenAM Configuration
<a name="introduction"></a>

## Install OpenAM
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-introduction)**

Let OpenAM hostname is `openam.example.org`, and the Spring Boot application hostname is `app.example.org`.
<a name="openam-configuration"></a>

If you already have OpenAM installed, you can skip this step. The easiest way to deploy OpenAM is in a Docker container. Before starting, add the hostname and IP address to the `hosts` file, for example `127.0.0.0.1 app.example.org openam.example.org` .
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-openam-configuration)**

On Windows systems, the `hosts` file is located at `C:Windows/System32/drivers/etc/hosts` , on Linux and Mac it is located at `/etc/hosts` .
<a name="install-openam"></a>

Create a network in Docker for OpenAM
**[Install OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-install-openam)**

```bash
docker network create openam
```
<a name="authentication-module-configuration"></a>

Next, start the Docker container OpenAM Execute the following command:
**[Authentication Module Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-authentication-module-configuration)**

```bash
docker run -h openam.example.org -p 8080:8080 --network openam --name openam openidentityplatform/openam
```
<a name="authentication-chain-configuration"></a>

Once the server is up and running, run the initial OpenAM configuration. Run the following command:
**[Authentication Chain Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-authentication-chain-configuration)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
<a name="configure-realm"></a>

After successful configuration you can proceed to further steps.
**[Configure realm](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-configure-realm)**

Note the `COOKIE_DOMAIN` parameter - the authentication session cookie must be set to a common top-level domain for OpenAM and the application.
<a name="spring-boot-application-setup"></a>

**[Spring Boot Application Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-spring-boot-application-setup)**

## Authentication Module Configuration
<a name="test-solution"></a>

Go to the OpenAM administrator console at

http://openam.example.org:8080/openam/XUI/#login/

In the login field enter the value `amadmin`, in the password field enter the value from the `ADMIN_PWD` parameter of the setup command, in this case `passw0rd`.

Select the root realm and select Authentication → Modules from the menu. Create a new Active Directory authentication module.

![OpenAM new Active Directory Module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-ad-springboot/0-openam-new-ad-module.png)

Set the module settings according to the table

| Setting | Description |
| --- | --- |
| Primary Active Directory Server | AD host and port number, for example: ad.example.org:389 |
| Users Domain | | Active Directory domain for user authentication, for example, example.org. You need to fill this property so that users do not enter a name like user@example.org | to authenticate.
| Bind User DN | Leave blank. If empty, binding authentication is used and you do not need to specify Bind user password, User Search Filter, and DN to Start User Search. | Bind user password.

You can leave other settings unchanged.

## Authentication Chain Configuration

Go to the admin console, select the root realm and select Authentication → Chains from the menu. Create an `activeDirectory` authentication chain with the recently created `activeDirectory` module.

![OpenAM Active Directory Authentication Chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-ad-springboot/1-openam-ad-auth-chain.png)

## Configure realm

Go to Authentication → Chains for realm and on the User Profile tab, set the `User Profile` setting to `Ignore`.

![OpenAM Realm User Profile Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-ad-springboot/2-openam-realm-auth-settings.png)

So, you can authenticate to Active Directory without setting up Active Directory as a User Data Store in OpenAM.

# Spring Boot Application Setup

The recommended way is to integrate through Spring Security.

The application uses a filter that can be attached to a Spring REST or a Web Controller.

The filter receives a Cookie with the authentication session ID set by OpenAM on successful authentication from the HttpServletRequest. Then the filter calls the OpenAM API to retrieve the user from the session. If the cookie does not exist or the session retrieved from the cookie is not valid, the user is redirected to authentication.

An example filter is in the listing below:

```java
@Component
public class OpenAmAuthFilter implements Filter {

final static String OPENAM_URI = "http://openam.example.org:8080/openam";

final static String OPENAM_COOKIE_NAME = "iPlanetDirectoryPro";

final static String REDIRECT_URI_TEMPLATE = OPENAM_URI.concat("/XUI#login/&service=activeDirectory&goto=");

private final String OPENAM_USER_INFO_URI = OPENAM_URI.concat("/json/users?_action=idFromSession");

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

//reading OpenAM session cookie
Optional<Cookie> openamCookie = Optional.empty();
if(request.getCookies() != null) {
openamCookie = Arrays.stream(request.getCookies())
.filter(c -> c.getName().equals(OPENAM_COOKIE_NAME)).findFirst();
}
String redirectUri = request.getRequestURL().toString();
if(openamCookie.isEmpty()) {
response.sendRedirect(REDIRECT_URI_TEMPLATE + URLEncoder.encode(redirectUri, StandardCharsets.UTF_8));
} else {
//retrieve userID from by session cookie value from OpenAM
String userId = getUserIdFromSession(openamCookie.get().getValue());
if (userId == null) {
response.sendRedirect(REDIRECT_URI_TEMPLATE + URLEncoder.encode(redirectUri, StandardCharsets.UTF_8));
return;
}
request.setAttribute("openam.userId", userId);
filterChain.doFilter(servletRequest, servletResponse);
}
}

private String getUserIdFromSession(String sessionId) {
RestTemplate restTemplate = new RestTemplate();
ParameterizedTypeReference<Map<String, String>> responseType = new ParameterizedTypeReference<>() {};
HttpHeaders headers = new HttpHeaders();
headers.add(OPENAM_COOKIE_NAME, sessionId);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<?> entity = new HttpEntity<>(headers);
ResponseEntity<Map<String, String>> response
= restTemplate.exchange(OPENAM_USER_INFO_URI, HttpMethod.POST, entity, responseType);
Map<String, String> body = response.getBody();
if (body == null) {
return null;
}
return body.get("id");
}
}
```

# Test Solution

Let's run a demo Spring Boot application in a Docker container

```bash
docker run -h app.example.org -p 8081:8081 --network openam --name spring-security-openam-example openidentityplatform/spring-security-openam-example
```

Exit the console and open the demo application link in your browser. http://app.example.org:8081/ Click the `OpenAM Cookie` link.

![Example Spring Boot Application](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-ad-springboot/3-example-spring-boot-application.png)

The filter will not find a valid session and will redirect to OpenAM authentication. Enter the user's credentials from Active Directory.

![OpenAM Authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-ad-springboot/4-openam-authentication.png)

After successful authentication, the user will be redirected back to the application. The `openam.userId` attribute of the HttpServletRequest object will be set to the user ID from Active Directory.

![Seccuessful Authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-ad-springboot/5-successful-auth.png)

**Further reading**

- [OpenAM and Spring Boot 3 Integration via OIDC OAuth2 Protocol](https://github.com/OpenIdentityPlatform/OpenAM/wiki/OpenAM-and-Spring-Boot-3-Integration-via-OIDC-OAuth2-Protocol)
- [OpenAM and Spring Boot 3 Integration via SAMLv2 Protocol](https://github.com/OpenIdentityPlatform/OpenAM/wiki/OpenAM-and-Spring-Boot-3-Integration-via-SAMLv2-Protocol)
- [OpenAM and Spring Boot 3 Integration via OpenAM Cookie](https://github.com/OpenIdentityPlatform/OpenAM/wiki/OpenAM-and-Spring-Boot-3-Integration-via-OpenAM-Cookie)
- [How to Add Authorization and Protect Your Application With OpenAM and OpenIG Stack](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-Add-Authorization-and-Protect-Your-Application-With-OpenAM-and-OpenIG-Stack)
**[Test Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-active-directory-authentication-in-a-spring-boot-application#how-to-setup-active-directory-authentication-in-a-spring-boot-application-test-solution)**
212 changes: 27 additions & 185 deletions How-to-Setup-OAuth2-OIDC-Federation-in-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,211 +1,53 @@
# Introduction

In the following manual, we will set up a federation between two OpenAM instances via OAuth2/OIDC protocol. One OpenAM instance we will set up as OAuth2/OIDC Server - Identity Provider (IdP), and another instance OAuth2/OIDC client - Service Provider (SP).Thus, you can authenticate to an OpenAM client instance (SP) using OpenAM instance credentials (IdP) using the OAuth2/OIDC protocol.

# OpenAM Instances Installation
This article has moved to the Open Identity Platform documentation site:

If you already have OpenAM instances installed, you can skip this section.
For demonstration purposes, we will install OpenAM IdP and SP in Docker containers.
[How to Setup OAuth2 OIDC Federation in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam).

## Network Setup
Please use the documentation site for the current version.

Add hostnames and IP adress to the `hosts` file.
<a name="introduction"></a>

```bash
127.0.0.1 idp.acme.org sp.mycompany.org
```
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-introduction)**

In Windows `hosts` file located at `C:\Windows\System32\drivers\etc\hosts` directory. Un Linux and Mac the file location is `/etc/hosts`
<a name="openam-instances-installation"></a>

Create a Docker network for OpenAM instances
**[OpenAM Instances Installation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-openam-instances-installation)**

```bash
docker network create openam-oauth
```
<a name="network-setup"></a>

## OpenAM IdP Installation
**[Network Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-network-setup)**

Run OpenAM Docker Container
<a name="openam-idp-installation"></a>

```bash
docker run -h idp.acme.org -p 8080:8080 --network openam-oauth --name openam-idp openidentityplatform/openam
```
**[OpenAM IdP Installation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-openam-idp-installation)**

Once the OpenAM server is running, perform the initial configuration by running the following command and wait for the configuration to complete.
<a name="openam-sp-installation"></a>

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam-idp bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://idp.acme.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=idp.acme.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=idp.acme.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
**[OpenAM SP Installation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-openam-sp-installation)**

## OpenAM SP Installation
<a name="oauth2oidc-server-setup"></a>

Run OpenAM Docker Container
**[OAuth2/OIDC Server Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-oauth2oidc-server-setup)**

```bash
docker run -h sp.mycompany.org -p 8081:8080 --network openam-oauth --name openam-sp openidentityplatform/openam
```
<a name="create-a-client-application"></a>

Once the OpenAM server is running, perform the initial configuration by running the following command and wait for the configuration to complete.
**[Create a Client Application](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-create-a-client-application)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam-sp bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://sp.mycompany.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=sp.mycompany.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=sp.mycompany.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
<a name="oauth2oidc-client-setup"></a>

# OAuth2/OIDC Server Setup
**[OAuth2/OIDC Client Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-oauth2oidc-client-setup)**

Open the OpenAM console, which will be in the role of the OAuth2/OIDC server at [http://idp.acme.org:8080/openam](http://idp.acme.org:8080/openam). In the login field enter the `amadmin` value. In the password field enter the value from `ADMIN_PWD` option, in this case `passw0rd`.
<a name="create-oauth2oidc-authentication-module"></a>

Go to the root realm and in the Dashboard select `Configure OAuth Provider`.
**[Create OAuth2/OIDC Authentication Module](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-create-oauth2oidc-authentication-module)**

![OpenAM realm overview](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/0-openam-idp-realm-overview.png)
<a name="setup-oauth2oidc-authentication-chain"></a>

Next, `Configure OpenID Connect`.
**[Setup OAuth2/OIDC Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-setup-oauth2oidc-authentication-chain)**

![OpenAM Configure OpenID Connect](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/1-openam-configure-openid-connect.png)
<a name="realm-setup"></a>

Leave the settings unchanged and click the `Create` button.
**[Realm Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-realm-setup)**

![OpenAM OpenID Connect Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/2-openam-openidconnect-settings.png)
<a name="test-the-solution"></a>

## Create a Client Application

Open the OAuth2/OIDC server admin console, navigate to the desired realm and select `Applications` → `OAuth 2.0` from the left menu

![OpenAM create OAuth2 Client](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/3-openam-applications-oauth2.png)

In the list, click the `New` button.

![OpenAM OAuth2 OIDC client list](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/4-oauth2-oidc-client-list.png)

Fill the `Name` (client_id) and `Password` (client_secret) fields. Repeat the password and press the `Create` button.

![OpenAM new OAuth2 client](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/5-oauth2-new-client.png)

Open the created application and fill the settings.
|Setting|Value|
| --- | --- |
| Redirection URIs | http://sp.mycompany.org:8081/openam/oauth2c/OAuthProxy.jsp |
| Scope | openid |
| Token Endpoint Authentication Method | client_secret_post |
| ID Token Signing Algorithm | RS256 |

# OAuth2/OIDC Client Setup

## Create OAuth2/OIDC Authentication Module

Open the console of OpenAM, which will be in the role of OAuth2/OIDC client at [http://openam-sp.example.org:8081/openam](http://openam-sp.example.org:8081/openam). In the login field enter the value `amadmin`, in the password field enter the value specified in the `ADMIN_PWD` setting, in this case `passw0rd`.

Open the realm and select `Authentication` → `Modules` from the left menu. Click the `Add Module` button.

![Untitled](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/6-openam-authenticaion-modules.png)

Select the module type `OAuth2/OpenID Connect`, the module name can be anything, the path will be `oauth`.

![OpenAM new module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/7-openam-new-module.png)

Press the `Create` button.

In the list, open the settings of the created module and fill in the settings:

| Setting | Value |
| --- | --- |
| Client Id | test_client |
| Client Secret | Password specified when registering the application |
| Authentication Endpoint URL | http://idp.acme.org:8080/openam/oauth2/authorize |
| Access Token Endpoint URL | http://idp.acme.org:8080/openam/oauth2/access_token |
| User Profile Service URL | http://idp.acme.org:8080/openam/oauth2/tokeninfo |
| Scope | openid |
| OAuth2 Access Token Profile Service Parameter name | access_token |
| Proxy URL | http://sp.mycompany.org:8081/openam/oauth2c/OAuthProxy.jsp |
| Account Mapper | org.forgerock.openam.authentication.modules.oidc.JwtAttributeMapper |
| Account Mapper Configuration | sub=uid |
| Attribute Mapper | org.forgerock.openam.authentication.modules.oidc.JwtAttributeMapper |
| Attribute Mapper Configuration | sub=uid |
| Create account if it does not exist | disabled |
| Prompt for password setting and activation code | disabled |
| Map to anonymous user | disabled |
| OpenID Connect validation configuration type | .well-known/openid-configuration_url |
| OpenID Connect validation configuration value | http://idp.acme.org:8080/openam/oauth2/.well-known/openid-configuration |
| Name of OpenID Connect ID Token Issuer | http://idp.acme.org:8080/openam/oauth2 |

## Setup OAuth2/OIDC Authentication Chain

Open the OpenAM Service Provider administrator console. Select the realm and in the left menu go to `Authentication` → `Chains`.

![OpenAM Authenticaion Chains](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/8-openam-authentication-chains.png)

Create a new authentication chain

![OpenAM new authenticaion chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/9-openam-new-auth-chain.png)

Click the `Add a Module` button and add the `oauth` module. Set the Criteria to `Requisite`. Click `OK` and then `Save Changes`.

![Untitled](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/10-openam-auth-chain-settings.png)

## Realm Setup

Go to the OpenAM SP administrator console. In the left menu, go to `Authentication` → `Settings`. On the `User Profile` tab, select `Ignore`. Save the changes.

![OpenAM realm user profile settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/11-openam-realm-user-profile-settings.png)

# Test the Solution

Go to the OpenAM OAuth2/OIDC Server admin console, select realm, under Dashboard in the left menu select `Subjects`.

This will open a list of users. Create a new `testIdp` account

![OpenAM create new user](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/12-openam-create-new-user.png)

Log out of the OpenAM OAuth2/OIDC Server administration console and the OpenAM OAuth2/OIDC Client administration console or open a browser in incognito mode.

Open the OAuth2/OIDC Client authentication URL of the `oauth` chain [http://sp.mycompany.org:8081/openam/XUI/?service=oauth](http://sp.mycompany.org:8081/openam/XUI/?service=oauth)

You will be redirected to authenticate to the OAuth2/OIDC Server. Enter the users testIdP credentials.

Confirm consent to access the `test_client` application user data

![OpenAM User Consent](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/13-openam-user-access-consent.png)

After accepting the consent, you well be redirected to OpenAM OAuth2/OIDC Client console with the OpenAM OAuth2/OIDC Server user credentials.

![OpenAM Authenticated](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-oauth/14-openam-authenticated.png)
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-oauth2-oidc-federation-in-openam#how-to-setup-oauth2-oidc-federation-in-openam-test-the-solution)**
196 changes: 31 additions & 165 deletions How-to-Setup-SAMLv2-Federation-in-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,195 +1,61 @@
# Introduction

In the following manual, we will set up a federation between two OpenAM instances. One instance will act as an Identity Provider (IdP), and another as a Service Provider (SP). Therefore, you will be able to authenticate in OpenAM SP with OpenAM IdP credentials.

# OpenAM Instances Installation
This article has moved to the Open Identity Platform documentation site:

If you already have OpenAM instances installed, you can skip this section.
For demonstration purposes, we will install OpenAM IdP and SP in Docker containers.
[How to Setup SAMLv2 Federation in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam).

## Network Setup
Please use the documentation site for the current version.

Add hostnames and IP adress to the `hosts` file.
<a name="introduction"></a>

```bash
127.0.0.1 idp.acme.org sp.mycompany.org
```
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-introduction)**

In Windows `hosts` file located at `C:\Windows\System32\drivers\etc\hosts` directory. Un Linux and Mac the file location is `/etc/hosts`
<a name="openam-instances-installation"></a>

Create a Docker network for OpenAM instances
**[OpenAM Instances Installation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-openam-instances-installation)**

```bash
docker network create openam-saml
```
<a name="network-setup"></a>

## OpenAM IdP Installation
**[Network Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-network-setup)**

Run OpenAM Docker Container
<a name="openam-idp-installation"></a>

```bash
docker run -h idp.acme.org -p 8080:8080 --network openam-saml --name openam-idp openidentityplatform/openam
```
**[OpenAM IdP Installation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-openam-idp-installation)**

Once the OpenAM server is running, perform the initial configuration by running the following command and wait for the configuration to complete.
<a name="openam-sp-installation"></a>

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam-idp bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://idp.acme.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=idp.acme.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=idp.acme.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
**[OpenAM SP Installation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-openam-sp-installation)**

## OpenAM SP Installation
<a name="identity-provider-и-service-provider-configuration"></a>

Run OpenAM Docker Container
**[Identity Provider и Service Provider Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-identity-provider-и-service-provider-configuration)**

```bash
docker run -h sp.mycompany.org -p 8081:8080 --network openam-saml --name openam-sp openidentityplatform/openam
```
<a name="hosted-identity-provider-configuration"></a>

Once the OpenAM server is running, perform the initial configuration by running the following command and wait for the configuration to complete.
**[Hosted Identity Provider Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-hosted-identity-provider-configuration)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam-sp bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://sp.mycompany.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=sp.mycompany.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=sp.mycompany.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
<a name="hosted-service-provider-configuration"></a>

# Identity Provider и Service Provider Configuration
**[Hosted Service Provider Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-hosted-service-provider-configuration)**

## Hosted Identity Provider Configuration
<a name="remote-identity-provider-setup"></a>

Open the OpenAM Identity provider administartion console at [http://idp.acme.org:8080/openam](http://idp.acme.org:8080/openam). In the login field enter the `amadmin` value. In the password field enter the value from `ADMIN_PWD` option, in this case `passw0rd`.
**[Remote Identity Provider Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-remote-identity-provider-setup)**

Go to the root realm and in the Dashboard select `Configure SAMLv2 Provider`.
<a name="user-mapping-configuration"></a>

![OpenAM realm overview](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/0-openam-idp-realm-overview.png)
**[User Mapping Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-user-mapping-configuration)**

Then `Create Hosted Identity Provider`
<a name="configure-realm-for-service-provider"></a>

![OpenAM Create Hosted Identity Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/1-openam-create-hosted-idp.png)
**[Configure Realm for Service Provider](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-configure-realm-for-service-provider)**

In the `Signing Key` setting for the demonstration purposes select the `test` value, then enter any `Circle of Trust` value. Then add `uid` in the `Attribute Mapping` setting.
<a name="remote-service-provider-setup"></a>

![Hosted identity provider settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/2-openam-hosted-idp-settings.png)
**[Remote Service Provider Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-remote-service-provider-setup)**

Press the `Configure` button. Next, OpenAM will prompt you to configure the Remote Service Provider. Since we do not have it configured yet, click the `Finish` button
<a name="test-account-creation"></a>

## Hosted Service Provider Configuration
**[Test Account Creation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-test-account-creation)**

Open the OpenAM Service Provider administarion console at [http://sp.mycompany.org:8081/openam](http://sp.mycompany.org:8081/openam). In the login field enter the `amadmin` value. In the password field enter the value from `ADMIN_PWD` option, in this case `passw0rd`.
Go to the root realm and in the Dashboard select `Configure SAMLv2 Provider`. Next `Create Hosted Service Provider`.
<a name="test-the-solution"></a>

![OpenAM create hosted service provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/3-openam-create-hosted-sp.png)

Enter the circle of trust name, you can leave the other settings unchanged.

![OpenAM hosted service provider settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/4-openam-hosted-sp-settings.png)

Press the `Configure` button.

![Create remote identity provider promts](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/4-remote-idp-prompt.png)

You will be prompted to configure the remote identity provider. Since we have already configured the Identity Provider in the previous step, you can click `Yes`. This will open the remote identity provider configuration window.

## Remote Identity Provider Setup

Select the identity provider metadata location - URL. Enter the identity provider metadata URL in the field.

[http://idp.acme.org:8080/openam/saml2/jsp/exportmetadata.jsp](http://idp.acme.org:8080/openam/saml2/jsp/exportmetadata.jsp)

![OpenAM remote identity provider settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/6-openam-idp-settings.png)

Click the `Configure` button.

## User Mapping Configuration

Open the OpenAM SP admin console. In the Dashboard in the left menu go to `Applications` → `SAML 2.0`

![OpenAM goto saml](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/7-openam-sp-goto-saml.png)

This will open the SAML federation configuration window. Navigate to `Entity Providers` → [`http://sp.mycompany.org:8081/openam`](http://sp.mycompany.org:8081/openam)

![OpenAM SP circle of trust configuration](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/8-openam-sp-circle-of-trunt.png)

Next, click the `Assertions Processing` tab. Enable automatic federation by the `uid` attribute.

![Untitled](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/9-openam-sp-auto-federation.png)

Press the `Save` button.

## Configure Realm for Service Provider

Go to the OpenAM SP administrator console. In the left menu, go to `Authentication` → `Settings` . On the `User Profile` tab, select `Ignore` . Save the changes.

![OpenAM realm user profile settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/10-openam-realm-user-profile.png)

## Remote Service Provider Setup

Go to OpenAM IdP administration console at [`http://openam-idp.example.org:8080/openam`](http://openam-idp.example.org:8080/openam). Open the root realm and in the Dashboard select `Configure SAMLv2 Provider`, then `Configure Remote Service Provider`.

![OpenAM configure remote service provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/11-openam-configure-remote-sp.png)

Add the service provider metadata URL [http://sp.mycompany.org:8080/openam/saml2/jsp/exportmetadata.jsp](http://openam-sp.example.org:8080/openam/saml2/jsp/exportmetadata.jsp). Note that the OpenAM Service Provider port is `8080` since the OpenAM instances are on the same network OpenAM IdP connects to the SP container on port `8080`.

![OpenAM remote service provider settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/12-openam-remote-sp-settings.png)

Click the `Configure` button. A message indicating that the remote service provider has been successfully created will be displayed.

# Test Account Creation

Go to the OpenAM IdP admin console, select realm, in the Dashboard in the left hand menu select `Subjects`.

A list of users will open. Create a new `testIdp` account

![OpenAM new account creation](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/13-openam-new-account.png)

# Test the Solution

Log out of both OpenAM consoles and open the Service Provider authentication initialization link in your browser. [http://sp.mycompany.org:8081/openam/spssoinit?metaAlias=/sp&idpEntityID=http%3A//idp.acme.org%3A8080/openam&RelayState=http%3A//sp.mycompany.org%3A8081/openam](http://sp.mycompany.org:8081/openam/spssoinit?metaAlias=/sp&idpEntityID=http%3A//idp.acme.org%3A8080/openam&RelayState=http%3A//sp.mycompany.org%3A8081/openam)

As an alternative, you can use the Identity Provider authentication initalization link [http://idp.acme.org:8080/openam/idpssoinit?metaAlias=/idp&spEntityID=http%3A//sp.mycompany.org%3A8081/openam&RelayState=http%3A//sp.mycompany.org%3A8081/openam](http://idp.acme.org:8080/openam/idpssoinit?metaAlias=/idp&spEntityID=http%3A//sp.mycompany.org%3A8081/openam&RelayState=http%3A//sp.mycompany.org%3A8081/openam)

You will be redirected to the Identity Provider authentication. Enter the credentials for the user `testIdP`.

![OpenAM sign in](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/14-openam-sign-in.png)

After successful authentication, the SP console with the authenticated user `testIdP` will be opened

![OpenAM authenticated](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-saml/15-openam-authenticated.png)
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-samlv2-federation-in-openam#how-to-setup-samlv2-federation-in-openam-test-the-solution)**
66 changes: 23 additions & 43 deletions How-to-Setup-Two-Factor-Authentication-in-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,45 @@
# Introduction
This article has moved to the Open Identity Platform documentation site:

In the following article, we will set up OpenAM authentication with a Time-Based One-Time Password (TOTP, [RFC 6238](https://tools.ietf.org/html/rfc6238)).
[How to Setup Two Factor Authentication in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam).

# OpenAM Setup
Please use the documentation site for the current version.

## OpenAM Installation
<a name="introduction"></a>

If you have not already had OpenAM installed, you can do it as described [here](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP:-Quick-OpenAM-Docker-Configuration-From-a-Command-Line).
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-introduction)**

## Authentication Module Setup
<a name="openam-setup"></a>

Open the OpenAM administration console using the link [http://openam.example.org:8080/openam/console](http://openam.example.org:8080/openam/console). In the login field enter the `amadmin` value, in the password field enter the value from the `ADMIN_PWD` parameter of the setup command, in this case, `passw0rd`.
**[OpenAM Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-openam-setup)**

Open the root realm, in the left menu, select Authentication → Modules, and press the `Add Module` button. In the form enter the name of the module, for example, `totp` and choose the module type `Authenticator (OATH)`. Press the `Create` button.
<a name="openam-installation"></a>

![OpenAM new module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-2fa/0-openam-new-module.png)
**[OpenAM Installation](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-openam-installation)**

Set the `OATH Algorithm to Use` setting to `TOTP`, set the `Name of the Issuer` field to any non-empty value, for example, `OpenAM` and click the `Save Changes` button.
<a name="authentication-module-setup"></a>

![OATH module settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-2fa/1-oath-module-settings.png)
**[Authentication Module Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-authentication-module-setup)**

## Device Registration Authentication Chain Setup
<a name="device-registration-authentication-chain-setup"></a>

In the administration console in the realm settings in the left menu select Authentication → Chains and in the chain list press the `Add Chain` button.
Enter the authentication chain name `totp-register` and press the `Create` button. In the chain settings press the `Add a Module` button and add the `totp` authentication module as shown in the picture below. Press the `OK` button and next `Save Changes`.
**[Device Registration Authentication Chain Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-device-registration-authentication-chain-setup)**

![Devide registration chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-2fa/2-device-registration-chain.pngg)
<a name="login-authentication-chain-setup"></a>

**[Login Authentication Chain Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-login-authentication-chain-setup)**

## Login Authentication Chain Setup
<a name="test-the-solution"></a>

**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-test-the-solution)**

In the administration console in the realm settings in the left menu select Authentication → Chains and in the chain list press the `Add Chain` button.
Enter the authentication chain name `totp-login` and press the `Create` button. Add the login and password `DataStore` authentication module. Next, add the one-time password `totp` authentication module. Press the `Save Changes` button.
<a name="setting-up-a-test-user"></a>

![2FA login chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-2fa/3-2fa-login-chain.png)
**[Setting Up a Test User](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-setting-up-a-test-user)**

# Test the Solution
<a name="device-registration"></a>

Download on your mobile device Microsoft Authenticator or Google Authenticator application.
**[Device Registration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-device-registration)**

## Setting Up a Test User
In the OpenAM admin console, navigate to the root realm and select `Subjects` from the left menu. Set the password for the `demo` user. To do this, select it in the list of users, and click the `Edit` link under Password. Enter and save the new password. Next, log out of the administrator console.

## Device Registration

Log in to the console with the `demo` user account. To do this, log out of the administrator console or open a browser in Incognito mode. Go to the URL [http://openam.example.org:8080/openam/XUI/#login/](http://openam.example.org:8080/openam/XUI/#login/) and log in to OpenAM with the `demo` user credentials. After successful authentication, open the registration chain link in the browser [http://openam.example.org:8080/openam/XUI/#login&service=totp-register](http://openam.example.org:8080/openam/XUI/#login&service=totp-register).

Press the `Register Device` button. There will be a QR code in the browser. Open the authenticator application on your mobile device and tap the add account button. Scan the QR code from the browser. A `demo` user account for OpenAM will be added to the authenticator mobile app.

![QR device registration](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-2fa/4-qr-device-registration.png)

Next, click the `Login Using Verification Code` button in the browser. Enter the code from the mobile app and click `Submit`.

![Enter TOTP form](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-2fa/5-enter-totp.png)

The application has been registered.

## One-Time Password Authentication

Log out of the OpenAM console or open your browser in Incognito mode. Open the [http://openam.example.org:8080/openam/XUI/#login&service=totp-login](http://openam.example.org:8080/openam/XUI/#login&service=totp-login) link in the browser.

Enter the username and password for the user `demo`. After entering the username and password, OpenAM will prompt for a one-time password from the mobile app. Open the mobile app, select the `demo` user account, enter the one-time password from the mobile app in the browser, and press the `Submit` button. After entering the correct one-time password, authentication will be completed successfully.
<a name="one-time-password-authentication"></a>

**[One-Time Password Authentication](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-two-factor-authentication-in-openam#how-to-setup-two-factor-authentication-in-openam-one-time-password-authentication)**
137 changes: 31 additions & 106 deletions How-to-Setup-WebAuthn-Authentication-in-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,136 +1,61 @@
# How to Setup WebAuthn Authentication in OpenAM
This article has moved to the Open Identity Platform documentation site:

# Introduction
[How to Setup WebAuthn Authentication in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam).

[WebAuthn](https://en.wikipedia.org/wiki/WebAuthn) is a
[W3C](https://www.w3.org/) and [FIDO](https://fidoalliance.org/) standard
that describes Web public key authentication.
For authentication, a client can use Hardware USB, Bluetooth, or NFC tokens,
or mobile or laptop biometric authentication, such as fingerprint or FaceID.
Please use the documentation site for the current version.

In short, WebAuthn uses mutual authentication, utilizing an asymmetric encryption algorithm and exchange of credential messages encrypted with public keys (passkeys). Therefore, WebAuthn is resistant to phishing.
<a name="how-to-setup-webauthn-authentication-in-openam"></a>

More details about the standard can be found at [https://www.w3.org/TR/webauthn-3/](https://www.w3.org/TR/webauthn-3/)
**[How to Setup WebAuthn Authentication in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam)**

## Browsers Support
<a name="introduction"></a>

WebAuthn is supported by most modern browsers, including Google Chrome, Mozilla Firefox (with partial support), Apple Safari, and Microsoft Edge, including their mobile versions. For up-to-date information about browsers and devices supporting WebAuthn, visit [https://caniuse.com/?search=webauthn](https://caniuse.com/?search=webauthn).
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-introduction)**

## Devices Support
<a name="browsers-support"></a>

Passkeys created on iPhone, iPad, or Mac can be used on the same device or another iPhone, iPad, or Mac with the same Apple ID. The passkeys are synchronized automatically.
**[Browsers Support](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-browsers-support)**

Passkeys created on Android devices can be used on an Android device with the same Google account. The passkeys are synchronized automatically
<a name="devices-support"></a>

More details at the link [https://passkeys.dev/device-support/](https://passkeys.dev/device-support/)
**[Devices Support](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-devices-support)**

<a name="openam-setup"></a>

# OpenAM Setup
Since WebAuthn in a browser only works over HTTPS or on the localhost domain, for demonstration purposes we will deploy OpenAM in a Docker container on localhost.
**[OpenAM Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-openam-setup)**

Create a network in Docker for OpenAM
<a name="webauthn-registration-setup"></a>

```bash
docker network create openam
```
**[WebAuthn Registration Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-webauthn-registration-setup)**

Then run the OpenAM Docker container with the following command
<a name="authentication-module-setup"></a>

```bash
docker run -p 8080:8080 --network openam --name openam openidentityplatform/openam
```
**[Authentication Module Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-authentication-module-setup)**

Once the OpenAM server is running, perform the initial configuration by running the following command and wait for the configuration to complete.
<a name="authentication-chain-setup"></a>

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://localhost:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=localhost
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=localhost
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
After successful configuration, you can proceed to further configuration. Let's configure the WebAuthn registration and authentication chains.
**[Authentication Chain Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-authentication-chain-setup)**

<a name="webauthn-authentication-setup"></a>

## WebAuthn Registration Setup
**[WebAuthn Authentication Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-webauthn-authentication-setup)**

### Authentication Module Setup
<a name="authentication-module-setup-1"></a>

Open the OpenAM administration console at [http://localhost:8080/openam/XUI/#login/](http://localhost:8080/openam/XUI/#login/)
In the login field enter the `amadmin` value, in the password field enter the value from the `ADMIN_PWD` parameter of the setup command, in this case, `passw0rd`.
Select the root realm and then goto Authentication → Modules in the left menu. Create a new authentication module `WebAuthn Registration`
**[Authentication Module Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-authentication-module-setup-1)**

![OpenAM Create WebAuthn Registration Authentication Module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/0-webauthn-registration-new-module.png)
<a name="authentication-chain-setup-1"></a>

The default module settings can be left unchanged.
**[Authentication Chain Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-authentication-chain-setup-1)**

![OpenAM WebAuthn Registration Authentication Module Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/1-webauthn-registration-module.png)
<a name="test-the-solution"></a>

### Authentication Chain Setup
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-test-the-solution)**

Go to the admin console, select the root realm and select Authentication → Chains from the menu. Create a `webauthn-registration` authentication chain with the created `webauthn-registration` module.
![OpenAM WebAuthn Registration Authentication Chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/2-webauthn-registration-chain.png)
<a name="registration"></a>

## WebAuthn Authentication Setup
**[Registration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-registration)**

### Authentication Module Setup
<a name="authentication"></a>

Open the OpenAM administration console. Select the root realm and then goto Authentication → Modules in the left menu. Create a new authentication module `WebAuthn Authentication`

![OpenAM Create WebAuthn Authentication Module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/3-webauthn-authentication-new-module.png)

The default module settings can be left unchanged.

![OpenAM WebAuthn Authentication Module Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/4-webauthn-authentication-module.png)


### Authentication Chain Setup
Go to the admin console, select the root realm and select Authentication → Chains from the menu. Create a `webauthn-authentication` authentication chain with the created `webauthn-authentication` module.

![OpenAM WebAuthn Authentication Chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/5-webauthn-authentication-chain.png)

# Test the Solution

Log out of the OpenAM admin console or open a browser in Incognito mode and log in at http://localhost:8080/openam/XUI/#login with the user credentials `demo`. In the login field enter `demo` in the password field enter `changeit`.

## Registration

For demonstration purposes, we will use the WebAuthn emulator built into the browser. How to enable it is described at [https://developer.chrome.com/docs/devtools/webauthn](https://developer.chrome.com/docs/devtools/webauthn).

Add a virtual authenticator with Supports resident keys and Supports user verification settings enabled.

![WebAuthn New Chrome Authenticator](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/6-webauthn-chrome-new-authenticator.png)

Open the registration authentication chain at [http://localhost:8080/openam/XUI/#login&service=webauthn-registration](http://localhost:8080/openam/XUI/#login&service=webauthn-registration) and click the `Register` button.

![WebAuthn New Chrome Authenticator](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/7-webauthn-registration.png)

You will be immediately redirected back to the console with the `demo` account, and in the developer tools for the authenticator you will see the registered credentials for the demo user.

![WebAuthn Chrome Authenticator Credentials](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/8-webauthn-authenticator-credentials.png)

## Authentication
In the Console under the user `demo` click on the user icon and select Logout
![OpenAM Logout](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/9-openam-demo-logout.png)

Go to [http://localhost:8080/openam/XUI/#login&service=webauthn-authentication](http://localhost:8080/openam/XUI/#login&service=webauthn-authentication) and click the `Log In` button. An account selection window will pop up.

![Authenticator Account Selection](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/webauthn/10-account-selection.png)

Select the `demo` account and click Continue. You will be authenticated with the `demo` account .
**[Authentication](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-webauthn-authentication-in-openam#how-to-setup-webauthn-authentication-in-openam-authentication)**
120 changes: 15 additions & 105 deletions How-to-Start-OpenAM-and-OpenDJ-in-Separate-Docker-Contaners.md
Original file line number Diff line number Diff line change
@@ -1,119 +1,29 @@
## Requeirements
This article has moved to the Open Identity Platform documentation site:

To reproduce steps in the following article, Docker and Docker Compose should be installed.
[How to Start OpenAM and OpenDJ in Separate Docker Containers](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers).

The sample configuration used in the following article could be found [here](https://github.com/maximthomas/openidentityplatform-docker)
Please use the documentation site for the current version.

## OpenAM Perparation
<a name="requeirements"></a>

Create `docker-compose.yml` file and add OpenAM service:
**[Requeirements](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers#how-to-start-openam-and-opendj-in-separate-docker-containers-requeirements)**

```yml
version: '3.9'
<a name="openam-perparation"></a>

services:
openam:
image: openidentityplatform/openam:latest
ports:
- "8080:8080"
hostname: openam.example.com
volumes:
- ./persistence/openam:/usr/openam/config
```
Add OpenAM FQDN to your `hosts` file on your machine, for example
**[OpenAM Perparation](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers#how-to-start-openam-and-opendj-in-separate-docker-containers-openam-perparation)**

```
127.0.0.1 auth.example.com
```
<a name="opendj-preparation"></a>

**[OpenDJ Preparation](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers#how-to-start-openam-and-opendj-in-separate-docker-containers-opendj-preparation)**

In the `persistence/openam` folder OpenAM will store its configuration data
<a name="start-and-configuration"></a>

# OpenDJ Preparation
**[Start and Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers#how-to-start-openam-and-opendj-in-separate-docker-containers-start-and-configuration)**

Add OpenDJ service to `docker-compose.yml` file:
<a name="start-services"></a>

```yml
opendj:
image: openidentityplatform/opendj:latest
hostname: opendj.example.com
ports:
- "1389:1389"
- "1636:1636"
- "4444:4444"
volumes:
- ./opendj/bootstrap/data/:/opt/opendj/bootstrap/data #initial data
- ./opendj/bootstrap/schema/:/opt/opendj/bootstrap/schema #schema
- ./persistence/opendj:/opt/opendj/data #opendj data
environment:
- BASE_DN=dc=openam,dc=openidentityplatform,dc=org #should be yours base DN
```
**[Start Services](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers#how-to-start-openam-and-opendj-in-separate-docker-containers-start-services)**

`opendj/boststrap` directory should exist on the host machine and contain two subfolders: `data` - for initial data и `schema` - schema files.
<a name="openam-configuration"></a>

The files could be found [here](https://github.com/maximthomas/openidentityplatform-docker/tree/master/opendj/bootstrap)

If base DN id different from `dc=openam,dc=openidentityplatform,dc=org` it should be changed in `opendj/boststrap/data/samlple.ldif` file as well

## Start and Configuration

### Start Services

Start OpenAM and OpenDJ with the following command:

```bash
docker-compose up
```

You shoudl see the following lines in the logs:
```
openidentityplatform-docker-openam-1 | 15-Jun-2022 10:09:46.063 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
openidentityplatform-docker-openam-1 | 15-Jun-2022 10:09:46.133 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [36437] milliseconds
openidentityplatform-docker-opendj-1 | OpenDJ is started
```

### OpenAM Configuration

After OpenAM and OpenDJ are started, open OpenAM URL in the browser, for example [http://auth.example.com:8080/openam](http://auth.example.com:8080/openam)

OpenAM configuration window should appear:
![OpenAM Configuration Start](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-opendj-docker/openam-conf-start.png)

Select Custom Configuration and press Create New Configuration. Read and accept the license agreement.

Enter and confirm amAdmin password, then press the Next button.

![OpenAM Configuration 1 General](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-opendj-docker/openam-conf1-general.png)

Leave server settings unchanged and press the Next button.

![OpenAM Configuration 2 Server Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-opendj-docker/openam-conf2-server-settings.png)

On the Configuration Data Store Settings step set the following settings:

* **Configuration Data Store** radiobutton to **OpenDJ**,
* Set **Host Name** to **opendj**, as OpenDJ Docker internal hostname
* Set **Port** to 1389 as specified for OpenDJ Docker container
* Set OpenDJ password as specified for OpenDJ Docker container as well (`password` by default).

If you changed base DN for OpenDJ, set the required Root Suffix as well.

Then press the Next button.

![OpenAM Configuration 3 Data Store Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-opendj-docker/openam-conf3-datastore.png)

On the User datastore settings set OpenDJ password as it has been set in the previous step and press the Next button.

![OpenAM Configuration 5 User Data Store Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-opendj-docker/openam-conf4-userdatastore.png)

If this instance is behind a load balancer, set the site configuration settings. If it's not, just press the Next button.

On the Step 6: Default Policy Agent User, enter and confirm default policy agent password and press the Next button.

Review configuration summary and press the Create Configuration button.

![OpenAM Configuration Summary](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-opendj-docker/openam-conf-summary.png)

If everything is ok, proceed to login page.

If you have any additional questions, [feel free to ask us](https://github.com/OpenIdentityPlatform/OpenAM/discussions)!
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-start-openam-and-opendj-in-separate-docker-containers#how-to-start-openam-and-opendj-in-separate-docker-containers-openam-configuration)**
120 changes: 27 additions & 93 deletions How-to-Use-Apache-Cassandra-as-User-and-Session-DataStore-in-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,119 +1,53 @@
# How to Use Apache Cassandra as User and Session DataStore in OpenAM
This article has moved to the Open Identity Platform documentation site:

## Introduction
One of the performance bottlenecks of authentication is User DataStore. This becomes noticeable when the total number of user accounts exceeds `4 000 000`.
[How to Use Apache Cassandra as User and Session DataStore in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam).

To maintain acceptable performance, the most obvious solution is to scale User DataStore horizontally or vertically. But with an increasing amount of data, DataStore scaling does not affect performance.
Please use the documentation site for the current version.

With the increasing load on the authentication system, the most obvious solution is to scale horizontally or vertically the number of user repository nodes.
<a name="how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam"></a>

Another alternative solution is to use storage specifically designed for working with large amounts of data. One of such storages is [Apache Cassandra](https://cassandra.apache.org/). It has proved itself as a high-availability and high-performance datastore.
**[How to Use Apache Cassandra as User and Session DataStore in OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam)**

# Prepare Apache Cassandra
<a name="introduction"></a>

Allow materialized views for Cassandra 4+ (in version 3 enabled by default) in conf/cassandra.yaml:
```yaml
# Enables materialized view creation on this node.
# Materialized views are considered experimental and are not recommended for production use.
enable_materialized_views: true
```
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-introduction)**

## Prepare Apache Cassandra to use as User DataStore
<a name="prepare-apache-cassandra"></a>

Сreate the corresponding Keyspaces and tables, for each OpenAM realm, from template [import.cql](https://raw.githubusercontent.com/OpenIdentityPlatform/OpenAM/master/openam-cassandra/openam-cassandra-datastore/src/test/resources/cassandra/import.cql)
```bash
bin/cqlsh -f import.cql
```
## Prepare Apache Cassandra to use as CTS
**[Prepare Apache Cassandra](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-prepare-apache-cassandra)**

Сreate the corresponding Keyspaces and tables, for OpenAM CTS, from template [schema.cqlsh](https://raw.githubusercontent.com/OpenIdentityPlatform/OpenAM/master/openam-cassandra/openam-cassandra-cts/src/test/resources/schema.cqlsh)
```bash
bin/cqlsh -f schema.cqlsh
```
<a name="prepare-apache-cassandra-to-use-as-user-datastore"></a>

**[Prepare Apache Cassandra to use as User DataStore](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-prepare-apache-cassandra-to-use-as-user-datastore)**

# OpenAM Setup
<a name="prepare-apache-cassandra-to-use-as-cts"></a>

Add cassandra contact-points info in bin/setenv.sh and restart OpenAM:
```bash
export CATALINA_OPTS=" ... \
-Ddatastax-java-driver.basic.contact-points.0=ip1:9042 \
-Ddatastax-java-driver.basic.contact-points.1=ip2:9042 \
-Ddatastax-java-driver.basic.load-balancing-policy.local-datacenter=datacenter1 \
-Ddatastax-java-driver.advanced.auth-provider.class=PlainTextAuthProvider \
-Ddatastax-java-driver.advanced.auth-provider.username=user \
-Ddatastax-java-driver.advanced.auth-provider.password=password \
"
```
**[Prepare Apache Cassandra to use as CTS](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-prepare-apache-cassandra-to-use-as-cts)**

## OpenAM create DataStore
<a name="openam-setup"></a>

Open OpenAM administration console, goto `Realms` select target realm, then goto `DataStores` and create new DataStore.
**[OpenAM Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-openam-setup)**

![OpenAM Create Cassandra DataStore](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/cassandra/create-datastore.png)
<a name="openam-create-datastore"></a>

Then setup following settings:
**[OpenAM create DataStore](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-openam-create-datastore)**

### Server settings
<a name="server-settings"></a>

|Setting|Value|
|-------|---------------------------------------------------|
|Servers|don't use (leave blank)|
|User name|don't use (leave blank)|
|Password| don't use (leave blank)|
|Password (confirm)| don't use (leave blank)|
|Keyspace| Cassandra keyspace for this realm `realm_name`|
**[Server settings](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-server-settings)**

### Plugin configuration
<a name="plugin-configuration"></a>

|Setting|Value|
|-------|---------------------------------------------------|
|Database Repository Plugin Class Name| `org.openidentityplatform.openam.cassandra.Repo` |
|Tables|`group=group`<br>`user=user`<br>`realm=realm`|
|Operations| `realm=read,create,edit,delete,service`<br>` group=read,create,edit,delete`<br> `user=read,create,edit,delete,service`|
**[Plugin configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-plugin-configuration)**

### User Configuration
<a name="user-configuration"></a>

|Setting|Value|
|-------|---------------------------------------------------|
|TTL|`realm:attr1=86400`<br>` user:attr2=86400` <br> `group:attr3=86400`|
|Attribute Name of User Status|inetuserstatus|
|User Status Active Value|Active|
**[User Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-user-configuration)**

### Group Configuration
|Setting|Value|
|-------|---------------------------------------------------|
|Attribute Name for Group Membership|memberOf|
<a name="group-configuration"></a>

Click the `Save` button
**[Group Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-group-configuration)**

You can check datastore. Goto `Subjects -> Users` and create a new user account. For example:
<a name="openam-cts-setup"></a>

![OpenAM Create Cassandra User Account](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/cassandra/create-user.png)

Click `Save` and make sure, the record exists in Cassandra:

```
cassandra@cqlsh:realm_name> SELECT * FROM realm_name.values ;
```

## OpenAM CTS Setup

Add cassandra external CTS settings in bin/setenv.sh:
```bash
export CATALINA_OPTS=" ... \
-Dorg.forgerock.openam.sm.datalayer.module.CTS_ASYNC=org.openidentityplatform.openam.cassandra.CTSAsyncConnectionModule \
-Dorg.forgerock.openam.sm.datalayer.module.CTS_MAX_SESSION_TIMEOUT_WORKER=org.openidentityplatform.openam.cassandra.CTSConnectionModule \
-Dorg.forgerock.openam.sm.datalayer.module.CTS_SESSION_IDLE_TIMEOUT_WORKER=org.openidentityplatform.openam.cassandra.CTSConnectionModule \
-Dorg.forgerock.openam.sm.datalayer.module.CTS_EXPIRY_DATE_WORKER=org.openidentityplatform.openam.cassandra.CTSConnectionModule \
-Dorg.forgerock.services.cts.store.root.suffix=cts.tokens \
"
```

restart OpenAM, login and check session info in Cassandra

```
cassandra@cqlsh:cts> SELECT * FROM cts.tokens ;
```
**[OpenAM CTS Setup](https://doc.openidentityplatform.org/openam/how-to/how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam#how-to-use-apache-cassandra-as-user-and-session-datastore-in-openam-openam-cts-setup)**
46 changes: 20 additions & 26 deletions How-to-disable-XUI-by-default.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
This article has moved to the Open Identity Platform documentation site:

# Legacy UI
## For one instance in cluster
[How to disable XUI by default](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default).

Goto [[Configuration]] > [[Servers and Sites]] > [[Default Server Settings]] > [[Advanced]] and add:
Please use the documentation site for the current version.

```
XUI.enable=false
```
<a name="legacy-ui"></a>

or change java system property:
**[Legacy UI](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default#how-to-disable-xui-by-default-legacy-ui)**

``` bash
-DXUI.enable=false
```
<a name="for-one-instance-in-cluster"></a>

## For all instances in cluster
**[For one instance in cluster](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default#how-to-disable-xui-by-default-for-one-instance-in-cluster)**

Goto [[Configuration]] > [[Servers and Sites]] > Select server > [[Advanced]] and add:
<a name="for-all-instances-in-cluster"></a>

```
XUI.enable=false
```
**[For all instances in cluster](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default#how-to-disable-xui-by-default-for-all-instances-in-cluster)**

# XUI Interface
## For one instance in cluster
Goto [[Deployment]] > [[Servers]] > Choose server > [[Advanced]] and add:
```
XUI.enable=false
```
## For all instances in cluster
Goto [[Configure]] > [[Server Defaults]] > [[Advanced]] and add:
```
XUI.enable=false
```
<a name="xui-interface"></a>

**[XUI Interface](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default#how-to-disable-xui-by-default-xui-interface)**

<a name="for-one-instance-in-cluster-1"></a>

**[For one instance in cluster](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default#how-to-disable-xui-by-default-for-one-instance-in-cluster-1)**

<a name="for-all-instances-in-cluster-1"></a>

**[For all instances in cluster](https://doc.openidentityplatform.org/openam/how-to/how-to-disable-xui-by-default#how-to-disable-xui-by-default-for-all-instances-in-cluster-1)**
6 changes: 5 additions & 1 deletion How-to-make-OpenAM-log-more-verbose.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
To make OpenAM log more verbose please add **-Dcom.iplanet.services.debug.level=message** to Tomcat's **setenv.sh** file. Hope this will help to figure out the cause of the problem
This article has moved to the Open Identity Platform documentation site:

[How to make OpenAM log more verbose](https://doc.openidentityplatform.org/openam/how-to/how-to-make-openam-log-more-verbose).

Please use the documentation site for the current version.
69 changes: 19 additions & 50 deletions How-to-setup-Kerberos-Authentication-with-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,37 @@
# Introduction
There are several ways how enterprise users can authenticate in enterprise applications. If there are many enterprise applications users should authenticate into each application and enter login and password. Even if applications use the same user account, it is painful to enter credentials every time. A solution is to use a single sign (SSO) technology. For Windows users it is Kerberos. With Kerberos, users could authenticate to web applications seamlessly using their Active Directory accounts.
This article has moved to the Open Identity Platform documentation site:

# Prerequisites
You have Windows Server and user accounts stored in the Active directory. You must also have OpenAM installed. Here is how to [quickly install OpenAM](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP:-Quick-OpenAM-Docker-Configuration-From-a-Command-Line).
[How to setup Kerberos Authentication with OpenAM](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam).

# Windows setup
Create an account for Kerberos authentication in the Active Directory. When creating an account, set checkboxes `User cannot change password` и `Password never expires enabled` as shown in the picture below.
Please use the documentation site for the current version.

![Kerberos Account Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/kerberos/kerberos-account.png)
<a name="introduction"></a>

In user account properties in the Account tab in Account Options enable the checkbox `This account supports Kerberos AES-256 bit encryption`.
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-introduction)**

On the domain controller create a keytab file openamKerberos.keytab in a current directory. To do this, execute the following command in the Windows terminal:
<a name="prerequisites"></a>

```PowerShell
ktpass -out openamKerberos.keytab -princ HTTP/openam.example.com@AD.EXAMPLE.COM -pass +rndPass -maxPass 256 -mapuser openamKerberos -crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL
```
**[Prerequisites](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-prerequisites)**

In this command in `-princ` parameter openam.example.com - is your OpenAM hostname and EXAMPLE.COM - your Active Directory domain name should be uppercase.
<a name="windows-setup"></a>

Copy openamKerberos.keytab file to a directory, where OpenAM can read the file.
**[Windows setup](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-windows-setup)**

On your firewall open network access from OpenAM to TCP/UDP ad.example.com:88
<a name="openam-configuration"></a>

Check keytab file on OpenAM machine:
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-openam-configuration)**

```bash
$ klist -k -t openamKerberos.keytab
Keytab name: FILE:openamKerberos.keytab
KVNO Timestamp Principal
---- ------------------- ------------------------------------------------------
0 01.01.1970 03:00:00 HTTP/openam.example.com@AD.EXAMPLE.COM
```
<a name="setup-authentication-module"></a>

# OpenAM Configuration
**[Setup Authentication Module](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-setup-authentication-module)**

## Setup Authentication Module
Go to the OpenAM administrator console at
http://openam.example.org:8080/openam/XUI/#login/
In the login field enter the value `amadmin`, in the password field enter the value from the `ADMIN_PWD` parameter of the setup command, in this case, `passw0rd`.
<a name="setup-authentication-chain"></a>

Select the root realm and select Authentication → Modules from the menu. Create a new Active Directory authentication module.
**[Setup Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-setup-authentication-chain)**

Edit the created `sso` authentication module settings.
<a name="realm-configuration"></a>

Set `Service Principal`, as in `ktpass` command. `Keytab File Name` should be `openamKerberos.keytab` file location on the OpenAM server. Set `Kerberos Realm`, `Kerberos Server Name`, and `Trusted Kerberos realms` according to your environment.
**[Realm Configuration](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-realm-configuration)**

![SSO Kerberos New Authentication Module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/kerberos/1-kerberos-module.png)

## Setup Authentication Chain
Go to the admin console, select the root realm, and select Authentication → Chains from the menu. Create an `sso` authentication chain with the recently created `sso` module.

![SSO Kerberos Authentication Chain Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/kerberos/2-kerberos-chain.png)

## Realm Configuration

Go to Authentication → Chains for realm and on the User Profile tab, set the `User Profile` setting to `Ignore`.

![OpenAM Realm User Profile Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/kerberos/3-openam-realm-auth-settings.png)

So, you can authenticate with Kerberos without setting up Active Directory as a User Data Store in OpenAM.

# Test Solution
On a Windows machine, authenticate with your Active Directory account and go to [http://openam.example.com:8080/openam/XUI/#login/&realm=/&service=sso](http://openam.example.com:8080/openam/XUI/#login/&realm=/&service=sso)

You should be seamlessly authenticated with an Active Directory account without prompting credentials.
<a name="test-solution"></a>

**[Test Solution](https://doc.openidentityplatform.org/openam/how-to/how-to-setup-kerberos-authentication-with-openam#how-to-setup-kerberos-authentication-with-openam-test-solution)**
51 changes: 17 additions & 34 deletions Login-and-Password-Authentication.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,33 @@
- [Introduction](#introduction)
- [Implementation](#implementation)
- [Pros and Cons](#pros-and-cons)
- [Conclusion](#conclusion)
This article has moved to the Open Identity Platform documentation site:

## Introduction
[Login and Password Authentication](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication).

The following article is intended for newbies, who want to develop authentication for their services. In the article, we will look at the most common authentication method - login and password authentication, its implementation, advantages, and disadvantages.
Please use the documentation site for the current version.

**Authentication** is an identity verification process. For software, authentication is used for verifying the identities of users or client applications. The most common way to authenticate users is login and password authentication.
<a name="introduction"></a>

User login could be public but the password should be only in the user's memory (and not on a piece of paper under the keyboard or taped to the monitor!) and used for verification than login belongs to the only user who knows the password.
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication#login-and-password-authentication-introduction)**

## Implementation
<a name="implementation"></a>

User identity data usually stored in a user database. And the only authentication system should have access to the database to minimize the risk of credentials leak.
**[Implementation](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication#login-and-password-authentication-implementation)**

Login in user database stored in plaintext to quick search for the user account. Password should be stored as its hash and never in plaintext. During authentication, the hash of the password entered by the user is calculated, compared with the value stored in the database and, if the values match, authentication is successful.
<a name="password-hashing"></a>

### Password Hashing
**[Password Hashing](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication#login-and-password-authentication-password-hashing)**

To store a password in a database relatively secure, not the password itself is stored in the database, but password hash. The hash is calculated by the formula: `password_hash = hash(password)`. To slow-down dictionary password attack, it is necessary to add so-called **salt** to password. **Salt** - is a random value, stored within the password hash. And password hash is calculated with function from password itself and hash `password_hash = hash(password, salt)`. More information about salt in Wikipedia: [Salt_(cryptography)](https://en.wikipedia.org/wiki/Salt_(cryptography)).
<a name="database-authentication"></a>

### Database Authentication
**[Database Authentication](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication#login-and-password-authentication-database-authentication)**

Some databases support internal authentication. In this case, the database itself is responsible for login and password authentication. Authentication service sends authentication request with login and password to the database, and the database returns authentication result: whether it is successful or not. For example, such an approach uses Microsoft Active Directory.
<a name="implementation-tips"></a>

### Implementation Tips
**[Implementation Tips](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication#login-and-password-authentication-implementation-tips)**

- If authentication was failed, do not tell users whether login exists or not
- Implement user account lock policy to prevent possible password brute force
- Use strong hashing function for example `[bcrypt](https://en.wikipedia.org/wiki/Bcrypt)`, `[scrypt](https://en.wikipedia.org/wiki/Scrypt)` or `[PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)`to prevent hash passwords reverse engineering in case user credentials database was stolen
- Use salt when hashing a password
<a name="pros-and-cons"></a>

## Pros and Cons
**[Pros and Cons](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication#login-and-password-authentication-pros-and-cons)**

Pros:
<a name="conclusion"></a>

- relatively simple implementation

Cons:

- the need for users to remember a password for each service.
- the need to implement additional service to recover/change password
- the security policy of some organizations requires periodic password changes, which impairs user experience
- the password could be stolen using fishing or social engineering

## Conclusion

Login and password authentication is the most common way to authenticate users, but it is also one of the most insecure, so it is recommended to use authentication without a password (login through social networks, biometrics, use of hardware security keys), or strengthen security by using the second authentication factor.
**[Conclusion](https://doc.openidentityplatform.org/openam/how-to/login-and-password-authentication#login-and-password-authentication-conclusion)**
124 changes: 23 additions & 101 deletions Login-via-"Госуслуги-РФ"-OAuth2-Identity-Provider.md
Original file line number Diff line number Diff line change
@@ -1,123 +1,45 @@
[Russian version TODO](todo)
This article has moved to the Open Identity Platform documentation site:

# Preparation
[Login via Gosuslugi OAuth2 Identity Provider](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider).

## Register an Organization on the Gosuslugi Portal
Please use the documentation site for the current version.

In order to use authentication through the ESIA, you need to register your organization on the Gosuslugi portal. To do this, you need to have a confirmed account of the head of the organization on the portal.
<a name="preparation"></a>

Next, you need to register your information system on the ESIA technology portal. To do this, go to the link [https://esia.gosuslugi.ru/console/tech](https://esia.gosuslugi.ru/console/tech) and authenticate with the account of the head of the organization. On the "Информационные системы" tab, click "Добавить систему" and fill in the properties on the link. The main thing to pay attention to is the system mnemonic, i.e. client_id, system URL - a list of allowed URLs to which redirection will be performed after successful or unsuccessful authentication in ESIA, as well as the algorithm of electronic signature formation - must be GOST3410_2012_256.
**[Preparation](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-preparation)**

The process is described in more detail in document [https://digital.gov.ru/ru/documents/6190/](https://digital.gov.ru/ru/documents/6190/) section 3.1.1
<a name="register-an-organization-on-the-gosuslugi-portal"></a>

## Send System Registration Application to the Ministry of Digitization
**[Register an Organization on the Gosuslugi Portal](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-register-an-organization-on-the-gosuslugi-portal)**

After you have registered an information system, you must obtain a certificate from an accredited certification center (List of accredited certification centers at [https://digital.gov.ru/ru/activity/govservices/certification_authority/](https://digital.gov.ru/ru/activity/govservices/certification_authority/)).
<a name="send-system-registration-application-to-the-ministry-of-digitization"></a>

The algorithm of electronic signature formation is GOST R 34.10-2012. The certificate must contain the OGRN of the legal entity that is the operator of the information system and can be issued for the employee of the legal entity or for the organization.
**[Send System Registration Application to the Ministry of Digitization](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-send-system-registration-application-to-the-ministry-of-digitization)**

Next, you need to fill an application to gain access to the test environment as described in [https://digital.gov.ru/ru/documents/4244/](https://digital.gov.ru/ru/documents/4244/) paragraph 9 and send it to the e-mail address of the Ministry of Digitization.
<a name="openam-installation"></a>

After your system is registered in the test environment, you can proceed to OpenAM configuration.
**[OpenAM Installation](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-openam-installation)**

# OpenAM Installation
<a name="network-setup"></a>

If you have already installed OpenAM, you can skip this section. For demonstration purposes, we will configure OpenAM in a Docker container.
**[Network Setup](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-network-setup)**

## Network Setup
<a name="install-openam-in-docker"></a>

Add the OpenAM hostname and IP address to the `hosts` file
**[Install OpenAM in Docker](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-install-openam-in-docker)**

```bash
127.0.0.0.1 openam.example.org
```
<a name="openam-configuration"></a>

On Windows systems, the `hosts` file is located at `C:Windows/System32/drivers/etc/hosts`; on Linux and Mac it is located at `/etc/hosts`.
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-openam-configuration)**

## Install OpenAM in Docker
<a name="setup-esia-authentication-module"></a>

Start the Docker image of OpenAM by mounting the key and certificate issued earlier to the container.
**[Setup ESIA Authentication Module](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-setup-esia-authentication-module)**

```bash
docker run -h openam.example.org -p 8080:8080 --name openam \
-v ./openam-esia.key:/usr/openam/esia/openam-esia.key:ro \.
-v ./openam-esia.pem:/usr/openam/esia/openam-esia.pem:ro openidentityplatform/openam:latest
```
<a name="configuring-the-esia-authentication-chain"></a>

Once the OpenAM server is running, perform the initial configuration by running the following command and wait for the configuration to complete.
**[Configuring the ESIA Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-configuring-the-esia-authentication-chain)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=openam.example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```

# OpenAM Configuration

## Setup ESIA Authentication Module

Open the OpenAM administrator console at [http://openam.example.org:8080/openam](http://openam.example.org:8080/openam). In the login field enter the `amadmin` value, in the password field enter the value specified in the `ADMIN_PWD` setting, in this case `passw0rd`.

In the console, select the root realm and then select Authentication → Modules from the left menu. In the opened list, click the `Add Module` button.

Enter the module name, for example, `esia` and the module type - `OAuth 2.0 / OpenID Connect`.

![OpenAM new ESIA module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-esia/0-openam-new-esia-module.png)

Press the `Create` button . Fill in the settings according to the table:

| Setting | Value |
| --- | --- |
| Client Id | Mnemonic of the information system specified in the ESIA technology portal |
| Client Secret | Not to be filled in, client secret is calculated dynamically for ESIA |
| Authentication Endpoint URL | https://esia-portal1.test.gosuslugi.ru/aas/oauth2/ac |
| Access Token Endpoint URL | https://esia-portal1.test.gosuslugi.ru/aas/oauth2/te | https://esia-portal1.test.gosuslugi.ru/aas/oauth2/te |
| User Profile Service URL | https://esia-portal1.test.gosuslugi.ru/rs/prns |
| Scope | Scope of the profile, for demonstration purposes we will specify fullname birthdate gender. You can read more about the scope description in the document at [https://digital.gov.ru/ru/documents/6186/](https://digital.gov.ru/ru/documents/6186/) |
| OAuth2 Access Token Profile Service Parameter name | access_token |
| Proxy URL | http://openam.example.org:8080/openam/oauth2c/OAuthProxy.jsp |
| Account Provider | org.forgerock.openam.authentication.modules.common.mapping.DefaultAccountProvider |
| Account Mapper | org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper |
| Account Mapper Configuration | oid=uid |
| Attribute Mapper | org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper |
| Attribute Mapper Configuration | oid=uid, remote-json=sn |
| Custom Properties | |
| esia-key-path | path to the private key file, e.g. /usr/openam/esia/openam-esia.key |
| esia-cert-path | the path to the certificate file, e.g. /usr/openam/esia/openam-esia.pem |
| esia-org-scope | organization scope if you want to get information about the organization of the ESIA user |
| esia-org-info-url | URL to retrieve organization information, e.g. https://esia-portal1.test.gosuslugi.ru/rs/orgs/ - for test ESIA |

## Configuring the ESIA Authentication Chain

Open the OpenAM admin console, select realm and from the left menu select `Authentication → Chains` . Click the `Add Chain` button and enter a name for the chain, for example `esia` . Click the `Create` button.

![OpenAM new ESIA auth chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-esia/1-openam-new-esia-chain.png)

Press the `Add a Module` button.

![OpenAM ESIA auth chain settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-esia/2-openam-esia-chain.png)

Add module `esia` , `Criteria` set to `Requisite`. Press the `OK button .

# Test the solution

Logout the OpenAM admin console, and open the ESUA authentication chain link: [http://openam.example.org:8080/openam/XUI/?service=esia](http://openam.example.org:8080/openam/XUI/?service=esia). If everything is configured correctly, you will be redirected to the ESIA authentication portal. Enter the user's credentials. After successful authentication to the ESIA, the ESIA will request consent to access the data passed in the scope parameter. After accepting the consent, you will be redirected to the OpenAM console with the user's ESIA credentials.
<a name="test-the-solution"></a>

**[Test the solution](https://doc.openidentityplatform.org/openam/how-to/login-via-gosuslugi-oauth2-identity-provider#login-via-gosuslugi-oauth2-identity-provider-test-the-solution)**
71 changes: 29 additions & 42 deletions Login-via-Facebook-OAuth2-Identity-Provider.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,29 @@
## Create Facebook Applicaton
Goto https://developers.facebook.com/apps/ and create new Facebook Application
Goto Application Dashboard. Then goto __Settings -> Basic__. There will be your app App Id and App Secret.

## Setup OpenAM
### Legacy UI
Login into console. Goto __Access Control__ then select target realm. Goto __Authentication__
#### Create Authentication Module
Under section __Module Instances__ create new __Authentication Module__.
Enter new module instance name, for example __facebook__. Authentication module type is __OAuth 2.0 / OpenID Connect__

Then select module, you've just created from module list and enter following settings:

|Setting|Value|
|-------|-----|
|Client Id| Your Facebook Application App Id |
|Client Secret| Your Facebook Application App Secret |
|Authentication Endpoint URL| https://www.facebook.com/dialog/oauth |
|Access Token Endpoint URL | https://graph.facebook.com/oauth/access_token |
|User Profile Service URL | https://graph.facebook.com/me |
|Scope | _Here you should enter scope, according to Facebook [documentation](https://developers.facebook.com/docs/facebook-login/permissions)_ for example __email__ |
|OAuth2 Access Token Profile Service Parameter name| access_token|
|Proxy URL| _[Your OpenAM URL]/oauth2c/OAuthProxy.jsp_ for example: https://openam.example.com/openam/oauth2c/OAuthProxy.jsp |
|Account Provider|org.forgerock.openam.authentication.modules.common.mapping.DefaultAccountProvider|
|Account Mapper|org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper|
|Account Mapper Configuration|Attribute configuration that will be used to map the account of the user authenticated in the OAuth 2.0 Provider to the local data store in the OpenAM. Example: <br>id=facebook-id <br> email=mail|
|Attribute Mapper| org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper |
|Attribute Mapper Configuration| Attribute configuration that will be used to map the user info obtained from the OAuth 2.0 Provider to the local user data store in the OpenAM. Example: <br> last_name=sn<br>last_name=facebook-lname<br>email=mail<br>first_name=givenname<br>first_name=facebook-fname<br>name=cn<br>email=facebook-email<br>id=facebook-id |

You can setup remaining attributes on your own, depending your authentication process requirement and press __Save__ and then __Back to Authentication__

#### Create Authentication Chain
Under section __Authentication Chaining__ create new Authentication Chain, enter its name, for example, __facebook__ and add recently created module __facebook__

Your authentication chain should look like this:

|Instance|Criteria|Options|
|--------|--------|-------|
|facebook|Required|&nbsp;|

### Test your Authentication Chain
Goto [Your OpenAM URL]/UI/Login?org=[your org]&service=[facebook auth chain], for example, http://example.openam.com/openam/UI/Login?org=/&service=facebook and you should see facebook authentication dialog
This article has moved to the Open Identity Platform documentation site:

[Login via Facebook OAuth2 Identity Provider](https://doc.openidentityplatform.org/openam/how-to/login-via-facebook-oauth2-identity-provider).

Please use the documentation site for the current version.

<a name="create-facebook-applicaton"></a>

**[Create Facebook Applicaton](https://doc.openidentityplatform.org/openam/how-to/login-via-facebook-oauth2-identity-provider#login-via-facebook-oauth2-identity-provider-create-facebook-applicaton)**

<a name="setup-openam"></a>

**[Setup OpenAM](https://doc.openidentityplatform.org/openam/how-to/login-via-facebook-oauth2-identity-provider#login-via-facebook-oauth2-identity-provider-setup-openam)**

<a name="legacy-ui"></a>

**[Legacy UI](https://doc.openidentityplatform.org/openam/how-to/login-via-facebook-oauth2-identity-provider#login-via-facebook-oauth2-identity-provider-legacy-ui)**

<a name="create-authentication-module"></a>

**[Create Authentication Module](https://doc.openidentityplatform.org/openam/how-to/login-via-facebook-oauth2-identity-provider#login-via-facebook-oauth2-identity-provider-create-authentication-module)**

<a name="create-authentication-chain"></a>

**[Create Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/login-via-facebook-oauth2-identity-provider#login-via-facebook-oauth2-identity-provider-create-authentication-chain)**

<a name="test-your-authentication-chain"></a>

**[Test your Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/login-via-facebook-oauth2-identity-provider#login-via-facebook-oauth2-identity-provider-test-your-authentication-chain)**
71 changes: 29 additions & 42 deletions Login-via-Odnoklassniki-OAuth2-Identity-Provider.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,29 @@
## Create Odnoklassniki Applicaton
Create Odnoklassniki application as described here https://apiok.ru/dev/app/create. After you create application you'll receive: Application ID, Application Key and Aplication Secret.

## Setup OpenAM
### Legacy UI
Login into console. Goto __Access Control__ then select target realm. Goto __Authentication__
#### Create Authentication Module
Under section __Module Instances__ create new __Authentication Module__.
Enter new module instance name, for example __odnoklassniki__. Authentication module type is __OAuth 2.0 / OpenID Connect__

Then select module, you've just created from module list and enter following settings:

|Setting|Value|
|-------|-----|
|Client Id| Your Odnoklassniki Application Id |
|Client Secret| Your Odnoklassniki Application Secret |
|Authentication Endpoint URL| https://connect.ok.ru/oauth/authorize |
|Access Token Endpoint URL | https://api.ok.ru/oauth/token.do |
|User Profile Service URL | https://api.ok.ru/api/users/getCurrentUser|
|Scope | _Here you should enter scope, according to Odnoklassniki [documentation](https://apiok.ru/ext/oauth/permissions)_ for example __VALUABLE_ACCESS;LONG_ACCESS_TOKEN__ |
|OAuth2 Access Token Profile Service Parameter name| access_token|
|Proxy URL| _[Your OpenAM URL]/oauth2c/OAuthProxy.jsp_ for example: https://openam.example.com/openam/oauth2c/OAuthProxy.jsp |
|Account Provider|org.forgerock.openam.authentication.modules.common.mapping.DefaultAccountProvider|
|Account Mapper|org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper|
|Account Mapper Configuration|Attribute configuration that will be used to map the account of the user authenticated in the OAuth 2.0 Provider to the local data store in the OpenAM. Example: <br>uid=uid|
|Attribute Mapper| org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper |
|Attribute Mapper Configuration| Attribute configuration that will be used to map the user info obtained from the OAuth 2.0 Provider to the local user data store in the OpenAM. Example: <br> first_name=cn<br>last_name=givenName|
|Custom Properties| Add Oddnoklassniki Application Key as __ok-public-key__ property, for examplpe <br> __ok-public-key=AAAAAAAAAAAAAA__|

You can setup remaining attributes on your own, depending your authentication process requirement and press __Save__ and then __Back to Authentication__

#### Create Authentication Chain
Under section __Authentication Chaining__ create new Authentication Chain, enter its name, for example, __odnoklassniki__ and add recently created module __odnoklassniki__

Your authentication chain should look like this:

|Instance|Criteria|Options|
|--------|--------|-------|
|odnoklassniki|Required|&nbsp;|

### Test your Authentication Chain
Goto [Your OpenAM URL]/UI/Login?org=[your org]&service=[ok auth chain], for example, http://example.openam.com/openam/UI/Login?org=/&service=odnoklassniki and you should see Odnoklassniki authentication dialog
This article has moved to the Open Identity Platform documentation site:

[Login via Odnoklassniki OAuth2 Identity Provider](https://doc.openidentityplatform.org/openam/how-to/login-via-odnoklassniki-oauth2-identity-provider).

Please use the documentation site for the current version.

<a name="create-odnoklassniki-applicaton"></a>

**[Create Odnoklassniki Applicaton](https://doc.openidentityplatform.org/openam/how-to/login-via-odnoklassniki-oauth2-identity-provider#login-via-odnoklassniki-oauth2-identity-provider-create-odnoklassniki-applicaton)**

<a name="setup-openam"></a>

**[Setup OpenAM](https://doc.openidentityplatform.org/openam/how-to/login-via-odnoklassniki-oauth2-identity-provider#login-via-odnoklassniki-oauth2-identity-provider-setup-openam)**

<a name="legacy-ui"></a>

**[Legacy UI](https://doc.openidentityplatform.org/openam/how-to/login-via-odnoklassniki-oauth2-identity-provider#login-via-odnoklassniki-oauth2-identity-provider-legacy-ui)**

<a name="create-authentication-module"></a>

**[Create Authentication Module](https://doc.openidentityplatform.org/openam/how-to/login-via-odnoklassniki-oauth2-identity-provider#login-via-odnoklassniki-oauth2-identity-provider-create-authentication-module)**

<a name="create-authentication-chain"></a>

**[Create Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/login-via-odnoklassniki-oauth2-identity-provider#login-via-odnoklassniki-oauth2-identity-provider-create-authentication-chain)**

<a name="test-your-authentication-chain"></a>

**[Test your Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/login-via-odnoklassniki-oauth2-identity-provider#login-via-odnoklassniki-oauth2-identity-provider-test-your-authentication-chain)**
71 changes: 29 additions & 42 deletions Login-via-VK-OAuth2-Identity-Provider.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,29 @@
## Create Applicaton
Goto https://vk.com/apps?act=manage and create new VKontakte Application
Goto Application Setting. There will be your app App Id and App Secret.

## Setup OpenAM
### Legacy UI
Login into console. Goto __Access Control__ then select target realm. Goto __Authentication__
#### Create Authentication Module
Under section __Module Instances__ create new __Authentication Module__.
Enter new module instance name, for example __vkontakte__. Authentication module type is __OAuth 2.0 / OpenID Connect__

Then select module, you've just created from module list and enter following settings:

|Setting|Value|
|-------|-----|
|Client Id| Your VKontakte Application App Id |
|Client Secret| Your VKontakte Application App Secret |
|Authentication Endpoint URL| https://oauth.vk.com/authorize |
|Access Token Endpoint URL | https://oauth.vk.com/access_token |
|User Profile Service URL | https://api.vk.com/method/users.get |
|Scope | _Here you should enter scope, according to VKontakte [documentation](https://vk.com/dev/permissions)_ for example __email__ |
|OAuth2 Access Token Profile Service Parameter name| access_token|
|Proxy URL| _[Your OpenAM URL]/oauth2c/OAuthProxy.jsp_ for example: https://openam.example.com/openam/oauth2c/OAuthProxy.jsp |
|Account Provider|org.forgerock.openam.authentication.modules.common.mapping.DefaultAccountProvider|
|Account Mapper|org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper|
|Account Mapper Configuration|Attribute configuration that will be used to map the account of the user authenticated in the OAuth 2.0 Provider to the local data store in the OpenAM. Example: <br>id=uid|
|Attribute Mapper| org.forgerock.openam.authentication.modules.common.mapping.JsonAttributeMapper |
|Attribute Mapper Configuration| Attribute configuration that will be used to map the user info obtained from the OAuth 2.0 Provider to the local user data store in the OpenAM. Example: <br> last_name=givenName <br> id=uid |

You can setup remaining attributes on your own, depending your authentication process requirement and press __Save__ and then __Back to Authentication__

#### Create Authentication Chain
Under section __Authentication Chaining__ create new Authentication Chain, enter its name, for example, __vkontakte__ and add recently created module __vkontakte__

Your authentication chain should look like this:

|Instance|Criteria|Options|
|--------|--------|-------|
|vkontakte|Required|&nbsp;|

### Test your Authentication Chain
Goto [Your OpenAM URL]/UI/Login?org=[your org]&service=[facebook auth chain], for example, http://example.openam.com/openam/UI/Login?org=/&service=vkontakte and you should see facebook authentication dialog
This article has moved to the Open Identity Platform documentation site:

[Login via VK OAuth2 Identity Provider](https://doc.openidentityplatform.org/openam/how-to/login-via-vk-oauth2-identity-provider).

Please use the documentation site for the current version.

<a name="create--applicaton"></a>

**[Create Applicaton](https://doc.openidentityplatform.org/openam/how-to/login-via-vk-oauth2-identity-provider#login-via-vk-oauth2-identity-provider-create-applicaton)**

<a name="setup-openam"></a>

**[Setup OpenAM](https://doc.openidentityplatform.org/openam/how-to/login-via-vk-oauth2-identity-provider#login-via-vk-oauth2-identity-provider-setup-openam)**

<a name="legacy-ui"></a>

**[Legacy UI](https://doc.openidentityplatform.org/openam/how-to/login-via-vk-oauth2-identity-provider#login-via-vk-oauth2-identity-provider-legacy-ui)**

<a name="create-authentication-module"></a>

**[Create Authentication Module](https://doc.openidentityplatform.org/openam/how-to/login-via-vk-oauth2-identity-provider#login-via-vk-oauth2-identity-provider-create-authentication-module)**

<a name="create-authentication-chain"></a>

**[Create Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/login-via-vk-oauth2-identity-provider#login-via-vk-oauth2-identity-provider-create-authentication-chain)**

<a name="test-your-authentication-chain"></a>

**[Test your Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/login-via-vk-oauth2-identity-provider#login-via-vk-oauth2-identity-provider-test-your-authentication-chain)**
254 changes: 49 additions & 205 deletions Migrate-OpenAM-to-Apache-Cassandra-without-Single-Point-of-Failure.md
Original file line number Diff line number Diff line change
@@ -1,205 +1,49 @@
<h1>Initial Data Storage Scheme</h1>
<table>
<tbody>
<tr>
<th>Data Type</th>
<th>Storage Method</th>
<th>Fautl Tolerance Method</th>
<th colspan="1">Disadvantages</th></tr>
<tr>
<td>OpenAM configuration</td>
<td rowspan="3">OpenDJ (localhost:1389)</td>
<td rowspan="3">Multi-master replication<span>&nbsp;</span></td>
<td colspan="1">Configuration update on a single node affects all nodes by replication.</td></tr>
<tr>
<td>CTS-Core Token Service (Session persistence)</td>
<td rowspan="2">
<p>Syncronisation payload processed on all nodes</p>
<p>Read performance from single node restricted by single node performance.</p>
<p>Replication failure could cause other nodes to read-only mode</p></td></tr>
<tr>
<td>Accounts repository (except AD)</td></tr></tbody></table>

<h1>Data Storage Scheme for the Number of Credentials &gt;5 Million</h1>
<table>
<tbody>
<tr>
<th>Data Type</th>
<th>Storage Method</th>
<th>Fault Tolerance Method</th>
<th colspan="1">Disadvantages</th></tr>
<tr>
<td>OpenAM configuration</td>
<td>OpenDJ (localhost:1389)</td>
<td>Local independent storage as a part of the distribution (war file)</td>
<td colspan="1">Updating the configuration on one node does not affect other nodes (the nodes are completely independent)</td></tr>
<tr>
<td>CTS-Core Token Service (Session persistence)</td>
<td rowspan="2">Cassandra Cluster (tcp:9042)</td>
<td rowspan="2">Cluster without a single point of failure with geo-distribution and distribution by rack</td>
<td rowspan="2">
<p>Synchronization write payload is processed only on the nodes with the required replication level</p>
<p>The reading load from one node is not limited to the performance of one node, but distributed according to the replication level.</p>
<p>Node failure does cause replication stop according to the replication level</p></td></tr>
<tr>
<td>Accounts repository (except AD)</td></tr></tbody></table>

<h2>Migration Plan</h2>
<ol>
<li>Cluster hardware resources planning</li>
<li>Deploy the cluster according to the required level of fault tolerance</li>
<li>Provide network access OpenAM-&gt; tcp:9042</li>
<li>Migration stages (can be done independently):
<ol>
<li><span>Switch &quot;CTS - Core Token Service (sessions)&quot;</span></li>
<li><span><span>Switch &quot;Accounts repository (except AD)&quot; with legacy data migration</span></span></li>
<li><span><span><span>Switch &quot;OpenAM configuration&quot;</span></span></span></li></ol></li></ol>

<h2>Fault Tolerance Level Planning</h2>
<h3>Datacenter</h3>
<p>Defines geo-distributed storage fault tolerance. &nbsp;</p>
<ul>
<li>Minimum number of data centers: 1</li>
<li>The recommended number of data centers:&nbsp;
<ul>
<li>at least two&nbsp;</li>
<li>at least the same number of data centers used for application servers (OpenAM)</li></ul></li>
<li>Allowed data center fault tolerance mode:
<ul>
<li>Hot Spare: used for data processing&nbsp;for application servers (OpenAM)</li>
<li>Cold Spare: not used for data processing&nbsp;for application servers (OpenAM)</li></ul></li></ul>

<h3>Rack</h3>
<p>Minimum fault tolerance unit within a data center for data distribution within a data center, haves:</p>
<ul>
<li>Independent disk subsystem array</li>
<li>Independent virtualization hypervisor (host system)</li></ul>
<p>Amount calculation:</p>
<ul>
<li>Minimum quantity inside hot spare data center: 1, but not less than replication level inside the data center</li>
<li>Minimum quantity inside cold spare datacenter: 1, but not less than replication level inside the datacenter</li></ul>
<h3>Node</h3>
<div>Defines the unit of information storage and load inside the data center rack</div>

<h2>An Example of a Recommended Minimum Configuration</h2>
<h3>Test</h3>
<table>
<tbody>
<tr>
<th>DataCenter</th>
<th colspan="1">Type</th>
<th colspan="1">Amount of Copies</th>
<th>Rack</th>
<th colspan="1">% data</th>
<th>Node</th>
<th colspan="1">% data</th></tr>
<tr>
<td>dc01</td>
<td colspan="1">host</td>
<td colspan="1">1</td>
<td>rack01</td>
<td colspan="1">100%</td>
<td>dc01-rack01-node01</td>
<td colspan="1">100%</td></tr></tbody></table>

<h3>Production</h3>
<table>
<tbody>
<tr>
<th>DataCenter</th>
<th colspan="1">Type</th>
<th colspan="1">Amount of Copies</th>
<th>Rack</th>
<th colspan="1">data %</th>
<th>Node</th>
<th colspan="1"><span>data %</span></th></tr>
<tr>
<td>dc01</td>
<td colspan="1">hot</td>
<td colspan="1">1</td>
<td>rack01</td>
<td colspan="1" style="text-align: center;">100%</td>
<td><span>dc01-rack01-</span>node01</td>
<td colspan="1" style="text-align: center;">50%</td></tr>
<tr>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1" style="text-align: center;">&nbsp;</td>
<td colspan="1"><span>dc01-rack01-</span><span>node02</span></td>
<td colspan="1" style="text-align: center;"><span>50%</span></td></tr>
<tr>
<td>&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">1</td>
<td><span>rack02</span></td>
<td colspan="1" style="text-align: center;"><span>100%</span></td>
<td><span>dc01-rack02-</span><span>node01</span></td>
<td colspan="1" style="text-align: center;"><span>50%</span></td></tr>
<tr>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1" style="text-align: center;">&nbsp;</td>
<td colspan="1"><span>dc01-rack02-</span><span>node02</span></td>
<td colspan="1" style="text-align: center;"><span>50%</span></td></tr>
<tr>
<td><span>dc02</span></td>
<td colspan="1"><span>hot</span></td>
<td colspan="1">1</td>
<td><span>rack01</span></td>
<td colspan="1" style="text-align: center;"><span>100%</span></td>
<td><span>dc02-rack01-</span><span>node01</span></td>
<td colspan="1" style="text-align: center;"><span>50%</span></td></tr>
<tr>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1" style="text-align: center;">&nbsp;</td>
<td colspan="1"><span>dc02-rack01-</span><span>node02</span></td>
<td colspan="1" style="text-align: center;"><span>50%</span></td></tr>
<tr>
<td>&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">1</td>
<td><span>rack02</span></td>
<td colspan="1" style="text-align: center;"><span>100%</span></td>
<td><span>dc02-rack02-</span><span>node01</span></td>
<td colspan="1" style="text-align: center;"><span>50%</span></td></tr>
<tr>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1">&nbsp;</td>
<td colspan="1" style="text-align: center;">&nbsp;</td>
<td colspan="1"><span>dc02-rack02-</span><span>node02</span></td>
<td colspan="1" style="text-align: center;"><span>50%</span></td></tr></tbody></table>
<p>&nbsp;</p>
<p>Allowed:</p>
<ul>
<li>Increase the data center amount without service interruption</li>
<li>Increase the rack amount without service interruption</li>
<li>Increase the node amount without service interruption</li>
<li>Change the number of data copies inside the data center without service interruption</li></ul>

<h2>Hardware Requirements For a Single Node</h2>
<table>
<tbody>
<tr>
<th colspan="1">Environment</th>
<th>CPU</th>
<th>RAM</th>
<th>Disk</th></tr>
<tr>
<td colspan="1">Test</td>
<td>&gt;=2</td>
<td>&gt;=8</td>
<td>16G HDD</td></tr>
<tr>
<td colspan="1">Production</td>
<td>&gt;=8</td>
<td>&gt;=32 ballon=off</td>
<td>64G SSD RAID</td></tr></tbody></table>
This article has moved to the Open Identity Platform documentation site:

[Migrate OpenAM to Apache Cassandra without Single Point of Failure](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure).

Please use the documentation site for the current version.

<a name="initial-data-storage-scheme"></a>

**[Initial Data Storage Scheme](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-initial-data-storage-scheme)**

<a name="data-storage-scheme-for-the-number-of-credentials-5-million"></a>

**[Data Storage Scheme for the Number of Credentials >5 Million](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-data-storage-scheme-for-the-number-of-credentials-5-million)**

<a name="migration-plan"></a>

**[Migration Plan](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-migration-plan)**

<a name="fault-tolerance-level-planning"></a>

**[Fault Tolerance Level Planning](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-fault-tolerance-level-planning)**

<a name="datacenter"></a>

**[Datacenter](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-datacenter)**

<a name="rack"></a>

**[Rack](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-rack)**

<a name="node"></a>

**[Node](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-node)**

<a name="an-example-of-a-recommended-minimum-configuration"></a>

**[An Example of a Recommended Minimum Configuration](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-an-example-of-a-recommended-minimum-configuration)**

<a name="test"></a>

**[Test](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-test)**

<a name="production"></a>

**[Production](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-production)**

<a name="hardware-requirements-for-a-single-node"></a>

**[Hardware Requirements For a Single Node](https://doc.openidentityplatform.org/openam/how-to/migrate-openam-to-apache-cassandra-without-single-point-of-failure#migrate-openam-to-apache-cassandra-without-single-point-of-failure-hardware-requirements-for-a-single-node)**
106 changes: 13 additions & 93 deletions OpenAM-Monitoring-Using-Prometheus.md
Original file line number Diff line number Diff line change
@@ -1,105 +1,25 @@
# OpenAM Monitoring Using Prometheus
This article has moved to the Open Identity Platform documentation site:

## Preface
[OpenAM Monitoring Using Prometheus](https://doc.openidentityplatform.org/openam/how-to/openam-monitoring-using-prometheus).

[OpenAM](https://github.com/OpenIdentityPlatform/OpenAM) can expose SNMP metrics. To expose these metrics to Prometheus we will use [snmp_exporter](https://github.com/prometheus/snmp_exporter) tool, provided by the Prometheus community.
Please use the documentation site for the current version.

To follow the current manual Docker and Docker Compose should be installed
<a name="openam-monitoring-using-prometheus"></a>

Configuration files located in this project [https://github.com/maximthomas/openam-prometheus](https://github.com/maximthomas/openam-prometheus)
**[OpenAM Monitoring Using Prometheus](https://doc.openidentityplatform.org/openam/how-to/openam-monitoring-using-prometheus)**

Just clone it and run with docker-compose:
<a name="preface"></a>

```bash
git clone https://github.com/maximthomas/openam-prometheus.git
```
```bash
cd ./openam-prometheus
```
**[Preface](https://doc.openidentityplatform.org/openam/how-to/openam-monitoring-using-prometheus#openam-monitoring-using-prometheus-preface)**

```bash
docker-compose up
```
<a name="setup-openam-and-snmp-monitoring"></a>

**[Setup OpenAM and SNMP Monitoring](https://doc.openidentityplatform.org/openam/how-to/openam-monitoring-using-prometheus#openam-monitoring-using-prometheus-setup-openam-and-snmp-monitoring)**

## Setup OpenAM and SNMP Monitoring
<a name="setup-snmp-exporter"></a>

Open OpenAM URL and create a basic configuration (see [OpenAM Quick Start Gude](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Quick-Start-Guide))
**[Setup SNMP Exporter](https://doc.openidentityplatform.org/openam/how-to/openam-monitoring-using-prometheus#openam-monitoring-using-prometheus-setup-snmp-exporter)**

Enable SNMP in OpenAM. Login into OpenAM console, goto **Configure -> Global Services -> Monitoring**
<a name="setup-prometheus"></a>

![OpenAM monitoring](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-prometheus/openam-monitoring.png)

Enable checkboxes **Monitoring Status** and **Monitoring SNMP interface status**

Restart OpenAM instance

## Setup SNMP Exporter

Open SNMP exporter URL

[http://localhost:9116/](http://localhost:9116/)

![SNMP exporter](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-prometheus/snmp-exporter.png)

Fill the fields:
Target: OpenAM hostname and port, for example `openam:8085`
Module: SNMP exporter module, for example `openam`

Press the Submit, then you should see something like this:

```
# HELP authenticationFailureCount Count of unsuccessful authentications - 1.3.6.1.4.1.42.2.230.3.1.1.2.1.10.2
# TYPE authenticationFailureCount counter
authenticationFailureCount 0
# HELP authenticationFailureRate Current Auth failure rate / second based on a fixed preconfigured window. - 1.3.6.1.4.1.42.2.230.3.1.1.2.1.10.4
# TYPE authenticationFailureRate gauge
authenticationFailureRate 0
# HELP authenticationSuccessCount Count of successful authentications - 1.3.6.1.4.1.42.2.230.3.1.1.2.1.10.1
# TYPE authenticationSuccessCount counter
authenticationSuccessCount 0
# HELP authenticationSuccessRate Current Auth success rate / second based on a fixed preconfigured window. - 1.3.6.1.4.1.42.2.230.3.1.1.2.1.10.3
# TYPE authenticationSuccessRate gauge
authenticationSuccessRate 0
# HELP averageDuration Average duration of tokens of the specified type in OpenAM in seconds - 1.3.6.1.4.1.36733.1.2.3.5.1.2
# TYPE averageDuration counter
averageDuration{tokenTableIndex="1"} 1532
averageDuration{tokenTableIndex="10"} 0
averageDuration{tokenTableIndex="11"} 0
averageDuration{tokenTableIndex="12"} 0
averageDuration{tokenTableIndex="13"} 0
averageDuration{tokenTableIndex="14"} 0
averageDuration{tokenTableIndex="15"} 0
averageDuration{tokenTableIndex="16"} 340
......
```


## Setup Prometheus

If you have an existing prometheus instance add to `prometheus.yml` job `openam` with a target to SNMP exporter host and port:

```yaml
- job_name: "openam"
params:
target: ["openam:8085"]
module: ["openam"]
metrics_path: /snmp
static_configs:
- targets: ["snmp-exporter:9116"]
```
Run Prometheus and check targets:
[http://localhost:9090/targets](http://localhost:9090/targets)
You should see something like this:
![Prometheus target](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-prometheus/prometheus-target.png)
Then go to Graph and you will be able to add OpenAM metrics to monitor.
[http://localhost:9090/graph](http://localhost:9090/graph)
![Prometheus graph](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-prometheus/prometheus-graph.png)
If you have any additional questions, [feel free to ask us](https://github.com/OpenIdentityPlatform/OpenAM/discussions)!
**[Setup Prometheus](https://doc.openidentityplatform.org/openam/how-to/openam-monitoring-using-prometheus#openam-monitoring-using-prometheus-setup-prometheus)**
74 changes: 19 additions & 55 deletions OpenAM-QR-Authentication-Module.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,37 @@
This article has moved to the Open Identity Platform documentation site:

- [Introduction](#introduction)
- [Process Description](#process-description)
- [OpenAM Configuration](#openam-configuration)
- [Mobile Application Configuration](#mobile-application-configuration)
- [Testing Solution](#testing-solution)
[OpenAM QR Authentication Module](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module).

# Introduction
Please use the documentation site for the current version.

The most popular authentication method is also the most inconvenient. It is login and password authentication. A user must remember his login and password for each service, could forget the password, a password could be compromised, etc. The following article describes, how to login into the application in the browser on another device, if the user is already authenticated in a mobile application. The article contains step by step guide on how to set up the process in OpenAM.
<a name="introduction"></a>

# Process Description
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-introduction)**

- The user has a valid authentication session in the mobile application.
- The user opens the OpenAM authentication page.
- OpenAM generates a random code with a limited lifetime and displays it to the user as a QR code.
- User scan the QR with the mobile application
- Mobile application sends the code to OpenAM within authenticated session identifier
- Meanwhile, the browser periodically polls OpenAM to see if the code is received along with the authentication session
- If the code was received, authentication is successful and an authentication session is created.
<a name="process-description"></a>

## OpenAM Configuration
**[Process Description](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-process-description)**

At first, we will set up OpenAM, create an authentication module instance and an authentication chain with the instance.
<a name="openam-configuration"></a>

## Create QR Authentication Module Instance
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-openam-configuration)**

Go to the desired realm, then on the left side of the Authentication → Modules menu. The list of modules opens. Press the Add Module button. Enter the name of the module qr and choose QR code confirm from other session module type.
<a name="create-qr-authentication-module-instance"></a>

![New QR module Instance](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-qr/new-qr-module.png)
**[Create QR Authentication Module Instance](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-create-qr-authentication-module-instance)**

Press the Create button.
<a name="create-authentication-chain"></a>

![New QR module Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-qr/qr-module-settings.png)
**[Create Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-create-authentication-chain)**

Set desired QR code lifetime and authentication level and press the Save Changes button.
<a name="mobile-application-configuration"></a>

## Create Authentication Chain
**[Mobile Application Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-mobile-application-configuration)**

Go to **Authentication → Chains**. And create a new **qr** authentication chain. Add the created **qr** module to the chain.
<a name="mobile-application-setup"></a>

![QR authentication chain Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-qr/qr-auth-chain.png)
**[Mobile Application Setup](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-mobile-application-setup)**

# Mobile Application Configuration
<a name="testing-solution"></a>

Let's install and configure the mobile application. The following mobile application is only for demonstration and is not intended for production usage. But you can use application source code to build your application or modify application source code for your tasks. The application was developed with [Flutter](https://flutter.dev/)

Mobile application source code: [https://github.com/OpenIdentityPlatform/openam_demo_authenticator](https://github.com/OpenIdentityPlatform/openam_demo_authenticator)

Run the mobile application:

```bash
flutter run
```

## Mobile Application Setup

Press the Settings icon in the upper-right corner of the application and go to the settings menu. Enter OpenAM URL, realm, OpenAM username and password. Press the Back button in the upper-left corner. Settings data will be stored in the device's secure storage.

![QR mobile application settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-qr/qr-mobile-settings.png)

# Testing Solution

If you were logged in, log out from OpenAM. Open OpenAM URL with QR authentication chain. For example, [http://openam.example.org:8080/openam/XUI/#login/&realm=/&service=qr](http://openam.example.org:8080/openam/XUI/#login/&realm=/&service=qr) Replace [http://openam.example.org:8080/openam](http://openam.example.org:8080/openam) with your OpenAM URL. You will see a QR code that you need to scan. As well as the same code in the form of text as shown in the image below

![OpenAM QR code page](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-qr/qr-code-page.png)

Open the mobile application, press the Login button. The application will authenticate in OpenAM in the specified realm with specified credentials. If authentication succeeds, you'll see the user name and first symbols of the OpenAM authentication token

![QR mobile mobile authentication successful](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-qr/qr-mobile-successful.png)

Then press the "Scan QR to authenticate" button, scan the QR code and you will a message about successful authentication. Meanwhile, the browser will authenticate the scanned QR code.
If it is not possible to scan a QR code, you can enter the code manually in the "Enter a code from QR" field and press Authenticate. If you entered the code correctly, you will also be authenticated.
**[Testing Solution](https://doc.openidentityplatform.org/openam/how-to/openam-qr-authentication-module#openam-qr-authentication-module-testing-solution)**
166 changes: 11 additions & 155 deletions OpenAM-and-Spring-Boot-3-Integration-via-OIDC-OAuth2-Protocol.md
Original file line number Diff line number Diff line change
@@ -1,165 +1,21 @@
# Introduction
This article has moved to the Open Identity Platform documentation site:

There are several ways to integrate Spring application with OpenAM. In the following tutorial, we will integrate Spring Application with OpenAM using the OIDC/OAuth2 protocol.
[OpenAM and Spring Boot 3 Integration via OIDC OAuth2 Protocol](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol).

# OpenAM Configuration
Please use the documentation site for the current version.

If you have not installed OpenAM yet, you could run OpenAM as a [Docker image](https://hub.docker.com/r/openidentityplatform/openam/). Let’s assume the OpenAM instance URL is `http://openam.example.org:8080/openam`
<a name="introduction"></a>

Go to the target realm and in the Common Tasks section. Open OpenAM console in a browser and create OAuth2 Provider. Press the `Configure OAuth Provider` button, and then the `Configure OpenID Connect` button.
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol#openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol-introduction)**

![Realm Common Tasks](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/realm-common-tasks.png)
<a name="openam-configuration"></a>

![Realm Setup OIDC](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/realm-oidc.png)
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol#openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol-openam-configuration)**

Ajust the required setting and press the Create button.
<a name="spring-boot-application"></a>

![OIDC configuration](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/configure-oidc.png)
**[Spring Boot Application](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol#openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol-spring-boot-application)**

Go back to the realm and select in the realm’s dashboard Applications → OAuth 2.0 in the right menu.
<a name="test-the-solution"></a>

![Realm OAuth2 Applications](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/realm-applications-oauth.png)

Create a new Agent, set name (client id) and password (client secret) and press the Next button. Go to the new created agent and set the following settings

- Add `http://localhost:8081/login/oauth2/code/openam` to **Redirection URIs** values (is will be our Spring Security application code endpoint)
- Add `profile` and `openid` values to **Scope(s)**
- Set **ID Token Signing Algorithm** setting to RS256.

# Spring Boot Application

Create a new Spring Boot application and add the following Maven dependencies.

```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--security dependencies-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
```

Create a controller and two endpoints: `index` and `protected-oauth`. The `index` endpoint will be accessible for anyone and `protected-oauth` endpoint will be accessible for authenticated with OpenAM users via OIDC protocol.

```java
@Controller
public class SampleController {

@GetMapping
public String index() {
return "index";
}

@GetMapping("/oauth")
public String oauthProtected(HttpServletRequest request, Model model) {
Principal token = request.getUserPrincipal();
model.addAttribute("userName", token.getName());
model.addAttribute("method", "OAuth2/OIDC");
return "protected";
}
}
```

Create the following templates for controllers:

`index.html`

```html
<!DOCTYPE html>
<html>
<body>
<h1>OpenAM Spring Security Integration</h1>
<h2>Test Authentication</h2>
<ul>
<li><a href="/protected-oauth">OAuth2/OIDC</a></li>
</ul>
</body>
</html>
```

`protected.html`

```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Protected resource</h1>
<a href="/">Back</a></li>
<p><span th:text="${userName}"/> user authenticated with <span th:text="${method}"/></p>
</body>
</html>
```

Create Spring Security configuration

```java
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityWebFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> authorize.requestMatchers("/", "/oauth2/**")
.permitAll()
.requestMatchers("/protected-oauth").authenticated())
.oauth2Login(Customizer.withDefaults()).oauth2Client(Customizer.withDefaults()
);
return http.build();
}
}
```

Add the following settings to the `application.yml` file:

```yaml
server:
port: 8081
spring:
security:
oauth2:
client:
registration:
openam:
authorization-grant-type: authorization_code
client-id: test_client
client-secret: changeme
scope:
- openid
- profile
provider:
openam:
authorization-uri: http://openam.example.org:8080/openam/oauth2/authorize
token-uri: http://openam.example.org:8080/openam/oauth2/access_token
user-name-attribute: sub
issuer-uri: http://openam.example.org:8080/openam/oauth2
```
# Test the Solution
Logout form OpenAM if you are logged in.
Run the Spring application an open its URL in a browser: http://localhost:8081
![Spring Boot App Index](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/test-app.png)
Click on the OAuth2/OIDC navigation link, and you will be redirected to the OpenAM authentication page.
![OpenAM Authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/openam-auth.png)
Enter the user’s login and password and then press the LOG IN button.
![OpenAM Consent](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/openam-consent.png)
After pressing the Allow button, you will be redirected to the Spring Security Application as an authenticated user.
![Spring Boot App Authenticated](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-oauth/test-app-authenticated.png)
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol#openam-and-spring-boot-3-integration-via-oidc-oauth2-protocol-test-the-solution)**
236 changes: 13 additions & 223 deletions OpenAM-and-Spring-Boot-3-Integration-via-OpenAM-Cookie.md
Original file line number Diff line number Diff line change
@@ -1,235 +1,25 @@
# Introduction
This article has moved to the Open Identity Platform documentation site:

In the following article, we will set up OpenAM as an Identity Provider for a Spring Boot Application. In the [previous article,](https://github.com/OpenIdentityPlatform/OpenAM/wiki/OpenAM-and-Spring-Boot-3-Integration-via-SAMLv2-Protocol) we set up a Spring Boot application authentication via OpenAM with SAMLv2 protocol. In the following article, we will set up authentication via OpenAM cookie.
[OpenAM and Spring Boot 3 Integration via OpenAM Cookie](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-openam-cookie).

# Prerequisites
Please use the documentation site for the current version.

OpenAM and Spring Boot applications should share same domain. In the following example, OpenAM host is `openam.example.org` and Spring Boot application host is `app.example.org`.
<a name="introduction"></a>

To test the example on the local machine, add the following lines to your hosts file:
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-openam-cookie#openam-and-spring-boot-3-integration-via-openam-cookie-introduction)**

```makefile
127.0.0.1 openam.example.org app.example.org
```
<a name="prerequisites"></a>

# OpenAM Configuration
**[Prerequisites](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-openam-cookie#openam-and-spring-boot-3-integration-via-openam-cookie-prerequisites)**

Open OpenAM administration console. In the top menu go to Configure → Global Services → Platform. Set Cookie Domains as the common domain for the both applications: `example.org`
<a name="openam-configuration"></a>

![OpenAM Cookie Domain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-cookie/openam-cookie-domain.png)
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-openam-cookie#openam-and-spring-boot-3-integration-via-openam-cookie-openam-configuration)**

# Spring Application Configuration
<a name="spring-application-configuration"></a>

Create a new Spring Boot application and add the following Maven repositories and add the following dependencies:
**[Spring Application Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-openam-cookie#openam-and-spring-boot-3-integration-via-openam-cookie-spring-application-configuration)**

```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--security dependencies-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
```
<a name="test-solution"></a>

Add the following settings to the `application.yml` file

```yaml
server:
port: 8081
```
Create a controller and two endpoints: `index` and `protected-openam`. The `index` endpoint will be accessible for anyone and `protected-openam` endpoint will be accessible for OpenAM authenticated users.

```java
@Controller
public class SampleController {
@GetMapping
public String index() {
return "index";
}
@GetMapping("/protected-openam")
public String cookieProtected(Model model, @AuthenticationPrincipal String principal) {
model.addAttribute("userName", principal);
model.addAttribute("method", "OpenAM Cookie");
return "protected";
}
}
```

Create the following templates for controllers:

`index.html`

```html
<!DOCTYPE html><html>
<body>
<h1>OpenAM Spring Security Integration</h1>
<h2>Test Authentication</h2>
<ul>
<li><a href="/protected-openam">OpenAM Cookie</a></li>
</ul>
</body>
</html>
```

`protected.html`

```html
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Protected resource</h1>
<a href="/">Back</a></li>
<p><span th:text="${userName}"/> user authenticated with <span th:text="${method}"/></p>
</body>
</html>
```

Create Spring Security configuration class:

```java
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityOpenAmFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher("/protected-openam", OpenAmAuthenticationFilter.OPENAM_AUTH_URI)
.addFilterAt(new OpenAmAuthenticationFilter(), RememberMeAuthenticationFilter.class)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().fullyAuthenticated())
.exceptionHandling(e ->
e.authenticationEntryPoint((request, response, authException) ->
response.sendRedirect(OpenAmAuthenticationFilter.OPENAM_AUTH_URI)));
return http.build();
}
}
```

Create OpenAM authentication filter:

```java
public class OpenAmAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private final String openAmUrl = "http://openam.example.org:8080/openam";
private final String openAuthUrl = openAmUrl.concat("/XUI/#login");
private final String openAmUserInfoUrl = openAmUrl.concat("/json/users?_action=idFromSession");
private final String openAmCookieName = "iPlanetDirectoryPro";
private final String redirectUrl = "http://app.example.org:8081/protected-openam";
public static final String OPENAM_AUTH_URI = "/openam-auth";
public OpenAmAuthenticationFilter() {
super(OPENAM_AUTH_URI, new OpenAmAuthenticationManager());
setSecurityContextRepository(new HttpSessionSecurityContextRepository());
}
private final AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
Optional<Cookie> openamCookie = Arrays.stream(request.getCookies())
.filter(c -> c.getName().equals(openAmCookieName)).findFirst();
if(openamCookie.isEmpty()) {
response.sendRedirect(openAuthUrl + "&goto=" + URLEncoder.encode(redirectUrl, StandardCharsets.UTF_8));
return null;
} else {
String userId = getUserIdFromSession(openamCookie.get().getValue());
if (userId == null) {
throw new BadCredentialsException("invalid session!");
}
OpenAmAuthenticationToken token = new OpenAmAuthenticationToken(userId);
token.setDetails(authenticationDetailsSource.buildDetails(request));
return this.getAuthenticationManager().authenticate(token);
}
}
protected String getUserIdFromSession(String sessionId) {
RestTemplate restTemplate = new RestTemplate();
ParameterizedTypeReference<Map<String, String>> responseType =
new ParameterizedTypeReference<>() {};
HttpHeaders headers = new HttpHeaders();
headers.add(openAmCookieName, sessionId);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<?> entity = new HttpEntity<>(headers);
ResponseEntity<Map<String, String>> response = restTemplate.exchange(openAmUserInfoUrl, HttpMethod.POST, entity, responseType);
Map<String, String> body = response.getBody();
if (body == null) {
return null;
}
return body.get("id");
}
}
```

Create OpenAM authentication manager

```java
public class OpenAmAuthenticationManager implements AuthenticationManager {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if(authentication instanceof OpenAmAuthenticationToken) {
authentication.setAuthenticated(true);
return authentication;
}
authentication.setAuthenticated(false);
return authentication;
}
}
```

and OpenAM authentication token class:

```java
public class OpenAmAuthenticationToken extends AbstractAuthenticationToken {
private final String username;
public OpenAmAuthenticationToken(String username) {
super(Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")));
this.username = username;
}
@Override
public Object getCredentials() {
return "";
}
@Override
public Object getPrincipal() {
return username;
}
}
```

# Test Solution

Create the `demo` user for the top level realm for testing purposes. Open OpenAM console, open the top level realm. In the left menu click the `Subjects` element. In the list of subject click the `New` button.

![OpenAM Create User](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-cookie/openam-create-user.png)

Fill the attributes and press the `OK` button.

Logout form OpenAM.

Run the Spring application an open its URL in a browser: [http://app.example.org:8081](http://test.example.org:8081).

![Test App Index](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-cookie/test-app-index.png)

Click the OpenAM Cookie link. You will be redirected to the OpenAM authentication page.

![OpenAM Authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-cookie/openam-authentication.png)

Enter desired credentials and press the Log In button. After successful authentication you will be redirected to the Spring Boot application page as an authenticated user.

![Test App Authenticated](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-cookie/test-app-authenticated.png)

PS. Thanks to [https://www.tune-it.ru/web/adpashnin/blog/-/blogs/spring-security-i-openam](https://www.tune-it.ru/web/adpashnin/blog/-/blogs/spring-security-i-openam) for the idea for this manual.
**[Test Solution](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-openam-cookie#openam-and-spring-boot-3-integration-via-openam-cookie-test-solution)**
211 changes: 29 additions & 182 deletions OpenAM-and-Spring-Boot-3-Integration-via-SAMLv2-Protocol.md
Original file line number Diff line number Diff line change
@@ -1,190 +1,37 @@
# Introduction
This article has moved to the Open Identity Platform documentation site:

In the following article, we will set up OpenAM as an Identity Provider for a Spring Boot Application. In the [previous article,](https://github.com/OpenIdentityPlatform/OpenAM/wiki/OpenAM-and-Spring-Boot-3-Integration-via-OIDC-OAuth2-Protocol) we set up a Spring Boot application authentication via OpenAM with OAuth2/OIDC protocol. In the following article, we will set up authentication via OpenAM as an Identity Provider and Spring Boot application as a service provider using [SAMLv2](https://en.wikipedia.org/wiki/SAML_2.0) protocol.
[OpenAM and Spring Boot 3 Integration via SAMLv2 Protocol](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol).

# OpenAM Configuration
Please use the documentation site for the current version.

## Create Hosted Identity Provider
<a name="introduction"></a>

If you have not installed OpenAM yet, you could run OpenAM as a [Docker image](https://hub.docker.com/r/openidentityplatform/openam/). Let’s assume the OpenAM instance URL is `http://openam.example.org:8080/openam`
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-introduction)**

Go to the target realm and in the Common Tasks section. Open OpenAM console in a browser and press the Configure SAMLv2 Provider button.

![Realm Common Tasks](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-saml/realm-common-tasks.png)

Then press the Create Hosted Identity Provider button.

![Realm Create Hosted Identity Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-saml/realm-create-hosted-idp.png)

Select a Signing Key (for demonstration purposes we will use **test**), enter the Circle of Trust name, and then map user's attributes to OpenAM. For demonstration the OpenAM users will be mapped by email.

![Hosted Identity Provider Configuration](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-saml/hosted-idp-conf.png)
<a name="openam-configuration"></a>

Press the Configure button.

## **Setup User Mapping in OpenAM**

Open the administration console, goto desired realm, from the menu on the left. Select the applications section and navigate to SAML 2.0. In the Entity Providers list select `http://openam.example.org:8080/openam` On the Assertion Content tab, under **NameID Format** in the **NameID Value Map** list, add the element `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified=mail` Press the Save button.

## Create OpenAM Users

Open the administration console, goto desired realm, create a new user and fill the Email Address attribute

# Spring Application Configuration

Create a new Spring Boot application and add the following Maven repositories and dependencies:

```xml
<repositories>
<repository>
<id>releases</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
<repository>
<id>shibboleth</id>
<url>https://build.shibboleth.net/nexus/content/repositories/releases/</url>
</repository>
</repositories>
....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--security dependencies-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-saml2-service-provider</artifactId>
</dependency>
```

Generate certificate and key files with the OpenSSL tool.

```bash
openssl req -newkey rsa:2048 -nodes -keyout rp-private.key -x509 -days 365 -out rp-certificate.crt
```

Put the generated files into `src/main/resources/credentials` directory.

Add the following settings to the `application.yml` file

```yaml
server:
port: 8081
spring:
security:
saml2:
relyingparty:
registration:
openam:
signing:
credentials:
- private-key-location: classpath:credentials/rp-private.key
certificate-location: classpath:credentials/rp-certificate.crt
singlelogout:
binding: POST
url: "{baseUrl}/logout/saml2/slo"
assertingparty:
metadata-uri: http://openam.example.org:8080/openam/saml2/jsp/exportmetadata.jsp
```
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-openam-configuration)**

Create a controller and two endpoints: `index` and `protected-saml`. The `index` endpoint will be accessible for anyone and `protected-saml` endpoint will be accessible for authenticated with OpenAM users via SAMLv2 protocol.
<a name="create-hosted-identity-provider"></a>

```java
@Controller
public class SampleController {
@GetMapping
public String index() {
return "index";
}
@GetMapping("/protected-saml")
public String samlProtected(Model model, @AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) {
String emailAddress = principal.getFirstAttribute("email");
model.addAttribute("userName", emailAddress);
model.addAttribute("method", "SAMLv2");
return "protected";
}
}
```

Create the following templates for controllers:

`index.html`

```html
<!DOCTYPE html><html>
<body>
<h1>OpenAM Spring Security Integration</h1>
<h2>Test Authentication</h2>
<ul>
<li><a href="/protected-saml">SAMLv2</li>
</ul>
</body>
</html>
```

`protected.html`

```html
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Protected resource</h1>
<a href="/">Back</a></li>
<p><span th:text="${userName}"/> user authenticated with <span th:text="${method}"/></p>
</body>
</html>
```

Create Spring Security configuration

```java
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securitySamlFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> authorize.requestMatchers("/")
.permitAll()
.requestMatchers("/protected-saml").authenticated())
.saml2Metadata(Customizer.withDefaults())
.saml2Login(Customizer.withDefaults())
.saml2Logout(Customizer.withDefaults());
return http.build();
}
}
```

# Setup Service Provider in OpenAM

Run the Spring Boot Project to import the SAML metadata file of the Spring Boot project.

Open the OpenAM administration console, goto desired realm, click **Configure SAMLv2 Provider** in the Common Tasks section, then click **Configure Remote Service Provider.**

Set the metadata URL: `http://localhost:8081/saml2/service-provider-metadata/openam` and select the existing circle of trust created in the Create Hosted Identity Provider Step.

![Remote Service Provider Config](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-saml/remote-sp-conf.png)

# Test the Solution

Logout form OpenAM if you are logged in.

Run the Spring application an open its URL in a browser: [http://localhost:8081](http://localhost:8081/)

![Test App Index](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-saml/test-app.png)

Enter the user’s login and password and then press the LOG IN button.

![OpenAM Authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-saml/openam-authentication.png)

After pressing the Log In button, you will be redirected to the Spring Security Application as an authenticated user.

![Test App Authenticated](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spring-boot-saml/test-app-authenticated.png)
**[Create Hosted Identity Provider](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-create-hosted-identity-provider)**

<a name="setup-user-mapping-in-openam"></a>

**[Setup User Mapping in OpenAM](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-setup-user-mapping-in-openam)**

<a name="create-openam-users"></a>

**[Create OpenAM Users](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-create-openam-users)**

<a name="spring-application-configuration"></a>

**[Spring Application Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-spring-application-configuration)**

<a name="setup-service-provider-in-openam"></a>

**[Setup Service Provider in OpenAM](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-setup-service-provider-in-openam)**

<a name="test-the-solution"></a>

**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/openam-and-spring-boot-3-integration-via-samlv2-protocol#openam-and-spring-boot-3-integration-via-samlv2-protocol-test-the-solution)**
520 changes: 35 additions & 485 deletions OpenAM-and-Zero-Trust:-Confirming-Critical-Operations.md
Original file line number Diff line number Diff line change
@@ -1,519 +1,69 @@
## Introduction
This article has moved to the Open Identity Platform documentation site:

One of the principles of Zero Trust states: *Never trust, always verify*. In this article, we will explore how to implement this principle in an authentication system using open-source products [OpenAM](https://github.com/OpenIdentityPlatform/OpenAM) and [OpenIG](https://github.com/OpenIdentityPlatform/OpenIG).
[OpenAM and Zero Trust: Confirming Critical Operations](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations).

A practical example of this principle can be seen in banking applications. When confirming a payment, banks almost always want to ensure that it is *you* conducting the transaction, not a malicious actor. To verify this, they send a one-time code to a trusted device via push notification or SMS.
Please use the documentation site for the current version.

Alternatively, the user may be asked to confirm their biometric data, such as a fingerprint, use a hardware token, or rely on a specialized application like Microsoft Authenticator or Google Authenticator.
<a name="introduction"></a>

## Solution Design
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-introduction)**

The solution consists of three components:
<a name="solution-design"></a>

- **Protected Application**: Any application (in this case, a simple Node.js application) where users authenticate. It includes two pages: a profile page and a page with sensitive data.
- **Authentication Service (OpenAM)**: Handles user authentication and authorization.
- **Authorization Gateway (OpenIG)**: Sends a request to OpenAM to verify policy compliance. If successful, it grants access to the protected application; otherwise, it redirects the user for authentication. When attempting to access sensitive information, OpenAM will check whether the user has authenticated using a one-time code, ensuring no more than 20 seconds have passed since the last authentication.
**[Solution Design](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-solution-design)**

As a second authentication factor, one-time passwords generated using the [TOTP algorithm](https://en.wikipedia.org/wiki/Time-based_one-time_password) will be used, along with mobile applications like [Microsoft Authenticator](https://support.microsoft.com/en-us/account-billing/download-microsoft-authenticator-351498fc-850a-45da-b7b6-27e523b8702a) or [Google Authenticator](https://support.google.com/accounts/answer/1066447).
<a name="preparation"></a>

## Preparation
**[Preparation](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-preparation)**

The complete solution code is available at this link: [https://github.com/OpenIdentityPlatform/openam-openig-otp-example](https://github.com/OpenIdentityPlatform/openam-openig-otp-example).
<a name="preparing-the-hosts-file"></a>

### Preparing the Hosts File
**[Preparing the Hosts File](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-preparing-the-hosts-file)**

Let’s assume the hostname for the authentication service will be `openam.example.org` and for the gateway `openig.example.org`. Before running the setup, add these hostnames and IP addresses to the `hosts` file, for example:
`127.0.0.1 openam.example.org openig.example.org`
<a name="authenticator-application"></a>

- On **Windows**, the `hosts` file is located at: `C:\Windows\System32\drivers\etc\hosts`
- On **Linux** and **Mac**, it is located at: `/etc/hosts`
**[Authenticator Application](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-authenticator-application)**

### Authenticator Application
<a name="docker-compose"></a>

Install the mobile application [Microsoft Authenticator](https://support.microsoft.com/en-us/account-billing/download-microsoft-authenticator-351498fc-850a-45da-b7b6-27e523b8702a) or [Google Authenticator](https://support.google.com/accounts/answer/1066447) on your device.
**[Docker Compose](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-docker-compose)**

### Docker Compose
<a name="demo-application"></a>

For simplicity, all services will be launched using `docker compose`.
**[Demo Application](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-demo-application)**

Create an empty file named `docker-compose.yml` and add the `services` object:
<a name="openam-authentication-service-configuration"></a>

```yaml
services:
```
**[OpenAM Authentication Service Configuration](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-openam-authentication-service-configuration)**

## Demo Application
<a name="configuring-mfa-in-openam"></a>

For demonstration purposes, we will use a simple Node.js application with two URLs:
- **Profile Page (`/`)** – Displays user profile information
- **Sensitive Data Page (`/sensitive`)** – Contains protected sensitive information
**[Configuring MFA in OpenAM](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-configuring-mfa-in-openam)**

The application code can be found at [this link](https://github.com/OpenIdentityPlatform/openam-openig-otp-example/tree/master/demo-app).
<a name="configuring-openam-authorization-policy"></a>

**[Configuring OpenAM Authorization Policy](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-configuring-openam-authorization-policy)**

```jsx
const express = require("express");
const app = express();
const port = 3000;
<a name="openam-user-setup"></a>

app.set("view engine", "ejs");
**[OpenAM User Setup](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-openam-user-setup)**

app.use((req, res, next) => {
console.log(req.headers)
const token = req.headers.authorization;
if (!token) {
return res.status(401).send("Unauthorized");
}
next()
})
<a name="configuring-authentication-token-conversion-to-jwt"></a>

app.get("/", (req, res) => {
const token = req.headers.authorization;
const jwtPayload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
const user = { name: jwtPayload.sub };
res.render("profile", { user });
});
**[Configuring Authentication Token Conversion to JWT](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-configuring-authentication-token-conversion-to-jwt)**

app.get("/sensitive", (req, res) => {
const sensitiveData = { bankAccount: "1234-5678-9012-3456", secretKey: "MY_SUPER_SECRET_KEY" };
res.render("sensitive", { sensitiveData });
});
<a name="configure-the-openig-authorization-gateway"></a>

app.listen(port, () => console.log(`Server running at http://localhost:${port}`));
```
**[Configure the OpenIG authorization gateway](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-configure-the-openig-authorization-gateway)**

Add a demo application to the `docker-compose.yml` file in the `services` object
<a name="general-settings"></a>

```yaml
services:
demo-app:
build: ./demo-app
container_name: demo-app
```
**[General Settings](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-general-settings)**

Run the application with the command `docker compose up -d --build demo-app`
<a name="configure-routes-to-the-demo-application"></a>

## OpenAM Authentication Service Configuration
**[Configure Routes to the Demo Application](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-configure-routes-to-the-demo-application)**

Add the OpenAM seris to the `docker-compose.yml` file in the `services` object:
<a name="test-the-solution"></a>

```yaml
services:
...
openam:
image: openidentityplatform/openam:latest
container_name: openam
hostname: openam.example.org
ports:
- "8080:8080"
```

Start the OpenAM container with the command `docker compose up openam`. Wait for the container to start and perform the initial installation with the command:

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```

Wait until the installation is complete.


### Configuring MFA in OpenAM

Open the OpenAM administrator console at [http://openam.example.org:8080/openam](http://openam.example.org:8080/openam).

Enter the administrator login and password. In this case, it is `amadmin` and `passw0rd` respectively.

In the console, select **Top Level Realm**. In the left menu, select **Authentication** → **Modules** and create a new module `totp` with type `Authenticator (OATH)`.

![New TOTP Module.png](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/0-new-totp-module.png)

In the settings, select **OATH Algorithm to Use: TOTP**, also specify **Name of the Issuer**, e.g. **OpenAM**. The rest of the settings can be left unchanged. Save the `totp` module settings.

![TOTP module settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/1-totp-module-settings.png)

Next, let's configure the authentication chain

In the administrator console, open the Top Level Realm, then go to **Authentication** → **Chains** in the left menu and create a new authentication chain `totp`.

![New TOTP authentication chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/2-new-totp-chain.png)

Add the created `totp` module to the chain and save the changes.

![TOTP authentication chain settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/3-totp-chain-settings.png)

### Configuring OpenAM Authorization Policy

Now let's move on to configuring the authorization policy in OpenAM for the `/sensitive` endpoint of the demo application. The policy will be configured so that the user is required to authenticate with a one-time code in the `totp` authentication chain, but the authentication will only be valid for 20 seconds.

Open the OpenAM administrator console. Open Top Level Realm. From the menu on the left, select **Authorization** → **Policy Sets**. Select the **Default Policy Set**. Create a new `demo-sensitive` policy.

Select URL as the resource type and specify the resource as shown in the example in the figure below. Click **Add** and then **Create**.

![OpenAM new policy](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/4-new-policy.png)

For the created policy, on the Resources tab, allow GET and POST requests.

![Policy Actions](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/5-policy-actions.png)

On the Subjects tab, add the Authenticated Users type.

![Policy Subjects](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/6-policy-subjects.png)

On the Environments tab, add the Authentication by Module Chain condition and add the `totp` chain.

![Policy Environments](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/7-policy-environments.png)

Save the changes. This policy will authorize requests authenticated by the `totp` chain.

Now configure the policy so that access is only valid for 20 seconds. OpenAM doesn't have such a policy out of the box, so we'll configure a policy script. But first let's prepare OpenAM to work with the time from the script. In the top menu, go to Configure → Global Services. In the list that opens, select Scripting. Click the Secondary Configuration tab.

![Configure Scripting](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/8-configure-scripting.png)

Open the `POLICY_CONDITION` configuration. On the Secondary Configurations tab, select EngineConfiguration.

![Scripting Policy Condition](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/9-scripting-policy-condition.png)

In the **Java class whitelist**, add `java.time.*` to allow Groovy scripts to work with time and date.

Save the changes. From the console's top menu, select Realms → Top Level Realm and select Scripts from the menu on the left. Create a new script Auth Time Policy Condition.

![New Script](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/10-new-script.png)

Script type - POLICY_CONDITION. Language - Groovy.

![Auth Time Policy Condition](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/11-auth-time-policy-condition.png)

```groovy
import java.time.Instant;
import java.time.temporal.ChronoUnit;
logger.warning("Session: " + session)
def authInstant = session.getProperty("authInstant")
logger.warning("Auth time expired at1: " + authInstant)
def instant = Instant.parse(authInstant)
def expired = instant.plus(20, ChronoUnit.SECONDS)
if (Instant.now().compareTo(expired) > 0) {
logger.warning("Auth time expired at: " + expired)
authorized = false
} else {
authorized = true
}
```

Save the policy changes.

Now let's configure the use of the script in the authorization policy. In the left menu, go to **Authorization** → **Policy Sets** → **Default Policy Set** → **demo-sensitive**.

On the Environments tab, add a condition with the Script type and the value Auth Time Policy Condition.

![Policy Script](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/12-policy-script.png)

Save the changes.

Now let's configure the use of MFA for the `demo` user. This account was created when OpenAM was installed.

### OpenAM User Setup

Log out of the admin console, or open a browser in Incognito mode and go to [http://openam.example.org:8080/openam/XUI/#login](http://openam.example.org:8080/openam/XUI/#login)

In the login and password fields, enter `demo` and `changeit` respectively. This will open the user profile.

Now, start the authentication process on the `totp` chain. For this, open the link [http://openam.example.org:8080/openam/XUI/#login/&service=totp&ForceAuth=true](http://openam.example.org:8080/openam/XUI/#login/&service=totp&ForceAuth=true)

A window will open asking you to register a new device

![OpenAM Register Device](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/13-openam-register-device.png)

Click **Register Device** to register the device.

A page with a QR code will be displayed.

![OpenAM QR Code](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/14-openam-qr-code.png)

Open the authenticator app on your mobile device and scan the issued QR code in it. Click the **Login Using Verification Code** button.

Enter the code from the mobile app and click **Submit**.

![OpenAM verification code](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/15-openam-verification-code.png)

`MFA` for user `demo` is configured

### Configuring Authentication Token Conversion to JWT

After successful authentication, OpenAM creates a session and writes the session ID, which is a random character set, in a cookie to the browser. We will configure OpenAM so that third-party applications, such as OpenIG, can exchange the authentication token to the JWT to make it easier for third-party applications to work with.

Open the OpenAM admin console as described earlier. Select **Top Level Realm**. From the menu on the left, select **STS**. In the list that opens, create a new **Rest STS** instance. Fill in the settings

| **Setting** | **Value** |
| --- | --- |
| Supported Token Transforms | OPENAM->OPENIDCONNECT;don't invalidate interim OpenAM session |
| Deployment Url Element | jwt |
| The id of the OpenID Connect Token Provider | [https://openam.example.org/openam](https://openam.example.org/openam) |
| Client secret | changeme |
| Confirm client secret | changeme |
| The audience for issued tokens | [https://openam.example.org/openam](https://openam.example.org/openam) |

Save the Rest STS instance conversion settings.

You can read more about installing and configuring OpenAM in the documentation: [https://doc.openidentityplatform.org/openam/](https://doc.openidentityplatform.org/openam/)

## Configure the OpenIG authorization gateway

Add the OpenIG service to the `docker-compose.yml` file

```yaml
services:
...
openig:
image: openidentityplatform/openig:latest
container_name: openig
hostname: openig.example.org
volumes:
- ./openig:/usr/local/openig-config:ro
environment:
CATALINA_OPTS: -Dopenig.base=/usr/local/openig-config -Ddemo.app=http://demo-app:3000 -Dopenam=http://openam.example.org:8080/openam
ports:
- "8081:8080"
```

Note the arguments in the `CATALINA_OPTS` environment variable:

- `openig.base` - the path to the OpenIG configuration files
- `demo.app` - URL of the demo application to which OpenIG will proxy the request
- `openam` - the OpenAM URL to which OpenIG will redirect the user to authenticate and receive the JWT.

### General Settings

Create a `openig-config` folder and in it another `config` folder. In the `config` folder, create an `admin.json` file with the following contents:

```json
{
"prefix": "openig",
"mode": "PRODUCTION"
}
```

In the same folder, create a `config.json` file.

```json
{
"heap": [
{
"name": "EndpointHandler",
"type": "DispatchHandler",
"config": {
"bindings": [
{
"handler": "ClientHandler",
"capture": "all",
"baseURI": "${system['demo.app']}"
}
]
}
}
],
"handler": {
"type": "Chain",
"config": {
"filters": [
{
"name": "STSFilter",
"type": "ConditionalFilter",
"config": {
"condition": "${empty contexts.sts.issuedToken and not empty request.cookies['iPlanetDirectoryPro'][0].value}",
"delegate": {
"type": "TokenTransformationFilter",
"config": {
"openamUri": "${system['openam']}",
"realm": "/",
"instance": "jwt",
"from": "OPENAM",
"to": "OPENIDCONNECT",
"idToken": "${request.cookies['iPlanetDirectoryPro'][0].value}"
}
}
}
},
{
"name": "AuthorizationHeaderFilter",
"type": "ConditionalFilter",
"config": {
"condition": "${not empty contexts.sts.issuedToken}",
"delegate": {
"type": "HeaderFilter",
"config": {
"messageType": "REQUEST",
"remove": [
"Authorization",
"JWT"
],
"add": {
"Authorization": [
"Bearer ${contexts.sts.issuedToken}"
]
}
}
}
}
},
{
"name": "AuthenticationRedirectionFilter",
"type": "ConditionEnforcementFilter",
"config": {
"condition": "${not empty contexts.sts.issuedToken}",
"failureHandler": {
"type": "StaticResponseHandler",
"config": {
"status": 302,
"reason": "Found",
"headers": {
"Content-Type": [
"application/json"
],
"Location": [
"${system['openam']}/XUI/#login&goto=${urlEncode(contexts.router.originalUri)}"
]
},
"entity": "{ \"Redirect\": \"${system['openam']}/XUI/#login&goto=${urlEncode(contexts.router.originalUri)}\"}"
}
}
}
}
],
"handler": {
"type": "Router",
"name": "_router",
"capture": "all"
}
}
}
}
```

The `config.json` file defines a filter chain for each request to the demo application:

- `STSFilter` - if the HTTP request contains a cookie from OpenAM, the filter gets a JWT from this cookie, which is written to the context for further use
- `AuthorizationHeaderFilter` - adds the JWT received from OpenAM to the request in the `Authorization` header for use in the protected application
- `AuthenticationRedirectionFilter` - if the JWT is not present in the request context, redirects the user to authenticate with OpenAM.

An `EndpointHandler` handler is defined in the `heap` object that proxies requests in OpenIG to the demo application.

### Configure Routes to the Demo Application

In the `config` folder, create a `routes` folder and add a `10-home.json` route


```json
{
"name": "${matches(request.uri.path, '^/$')}",
"condition": "${matches(request.uri.path, '^/$')}",
"monitor": true,
"timer": true,
"handler": {
"type": "Chain",
"config": {
"filters": [],
"handler": "EndpointHandler"
}
},
"heap": [
]
}
```

The route simply proxies requests to the demo application using the `EndpointHandler` defined in the `config.json` configuration file.

We will add the route to a URL with sensitive information of the demo application. We will then configure a filter for the route so that it uses the authorization policy from OpenAM.

Add the `20-sensitive.json` route to the `routes` folder

```json
{
"name": "${matches(request.uri.path, '^/sensitive')}",
"condition": "${matches(request.uri.path, '^/sensitive')}",
"monitor": true,
"timer": true,
"handler": {
"type": "Chain",
"config": {
"filters": [
{
"name": "MFAPEPFilter",
"type": "PolicyEnforcementFilter",
"config": {
"openamUrl": "${system['openam']}",
"pepUsername": "amadmin",
"pepPassword": "ampassword",
"ssoTokenSubject": "${request.cookies['iPlanetDirectoryPro'][0].value}",
"failureHandler": {
"type": "StaticResponseHandler",
"config": {
"status": 403,
"headers": {
"Content-Type": [
"application/json"
]
},
"entity": "{ \"attributes\": \"${system['openam']}/XUI/#login&service=totp&ForceAuth=true&goto=${urlEncode(contexts.router.originalUri)}\"}"
}
}
},
"handler": "ClientHandler"
}
],
"handler": "EndpointHandler"
}
},
"heap": []
}
```

The route uses `MFAPEPFilter` to get the result of the authorization policy from OpenAM. And, if the policy check fails, redirects to authentication with a one-time code.

You can read more about installing and configuring OpenIG in the documentation: [https://doc.openidentityplatform.org/openig/](https://doc.openidentityplatform.org/openig/)

## Test the Solution

Start OpenIG with the `docker compose ui openig` command.

Log out of OpenAM if you are still authenticated.

Open the URL of the OpenIG protected demo application: [http://openig.example.org:8081/](http://openig.example.org:8081/). You will be redirected to authenticate to OpenAM. Enter the test user login and password: `demo` and `changeit`.

After authentication, you will be redirected to the main screen of the demo application


![Demo Profile Page](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/16-demo-profile-page.png)

Click the **Sensitive data** link. You will be redirected to additional authentication with a one-time code in OpenAM.

![TOTP Verification](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/17-totp-verification.png)

Enter the code from the authenticator application and click Submit. If successful, you will be redirected back to the page with sensitive data

![Demo Sensitive Page](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-otp-zts/18-demo-sensitive-page.png)

Wait 30 seconds and reload the page. You will be redirected to authentication with a one-time code again.
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/openam-and-zero-trust-confirming-critical-operations#openam-and-zero-trust-confirming-critical-operations-test-the-solution)**
181 changes: 49 additions & 132 deletions OpenAM-vs-Keycloak.md
Original file line number Diff line number Diff line change
@@ -1,132 +1,49 @@
## General Information

| | **OpenAM** | **Keycloak** |
| --- | --- | --- |
| Initial release | 2008 | 2014 |
| Maintainer | Open Identity Platform Community | Red Hat |
| Current version | 16.0.4 | 26.4.7 |
| Release and patches | Regular | Regular |
| Open Source | ✅ | ✅ |
| Programming Language | Java | Java |
| Supported Java version | 11+ LTS | 17+ LTS |
| License | CDDL | Apache License 2.0 |
| Multiple languages supported | ✅ | ✅ |

## Single Sign On (SSO) and Federation

| | OpenAM | Keycloak |
| --- | --- | --- |
| Applications deployment behind an auth gateway | ✅ [doc](https://doc.openidentityplatform.org/openam/deployment-planning/chap-topologies#logical-topology) | ✅ [doc](https://www.krakend.io/docs/authorization/keycloak/) |
| API gateway control | ✅ [doc](https://github.com/OpenIdentityPlatform/OpenAM/wiki/How-to-Add-Authorization-and-Protect-Your-Application-With-OpenAM-and-OpenIG-Stack) | ⛔️ |
| Apache Web Server Policy Agent | ✅ [doc](https://doc.openidentityplatform.org/openam/web-users-guide/chap-apache) | ⛔️ |
| IIS Policy Agent | ✅ [doc](https://doc.openidentityplatform.org/openam/web-users-guide/chap-msiis-7) | ⛔️ |
| J2EE Policy Agent (for Tomcat, Jetty, etc) | ✅ [doc](https://doc.openidentityplatform.org/openam/jee-users-guide/) | ⛔️ |
| OAuth 2.0/OIDC federation | ✅ [Google example](https://www.keycloak.org/docs/latest/server_admin/index.html#_github)| ✅ [GitHub example](https://www.keycloak.org/docs/latest/server_admin/index.html#_github) |
| SAMLv2 federation | ✅ [WordPress example](https://github.com/OpenIdentityPlatform/OpenAM/wiki/SAML-Authentication-in-WordPress-via-OpenAM)| ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_github) |

### Authentication

Supported authentication methods:

| **Authentication method** | **OpenAM** | **Keycloak** |
| --- | --- | --- |
| Login and password authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#data-store-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_authentication-flows) |
| Microsoft Active Directory authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#active-directory-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_user-storage-federation) |
| Authentication for demo access | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#anonymous-module-ref) | ⛔️ |
| Adaptive authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#adaptive-risk--module-ref) | ⛔️ |
| Authentication in an LDAPv3-compatible directory | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#ldap-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_user-storage-federation) |
| Persistent cookie authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#persistent-cookie-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#enabling-remember-me) |
| RDBMS authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#jdbc-module-ref) | ✅ [doc](https://www.keycloak.org/server/db) |
| Self-registration | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#membership-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#con-user-registration_server_administration_guide) |
| HTTP Header enrichment authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#msisdn-module-ref) | ⛔️ |
| Windows NT authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#windows-nt-module-ref) | ⛔️ |
| OAuth 2.0/OIDC authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#oauth-2) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#con-oidc_server_administration_guide) |
| Kerberos authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#windows-desktop-sso-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_kerberos) |
| OIDC id_token authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#openid-connect-id_token-bearer-module-ref) | ⛔️ |
| RADIUS authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#radius-module-ref) | ⛔️ |
| HOTP via SMS or email | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#hotp-module-ref) | ⛔️ |
| One time password with HOTP or TOTP authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#oath-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#one-time-password-otp-policies) |
| Custom scripted authentication provider | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#scripted-module-module-ref) | ⛔️ |
| SAMLv2 authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#saml2-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_saml) |
| ReCaptcha | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#recaptcha-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#proc-enabling-recaptcha_server_administration_guide) |
| QR-code authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#qr-code-confirm-from-other-session-module-ref) | ⛔️ |
| NTLM authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#ntlm-module-ref) | ⛔️ |
| Docker HTTP Basic Authentication | ⛔️ | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#docker-authentication-flow) |
| HTTP Basic Authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#http-basic-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#docker-authentication-flow) |
| Recovery codes authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/admin-guide/chap-auth-services#authn-mfa-accessing-recovery-codes) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_recovery-codes) |
| WebAuthn | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#webauthn-registration-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#webauthn_server_administration_guide) |
| X509 certificate authentication | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-auth-modules#certificate-module-ref) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_x509) |
| Custom authentication provider| ✅ [doc](https://doc.openidentityplatform.org/openam/dev-guide/chap-customizing#sec-auth-spi) | ✅ [doc](https://www.keycloak.org/docs/latest/server_development/index.html#implementing-an-authenticator) |


## Isolation (realms)

Realm support for isolation of identities and authentication processes

| | **OpenAM** | **Keycloak** |
| --- | --- | --- |
| Realms support | ✅ [doc](https://doc.openidentityplatform.org/openam/admin-guide/chap-realms) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#_configuring-realms) |
| Realm hierarchy | ✅ | ⛔️ |

## Interfaces

| **Interface** | **OpenAM** | **Keycloak** |
| --- | --- | --- |
| Administrator GUI | ✅ | ✅ |
| Admin REST API | ✅ | ✅ |
| Admin UI customization | ⛔️ | ✅ [doc](https://www.keycloak.org/ui-customization/creating-your-own-console) |
| Authentication GUI | ✅ | ✅ |
| Authentication GUI customization | ✅ [doc](https://doc.openidentityplatform.org/openam/install-guide/chap-custom-ui) | ✅ [doc](https://www.keycloak.org/guides#ui-customization) |
| Authentication REST API | ✅ [doc](https://doc.openidentityplatform.org/openam/dev-guide/chap-client-dev#sec-rest) | ⛔️ |
| Authentication XML-RPC API | ✅ [doc](https://doc.openidentityplatform.org/openam/dev-guide/chap-client-dev#sec-sdk) | ⛔️ |

## Authentication Sessions

| | **OpenAM** | **Keycloak** |
| --- | --- | --- |
| [Stateful][1] | Random session ID | JWT |
| [Stateless][1] | JWT | JWT |
| REST Security Token Service | ✅  | ✅ |
| SOAP Security Token Service | ✅  | ⛔️ |

[1]:https://github.com/OpenIdentityPlatform/OpenAM/wiki/Stateful-vs-Stateless-Authentication


## Identity Repositories

| Repository type | **OpenAM** | **Keycloak** |
| --- | --- | --- |
| LDAP (OpenDJ, OpenLDAP, etc.) | ✅  | ✅  |
| Active Directory | ✅  | ✅  |
| Apache Cassandra | ✅  | ⛔️ |
| MariaDB Server | ✅ | ✅ |
| Microsoft SQL Server | ✅ | ✅ |
| MySQL | ✅  | ✅ |
| Oracle Database | ✅  | ✅ |
| PostgreSQL | ✅  | ✅ |
| Flat file | ✅  | ⛔️ |
| Custom identity repository | ✅ [doc](https://doc.openidentityplatform.org/openam/dev-guide/chap-customizing#sec-identity-repo-spi)  | ✅ [doc](https://www.keycloak.org/docs/latest/server_development/index.html#_user-storage-spi) |


## Audit logging and Monitoring

| | **OpenAM** | **Keycloak** |
| --- | --- | --- |
| Audit Logging | ✅ [doc](https://doc.openidentityplatform.org/openam/reference/chap-audit-log-messages) | ✅ [doc](https://www.keycloak.org/docs/latest/server_admin/index.html#configuring-auditing-to-track-events) |
| HTTP-based Monitoring| ✅ [doc](https://doc.openidentityplatform.org/openam/admin-guide/chap-monitoring#monitoring-web-pages) | ✅ [doc](https://www.keycloak.org/server/management-interface) |
| SNMP Monitoring | ✅ [doc](https://doc.openidentityplatform.org/openam/admin-guide/chap-monitoring#monitoring-snmp) | ⛔️ |
| JMX Monitoring | ✅ [doc](https://doc.openidentityplatform.org/openam/admin-guide/chap-monitoring#monitoring-jmx) | ⛔️ |

## Useful Links

### OpenAM:

- [Official website](https://www.openidentityplatform.org/openam)
- [GitHub repository](https://github.com/OpenIdentityPlatform/OpenAM)
- [Documentation](https://doc.openidentityplatform.org/openam/)

### Keycloak:

- [Official website](https://www.keycloak.org/)
- [GitHub repository](https://github.com/keycloak/keycloak)
- [Documentation](https://www.keycloak.org/documentation)
This article has moved to the Open Identity Platform documentation site:

[OpenAM vs Keycloak](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak).

Please use the documentation site for the current version.

<a name="general-information"></a>

**[General Information](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-general-information)**

<a name="single-sign-on-sso-and-federation"></a>

**[Single Sign On (SSO) and Federation](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-single-sign-on-sso-and-federation)**

<a name="authentication"></a>

**[Authentication](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-authentication)**

<a name="isolation-realms"></a>

**[Isolation (realms)](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-isolation-realms)**

<a name="interfaces"></a>

**[Interfaces](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-interfaces)**

<a name="authentication-sessions"></a>

**[Authentication Sessions](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-authentication-sessions)**

<a name="identity-repositories"></a>

**[Identity Repositories](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-identity-repositories)**

<a name="audit-logging-and-monitoring"></a>

**[Audit logging and Monitoring](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-audit-logging-and-monitoring)**

<a name="useful-links"></a>

**[Useful Links](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-useful-links)**

<a name="openam"></a>

**[OpenAM:](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-openam)**

<a name="keycloak"></a>

**[Keycloak:](https://doc.openidentityplatform.org/openam/how-to/openam-vs-keycloak#openam-vs-keycloak-keycloak)**
101 changes: 23 additions & 78 deletions Passwordless-Authenticaion-Methods.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,45 @@
- [Intro](#intro)
- [Passwordless Authenticaion Methods](#passwordless-authenticaion-methods)
- [Conclusion](#conclusion)
This article has moved to the Open Identity Platform documentation site:

# Intro
Nowadays, people use more and more different online services in everyday life, and each service requires authentication. So, for each service, you need to remember your username and password. And, even the login for each service can be the same (for example, the email), then the password must be unique for each service. It is much better to have a complex password, i.e: have a length of 8 characters and more, contain uppercase and lowercase letters, numbers, and special characters.
[Passwordless Authentication Methods](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods).

Of course, it is impossible to remember the complex password for each service, so users either use simple passwords or use the same password for each service. Some users even write their own passwords on a piece of paper and put it under the keyboard (sic!). Of course, it compromises user accounts.
Please use the documentation site for the current version.

Passwordless authentication could solve this problem. In the following article, I will try to consider main passwordless authentication methods, as well as their advantages and disadvantages.
<a name="intro"></a>

There are the following passwordless authentication methods:
**[Intro](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-intro)**

* One-time link sent to the e-mail
* One-time password sent by SMS or Push-notification
* HOTP and TOTP (HMAC and Time-based one-time password)
* Persistent Cookie
* Third-party Identity provider (for example, log in via Facebook or via Google)
* USB token device
* Mobile application with biometric authentication.
<a name="passwordless-authenticaion-methods"></a>

# Passwordless Authenticaion Methods
**[Passwordless Authenticaion Methods](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-passwordless-authenticaion-methods)**

## One-time Authentication Link Sent to the E-mail
<a name="one-time-authentication-link-sent-to-the-e-mail"></a>

During authentication, the user enters his email, the service generates a one-time link and sends it to the specified email. Then the user must open the mail application, receive an email from the service, and follow the link.
**[One-time Authentication Link Sent to the E-mail](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-one-time-authentication-link-sent-to-the-e-mail)**

Pros:
* Low cost - sending e-mail is almost free
<a name="one-time-password-via-sms-or-push"></a>

Cons:
* The need for the user to open an additional email client application
* If the attacker has access to the user's e-mail, then authentication can be compromised.
* There is a risk of receiving an email with a phishing link to enter a malicious resource
**[One-time password via SMS or Push](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-one-time-password-via-sms-or-push)**

## One-time password via SMS or Push
The most widely used passwordless authentication method. During authentication, the user enters his phone number, then he receives an SMS or pushes notification with a one-time confirmation code, which has a limited validity period. The user enters the received one-time code in the service and authenticates.
<a name="hmac-and-time-based-one-time-password"></a>

Pros:
* Relative reliability - to fake a SIM card or steal a phone seems to be a rather non-trivial task for an attacker. In addition, the mobile phone can determine the location of the attacker.
**[HMAC and Time-based one-time password](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-hmac-and-time-based-one-time-password)**

Cons:
* Users must manually enter the code from an SMS, every time they authenticate, which can be annoying.
* For receiving a push notification users should install a mobile application.
<a name="persistent-cookie"></a>

## HMAC and Time-based one-time password
HMAC-based one-time password (HOTP) is generating a one-time password algorithm based on authentication attempts and a shared secret between user server and client. A time-based one-time password - is an improvement of HOTP and generates passwords based on system time. These algorithms generate passwords on both a server and a client each time user authenticates the system.
**[Persistent Cookie](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-persistent-cookie)**

Pros:
* You can use third-party trusted software to implement this algorithm (for example Google authenticator)
<a name="using-third-party-identity-provides-via-social-networks"></a>

Cons:
* For TOTP there is a need to synchronize time between server and client
* The shared secret can be stolen and attackers can generate their own TOTP values to authenticate
**[Using third-party Identity Provides (via Social Networks)](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-using-third-party-identity-provides-via-social-networks)**

## Persistent Cookie
<a name="usb-token-device"></a>

One of the simplest and widely used way to authenticate without a password. After authentication, a special cookie is set in the user's browser, which is then used to authenticate the user.
**[USB Token Device](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-usb-token-device)**

Pros:
* Further authentications do not require entering any data from the user
<a name="mobile-phone-biometrics"></a>

Cons:
* Works on a single device (browser)
* If an attacker steals an users cookie, he could gain access to the user's account
* The cookie should expire. When the cookie expires, the user should authenticate again.
**[Mobile Phone Biometrics](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-mobile-phone-biometrics)**

## Using third-party Identity Provides (via Social Networks)
During authentication, the user is prompted to authenticate using an existing account of a third-party Identity Provider (Google, Facebook, LinkedIn)
<a name="conclusion"></a>

Pros:
* Very easy to use, if the user has already authenticated to the identity provider.

Cons:
* If the user lost his Identity Provider account, access to the service can also be lost.
* Users may not have profiles in the Identity Providers list supported by the service.

## USB Token Device
Users can be authenticated using a USB token device. There is a cryptographic key, that uniquely identifies the device holder.

Pros:
* High security - it is almost not possible to forge the token

Cons:
* The user need to carry an extra device
* Sometimes, there is a need to install special software to authenticate
* The token device can be lost or stolen

## Mobile Phone Biometrics
While authenticating, the user receives notifications on his mobile phone application, asking for confirmation via fingerprint, face recognition, and so on.

Pros:
* High security, because mobile phone manufacturers are focusing on mobile phone security and protecting them from unauthorized access.
* Almost everyone has a mobile phone

Cons:
* User need to install and setup additional application on his phone

# Conclusion
All of the methods above have advantages and disadvantages. But for better user experience, is the usage of a combination of several methods. For example, to provide the ability to authenticate using OAuth or OpenID and a saved cookie. Also, a promising and secure approach is authentication using mobile phone biometrics, such as fingerprint or face recognition authentication.
**[Conclusion](https://doc.openidentityplatform.org/openam/how-to/passwordless-authentication-methods#passwordless-authentication-methods-conclusion)**
88 changes: 27 additions & 61 deletions Persistent-Cookie-module.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,51 @@
Тhe [[Persistent Cookie module]] supports the configuration of cookie lifetimes based on requests and a maximum time. Note that by default, the persistent cookie is called **session-jwt**.
This article has moved to the Open Identity Platform documentation site:

> If Secure Cookie is enabled [[Configuration]] > [[Servers and Sites]] > [[Default Server Settings]] > **Security** > **Cookie**, the [[Persistent Cookie module]] only works over HTTPS.
>
>![Configuration > Servers and Sites > Default Server Settings > Security > Cookie](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/Configuration-Servers%20and%20Sites-Default%20Server%20Settings-Security-Cookie.png)
[Persistent Cookie module](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module).

Before you begin, make sure a public key alias is defined in AM. The [[Persistent Cookie module]] encrypts a [[JSON Web Token (JWT)]] using a public key from the AM keystore. The keystore must be configured under [[Realms]] > **Realm Name** > [[Authentication]] > [[All Core Settings]] > [[Security]] > **Persistent Cookie Encryption Certificate Alias**. If the keystore changes and the default test key is no longer present, the public key alias must be updated to reflect the change, otherwise the module will fail. Similarly, in multi-instance deployments, the keypair must be available on all AM instances.
Please use the documentation site for the current version.

![Realms > Realm Name > Authentication > All Core Settings > Security](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/Realms-Realm%20Name-Authentication-All%20Core%20Settings-Security.png)
<a name="ssoadm-service-name-iplanetamauthpersistentcookieservice"></a>

To configure the [[Persistent Cookie module]] globally in the AM console, navigate to [[Configuration]] > [[Authentication]], and then click **Persistent Cookie**. In the window that appears you should see the following attributes:
**[
ssoadm service name: iPlanetAMAuthPersistentCookieService
](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-ssoadm-service-name-iplanetamauthpersistentcookieservice)**

![Module Instances > Persistent Cookie](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/Module%20Instances-Persistent%20Cookie.png)
<a name="idle-timeout"></a>

>For example, to generate an HMAC signing key, run the following:
>```sh
>openssl rand -base64 32
>```
>or
>```sh
>cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1|base64
>```
>Default: a random 256-bit secret key.
**[Idle Timeout](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-idle-timeout)**

When the [[Persistent Cookie module]] enforces the client IP address, and AM lies behind a load balancer or proxy layer, configure the load balancer or proxy to send the address by using the **X-Forwarded-For** header, and configure OpenAM to consume and forward the header as necessary. For details, see [[Handling HTTP Request Headers]] in the [[Installation Guide]].
<a name="max-life"></a>

The [[Persistent Cookie module]] belongs with a second module in an [[Authentication Chaining]]. To see how this works, navigate to [[Realms]] > **Realm Name** > [[Authentication]] > [[Authentication Chaining]]. Create a new chain and add modules as shown in the figure. The following example shows how a [[Persistent Cookie module]] is sufficient. If the persistent cookie does not yet exist, authentication relies on LDAP:
**[Max Life](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-max-life)**

![Module Instances > Persistent Cookie > Chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/Module%20Instances-Persistent%20Cookie-Chain.png)
<a name="enforce-client-ip"></a>

You should now be able to authenticate automatically, as long as the cookie exists for the associated domain.
**[Enforce Client IP](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-enforce-client-ip)**

## [[ssoadm]] service name: **iPlanetAMAuthPersistentCookieService**
<a name="use-secure-cookie"></a>

### Idle Timeout
Specifies the maximum idle time between requests in hours. If that time is exceeded, the cookie is no longer valid.
**[Use secure cookie](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-use-secure-cookie)**

[[ssoadm]] attribute: **openam-auth-persistent-cookie-idle-time**
<a name="use-http-only-cookie"></a>

### Max Life
Specifies the maximum life of the cookie in hours.
**[Use HTTP only cookie](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-use-http-only-cookie)**

[[ssoadm]] attribute: **openam-auth-persistent-cookie-max-life**
<a name="hmac-signing-key"></a>

### Enforce Client IP
When enabled, enforces that the persistent cookie can only be used from the same client IP to which the cookie was issued.
**[HMAC Signing Key](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-hmac-signing-key)**

[[ssoadm]] attribute: **openam-auth-persistent-cookie-enforce-ip**
<a name="check-box-name"></a>

### Use secure cookie
When enabled, adds the "Secure" attribute to the persistent cookie.
**[Check box name](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-check-box-name)**

[[ssoadm]] attribute: **openam-auth-persistent-cookie-secure-cookie**
<a name="repository-field"></a>

### Use HTTP only cookie
When enabled, adds the HttpOnly attribute to the persistent cookie.
**[Repository field](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-repository-field)**

[[ssoadm]] attribute: **openam-auth-persistent-cookie-http-only-cookie**
<a name="maximum-devices"></a>

### HMAC Signing Key
Specifies a key to use for HMAC signing of the persistent cookie. Values must be base64-encoded and at least 256 bits (32 bytes) long.
**[Maximum devices](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-maximum-devices)**

[[ssoadm]] attribute: **openam-auth-persistent-cookie-hmac-key**
<a name="cookie-name"></a>

### Check box name
The name of the check box, which means that the function is enabled by the user
[[ssoadm]] attribute: **openam-auth-persistent-cookie-input**
### Repository field
The name of the field in the repository in which the issued tokens are stored
[[ssoadm]] attribute: **openam-auth-persistent-cookie-field**
### Maximum devices
Maximum number of tokens (devices) per user
[[ssoadm]] attribute: **openam-auth-persistent-cookie-field-max**
### Cookie name
default session-jwt
[[ssoadm]] attribute: **openam-auth-persistent-cookie-name**
other [[Authentication modules]]
**[Cookie name](https://doc.openidentityplatform.org/openam/how-to/persistent-cookie-module#persistent-cookie-module-cookie-name)**
154 changes: 23 additions & 131 deletions Quick-Start-Guide.md
Original file line number Diff line number Diff line change
@@ -1,153 +1,45 @@
OpenAM Getting Started
>https://doc.openidentityplatform.org/openam/getting-started/ ([pdf](https://github.com/OpenIdentityPlatform/OpenAM/wiki/asciidoc/pdf/Getting_Started_With_OpenAM.pdf))
This article has moved to the Open Identity Platform documentation site:

OpenAM 13.5 Getting Started
>https://github.com/OpenIdentityPlatform/OpenAM/wiki/old/OpenAM-13.5-Getting-Started.pdf
[Quick Start Guide](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide).

## Preparations
### Install Docker
Install Docker for your platform, if you did not do this before, from https://docs.docker.com/install/#supported-platforms.
Please use the documentation site for the current version.

### Prepare Hosts File
<a name="preparations"></a>

First, you need to add to your _hosts_ file the local IP and FQDN mappings.
_openam.example.org_ - for OpenAm and _example.org_ for Apache Http Server.
Your hosts file should contain the following line:
**[Preparations](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-preparations)**

```bash
127.0.0.1 openam.example.org example.org
```
To add the above line to the hosts file on Windows:
1. Press the Windows key.
2. Type Notepad in the search field.
3. In the search results, right-click Notepad and select Run as administrator.
4. From Notepad, open the following file: c:\Windows\System32\Drivers\etc\hosts.
5. Make the necessary changes to the file.
6. Select File > Save to save your changes
<a name="install-docker"></a>

**[Install Docker](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-install-docker)**

## OpenAM Configuration
<a name="prepare-hosts-file"></a>

### Running OpenAM Image
**[Prepare Hosts File](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-prepare-hosts-file)**

Create Docker network for OpenAM
```bash
docker network create openam-quickstart
```
<a name="openam-configuration"></a>

Run OpenAM image
```bash
docker run -h openam.example.org -p 8080:8080 --network openam-quickstart --name openam openidentityplatform/openam
```
Change the name in the above command if you run into errors saying the container is already in use.
**[OpenAM Configuration](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-openam-configuration)**

### Basic OpenAM Setup
Open your browser, goto url http://openam.example.org:8080/openam.
![OpenAM Configuration Start](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-conf-start.png)
<a name="running-openam-image"></a>

Click __Create Default Configuration__.
**[Running OpenAM Image](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-running-openam-image)**

![OpenAM License Agreement](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-conf-license.png)
<a name="basic-openam-setup"></a>

Accept License Agreement
**[Basic OpenAM Setup](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-basic-openam-setup)**

![OpenAM Set Passwords](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-conf-passwords.png)
<a name="policy-configuration"></a>

Set password for default admin user and policy agent
**[Policy Configuration](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-policy-configuration)**

Press __Create Configuration__.
After configuration successfully created, press __Proceed to Login__ or open http://openam.example.com:8080/openam/console link in browser.
<a name="agent-configuration"></a>

**[Agent Configuration](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-agent-configuration)**

### Policy Configuration
<a name="cookie-domain-configuration"></a>

![OpenAM Console Realm](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-console-realm.png)
**[Cookie Domain Configuration](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-cookie-domain-configuration)**

In administration console select realm, then go to __Authorization -> Policy Sets__, select __Default Policy Set__ and add new Policy
<a name="apache-http-server-configuration"></a>

Set Policy Name as you wish, Resource Type set URL, and add new Resource _\*://example.org:*/\*_ and click __Create__ to save new policy.

![OpenAM Console New Policy](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-console-newpolicy.png)

On new policy settings select Actions tab and add two actions __GET__ and __POST__

![OpenAM Policy Actions](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-console-policy-actions.png)

Then select Subjects tab and set type to __Authenticated Users__

![OpenAM Policy Subjects](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-console-policy-subjects.png)

Click __Save Changes__ to save your policy

### Agent Configuration

Then, in left menu, go to __Applications -> Web Agents__ and create new Agent

![OpenAM Web Agents](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-console-webagents.png)

Set name as you wish, for example `apache_agent`, set agent password.

![OpenAM Create Web Agent](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/openam-console-webagents-create.png)

Server URL set http://openam.example.org:8080/openam

Agent URL set http://example.org:80

Click __Create__ to save new Web Agent

Click __General__ tab to return to main menu.

### Cookie Domain Configuration

Navigate to __Configure -> Global Services -> Platform -> Cookie Domain__.

Set cookie domain to _.example.org_, save your settings.


## Apache HTTP Server Configuration
Create Dockerfile in your _/home/user/openam-quickstart/apache/_ folder with following content

```dockerfile
FROM httpd:2.4.34

ENV PA_PASSWORD password

RUN echo "deb [trusted=yes] http://archive.kernel.org/debian-archive/debian/ jessie main" >> /etc/apt/sources.list

RUN apt-get update || true

RUN apt-get install -y curl unzip

RUN curl -L -o /tmp/Apache_v24_Linux_64bit_4.1.1.zip https://github.com/OpenIdentityPlatform/OpenAM-Web-Agents/releases/download/4.1.1/Apache_v24_Linux_64bit_4.1.1.zip

RUN unzip /tmp/Apache_v24_Linux_64bit_4.1.1.zip -d /usr/

RUN rm /tmp/Apache_v24_Linux_64bit_4.1.1.zip

RUN echo $PA_PASSWORD > /tmp/pwd.txt

RUN cat /tmp/pwd.txt

RUN cat /etc/issue

RUN /usr/web_agents/apache24_agent/bin/agentadmin --s "/usr/local/apache2/conf/httpd.conf" "http://openam.example.org:8080/openam" "http://example.org:80" "/" "apache_agent" "/tmp/pwd.txt" --acceptLicence --changeOwner
```

Set ENV PA_PASSWORD as you previously set for your WebAgent in OpenAm


Build Apache Docker image

```bash
docker build --network=host -t apache_agent -f /home/user/openam-quickstart/apache/Dockerfile /home/user/openam-quickstart/apache/
```

And then run image
```bash
docker run -it --name apache_agent -p 80:80 -h example.org --shm-size 2G --network openam-quickstart apache_agent
```
Change apache_agent to httpd in the above command.
apache_agent is not available on docker hub.

Open in browser link http://example.org, and you will be redirected to OpenAM Authentication. After authentication you should see default Apache HTTP Server page
![Apache Default Page](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/quickstart/apache-default.png)
**[Apache HTTP Server Configuration](https://doc.openidentityplatform.org/openam/how-to/quick-start-guide#quick-start-guide-apache-http-server-configuration)**
222 changes: 25 additions & 197 deletions SAML-Authentication-in-WordPress-via-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,221 +1,49 @@
## Introduction

[SAMLv2](https://en.wikipedia.org/wiki/SAML_2.0), despite its venerable age, is the de facto standard for [SSO (Single Sign On)](https://en.wikipedia.org/wiki/Single_sign-on) in an enterprise environment. And in the following article, we will set up a SAML login to WordPress using [OpenAM](http://github.com/OpenIdentityPlatform/OpenAM) authentication. That is, when authenticating to WordPress, users will be redirected to OpenAM and, after authenticating to OpenAM will be automatically authenticated to WordPress. Given OpenAM's flexibility in customizing authentication methods, you can customize WordPress login not only by login and password but also, for example, using built-in Windows authentication (NTLMv2 or Kerberos), adding a second authentication factor (biometrics or one-time password) or even by scanning a QR code in a special mobile app.

Instead of WordPress, it can be almost any application that supports SAMLv2. The OpenAM configuration will be nearly identical. Only the settings for the application itself will differ.


## Some terminology

**Service Provider (SP)** - The application whose services users will use after authentication.

**Identity Provider (IdP)** - the application that authenticates users and provides the Service Provider with information about the authenticated accounts.

In our case, the Identity Provider is OpenAM and the Service Provider is WordPress.


## Test environment

For demonstration purposes, all applications will be run in Docker containers via the Docker Compose utility.

Add the OpenAM and WordPress hostnames `127.0.0.0.1 openam.example.org wordpress.example.org` to the `hosts` file.

On systems running Windows, the `hosts` file is `C:\Windows\System32\drivers\etc\hosts`. On Linux and Mac systems, `/etc/hosts`.

Create a `docker-compose.yml` file with the following contents:

```yaml
services:
openam:
image: openidentityplatform/openam:latest
restart: always
hostname: openam.example.org
ports:
- "8080:8080"
volumes:
- openam-data:/usr/openam/config
- ./openam-config.properties:/usr/openam/openam-config.properties:ro
- ./openam-init.sh:/usr/local/tomcat/bin/openam-init.sh:ro
command: |
bash /usr/local/tomcat/bin/openam-init.sh
wordpress:
image: wordpress
restart: always
hostname: wordpress.example.org
ports:
- 8081:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wordpress:/var/www/html
This article has moved to the Open Identity Platform documentation site:

db:
image: mysql:8.0
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql

volumes:
wordpress:
db:
openam-data:
[SAML Authentication in WordPress via OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam).

```
Please use the documentation site for the current version.

To configure OpenAM immediately configured at startup, create an OpenAM `openam-config.properties` configuration file:
<a name="introduction"></a>

```properties
ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/openam
BASE_DIR=/usr/openam/config
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=openam.example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd
```
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-introduction)**

and an initial configuration script `openam-init.sh`
<a name="some-terminology"></a>

```bash
#!/bin/bash
**[Some terminology](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-some-terminology)**

/usr/local/tomcat/bin/catalina.sh run &
SERVER_PID=$!
<a name="test-environment"></a>

# Wait for OpenAM to respond to isAlive.jsp
until curl -f -s -o /dev/null http://localhost:8080/openam/isAlive.jsp; do
echo "Waiting for OpenAM to fully initialize..."
sleep 5
done
**[Test environment](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-test-environment)**

if [[ -f /usr/openam/config/boot.json ]]; then
echo "OpenAM has already been configured."
else
echo "Setting up OpenAM..."
java -jar /usr/openam/ssoconfiguratortools/openam-configurator-tool*.jar --file /usr/openam/openam-config.properties
fi
<a name="wordpress-configuration"></a>

wait $SERVER_PID
```
Start the containers with the `docker compose up` command.
**[WordPress Configuration](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-wordpress-configuration)**

## WordPress Configuration
<a name="initial-wordpress-configuration"></a>

### Initial WordPress Configuration
**[Initial WordPress Configuration](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-initial-wordpress-configuration)**

If you already have WordPress configured, you can skip this section. If not, open the [http://wordpress.example.org:8081/wp-admin/install.php](http://wordpress.example.org:8081/wp-admin/install.php) link in your browser. Select the language and go to settings. Fill in the settings and be sure to remember the generated password. You will need it to log in to the administrator console.
<a name="install-the-samlv2-plugin"></a>

**[Install the SAMLv2 Plugin](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-install-the-samlv2-plugin)**

![Initial WordPress Configuration](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/0-wordpress-setup-settings.png)
<a name="openam-setup"></a>

Press the `Install WordPress` button.
**[OpenAM Setup](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-openam-setup)**

After completing the configuration, navigate to the login form and enter the administrator username and password specified during installation. The administrator console will open.
<a name="create-a-hosted-identity-provider"></a>

### Install the SAMLv2 Plugin
**[Create a Hosted Identity Provider](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-create-a-hosted-identity-provider)**

In the administrator console, select Plugins. Click the `Add New Plugin` button and install the miniOrange SAML Single Sign On - SSO Login plugin.
<a name="configure-remote-service-provider"></a>

![WordPress plugin for SAML](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/1-wordpress-saml-plugin.png)
**[Configure Remote Service Provider](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-configure-remote-service-provider)**

Once installed, activate the plugin by clicking the Activate button in the plugin window. In the left panel, you will see the settings item for the installed plugin.
<a name="wordpress-openam-identity-provider-configuration"></a>

Go to the `Service Provider Metadata` section in the plugin settings panel and copy the Metadata URL. Change the port from 8081 to 80 because OpenAM will load metadata from the WordPress Docker container, available on port 80 within the Docker environment: `http://wordpress.example.org:80/?option=mosaml_metadata`.
**[WordPress OpenAM Identity Provider Configuration](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-wordpress-openam-identity-provider-configuration)**

<a name="test-the-solution"></a>

![SAML SP WordPress Metadata](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/2-wordpress-saml-sp-metadata.png)

## OpenAM Setup

### Create a Hosted Identity Provider

Go to the OpenAM administrator console at [http://openam.example.org:8080/openam/XUI/#login/](http://openam.example.org:8080/openam/XUI/#login/).

Enter the OpenAM administrator login and password. In our case, it will be `amadmin` and `passw0rd` respectively.

In the console, open `Top Level Realm`, click `Configure SAMLv2 Provider` → `Create Hosted Identity Provider`.


![OpenAM Configure SAMLv2 Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/3-openam-configure-saml-provider.png)

![OpenAM Create Hosted Identity Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/4-openam-create-hosted-idp.png)

Complete the settings as shown in the screenshot and click the "Configure" button.

![OpenAM SAML Identity Provider Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/5-openam-saml-idp-settings.png)

In the administrator console click `Top Level Realm` and in the left menu select `Applications` → `SAML 2.0`

![OpenAM SAML](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/6-openam-saml.png)

In the `Entity Providers` section, open the settings for Identity Provider `http://openam.example.org:8080/openam`. On the `Assertion Content` tab, go to `Name ID Format` → `NameID Value Map` and add the value `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified=uid`

![OpenAM SAML NameID Value Map](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/7-openam-saml-nameid-value-map.png)

Press the `Save` button.

### Configure Remote Service Provider

Next, register WordPress as a remote service provider. In the OpenAM administrator console, select `Top Level Realm`, then `Configure SAMLv2 Provider` → `Configure Remote Service Provider`.

![OpenAM Create Remote Service Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/8-openam-create-remote-sp.png)

Fill out the Remote Service Provider settings as shown in the screenshot. The metadata URL should be as in the SAMLv2 WordPress plugin configuration step: `http://wordpress.example.org:80/?option=mosaml_metadata`.

![OpenAM SAML Service Provider Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/9-openam-saml-sp-settings.png)

## WordPress OpenAM Identity Provider Configuration

Go back to the WordPress administration console.

Open the miniOrange SAML plugin settings.

Click the `Service Provider Setup` tab.

In the `Configure Service Provider` section, click the `Upload IDP Metadata` tab.

Fill in the fields as shown in the screenshot below. The SAML metadata URL for OpenAM will be:`http://openam.example.org:8080/openam/saml2/jsp/exportmetadata.jsp`

![WordPress SAML Service Provider Settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/10-wordpress-saml-sp-settings.png)

Press the `Fetch Metadata` button.

The configuration is now complete.

## Test the Solution

Now let's test the solution. Log out of the WordPress administration console, OpenAM administration console or open a browser window in Incognito mode. Open the [http://wordpress.example.org:8081/wp-admin/](http://wordpress.example.org:8081/wp-admin/) link. The OpenAM login button will appear in the WordPress login window.

![WordPress Login](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/11-wordpress-login.png)

Click this button. You will be redirected to OpenAM authentication. Enter the user name `demo` and password `changeit`. The `demo` user is created during the initial installation of OpenAM. In a production environment, you should delete this user or change it's the default password.

![OpenAM Login](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/12-openam-login.png)

Press the `LOG IN` button.

You will be authenticated to WordPress with the `demo` user account.

![WordPress Successful Authentication](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-wordpress/13-wordpress-demo-authenticated.png)
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-wordpress-via-openam#saml-authentication-in-wordpress-via-openam-test-the-solution)**
135 changes: 29 additions & 106 deletions SAML-Authentication-in-Yandex-Cloud-via-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,134 +1,57 @@
[Russian version](https://github.com/OpenIdentityPlatform/OpenAM/wiki/%D0%90%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D0%BF%D0%BE-%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%83-SAML-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-OpenAM-%D0%BD%D0%B0-%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B5-Yandex-Cloud)
# Getting started
This article has moved to the Open Identity Platform documentation site:

To configure SAML authentication, there are the following prerequisites:
[SAML Authentication in Yandex Cloud via OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam).

1. Docker platform installed and running Docker Engine
2. Locally running OpenAM instance. To launch OpenAM, run the following command.
Please use the documentation site for the current version.

```bash
docker run -h openam.example.org -p 8080:8080 --name openam openidentityplatform/openam
```
<a name="getting-started"></a>

Detailed description of the installation and initial configuration of OpenAM at [this link](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Quick-Start-Guide)
**[Getting started](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-getting-started)**

# Setting up Federation in OpenAM
<a name="setting-up-federation-in-openam"></a>

## Create and Configure Identity Provider in OpenAM
**[Setting up Federation in OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-setting-up-federation-in-openam)**

1. Open the administration console
2. Goto desired realm
3. Select **Configure SAMLv2 Provider** in the Common Tasks section
<a name="create-and-configure-identity-provider-in-openam"></a>

![OpenAM Realm Common Tasks](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/realm-common-tasks.png)
**[Create and Configure Identity Provider in OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-create-and-configure-identity-provider-in-openam)**

4. Then **Create Hosted Identity Provider**
<a name="setting-up-the-user-mapping-in-openam"></a>

![Configure SAML v2 Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/configure-saml-provider.png)
**[Setting up the User Mapping in OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-setting-up-the-user-mapping-in-openam)**

5. Select a Signing Key (for demonstration purposes we will use **test**), enter the Circle of Trust name, and then map user's attributes to OpenAM. For demonstration users will be mapped by email.
<a name="creating-openam-users"></a>

![Configure SAML Identity Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/configure-saml-identity-provider.png)
**[Creating OpenAM Users](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-openam-users)**

6. Press the Configure button.
<a name="creating-and-setting-up-a-federation-in-yandex-cloud-organization"></a>

## Setting up the User Mapping in OpenAM
**[Creating and Setting up a Federation in Yandex Cloud Organization](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-and-setting-up-a-federation-in-yandex-cloud-organization)**

1. Open the administration console
2. Goto desired realm
3. From the menu on the left, select the Applications section and navigate to SAML 2.0
4. In the Entity Providers list select `http://openam.example.org:8080/openam`
5. On the Assertion Content tab, under **NameID Format** in the **NameID Value Map** list, add the element `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified=mail`
6. Press the Save button
<a name="create-a-federation"></a>

## Creating OpenAM Users
**[Create a Federation](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-create-a-federation)**

1. Open the administration console
2. Goto desired realm
3. Create a new user and fill the Email Address attribute
<a name="add-certificates"></a>

# Creating and Setting up a Federation in Yandex Cloud Organization
**[Add Certificates](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-add-certificates)**

## Create a Federation
<a name="creating-a-remote-service-provider-в-openam"></a>

1. Gotot [Yandex Cloud Organization](https://org.cloud.yandex.ru/).
2. On the left panel choose [Federations](https://org.cloud.yandex.ru/federations) .
3. Click the **Create Federation** button.
4. Give your federation a name. It must be unique within the folder.
5. You can also add a description, if required.
6. In the Cookie lifetime field, specify the time before the browser asks the user to re-authenticate.
7. In the **IdP Issuer** field, enter a link to the OpenAM: `http://openam.example.org:8080/openam`
8. In the Link to the **IdP login page** field, enter a link: `http://openam.example.org:8080/openam/SSORedirect/metaAlias/idp`
11. Click the **Create federation** button.
**[Creating a Remote Service Provider в OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-a-remote-service-provider-в-openam)**

## Add Certificates
<a name="creating-a-metadata-file-for-openam"></a>

While authenticating, the Cloud Organization service should be able to verify the IdP server certificate. To enable this, add the certificate to the federation:
**[Creating a Metadata file for OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-a-metadata-file-for-openam)**

1. Open the OpenAM link `http://openam.example.org:8080/openam/saml2/jsp/exportmetadata.jsp` and copy the `ds:X509Certificate` tag value
2. Save the certificate in a text file with a `.cer` extension in the following format:
<a name="creating-a-service-provider-in-openam"></a>

```bash
----BEGIN CERTIFICATE-----
<value ds:X509Certificate>
----END CERTIFICATE-----
```
**[Creating a Service Provider in OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-a-service-provider-in-openam)**

1. In the left panel, select [Federations](https://org.cloud.yandex.ru/federations).
2. Click the the federation for which you want to add the certificate.
3. At the bottom of the page, click **Adding a certificate**.
4. Enter the certificate name and description.
5. Click **Choose a file** and specify the path to the certificate file.
6. Click the **Add** button.
<a name="adding-users-to-yandex-cloud-organization"></a>

# Creating a Remote Service Provider в OpenAM
**[Adding Users to Yandex Cloud Organization](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-adding-users-to-yandex-cloud-organization)**

## Creating a Metadata file for OpenAM
<a name="testing-authentication"></a>

1. Create a `metadata.xml` file with the following contents where federation_ID - is a federation identifier in [Yandex Cloud Organization](https://org.cloud.yandex.ru), [Federations](https://org.cloud.yandex.ru/federations) section

```xml
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://console.cloud.yandex.ru/federations/<federation_ID>">
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://console.cloud.yandex.ru/federations/<federation_ID>" index="1"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
```

## Creating a Service Provider in OpenAM

1. Open the administration console
2. Goto desired realm
3. Choose **Configure SAMLv2 Provider** in the Common Tasks section
4. Then click **Configure Remote Service Provider**

![SAML Remote Service Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/saml-remote-service-provider.png)

1. Load the `metadata.xml` file created in the previous step as metadata.
2. Select the existing Circle Of Trust, created on the **Create and Configure Identity Provider in OpenAM** stage
3. Нажмите Configure

# Adding Users to Yandex Cloud Organization

If the **Automatically create users** option is enabled, a federation will only add users logging in to a cloud for the first time. You can only add a federated user again manually after deleting them from a federation.

1. [Login to account](https://passport.yandex.ru/) that belongs to an organization administrator or owner.
2. Goto [Yandex Cloud Organization](https://org.cloud.yandex.ru/) service.
3. In the left panel, select [Users](https://org.cloud.yandex.ru/users).
4. In the top-right corner, click **Add federated users**.
5. Select the identity federation to add users from.
6. Enter emails of the OpenAM users
7. Click the **Add** button. This will give the OpenAM users access to the organization.

# Testing Authentication

When you finish setting up SSO, test that everything works properly:

1. Open your browser in guest or private browsing mode.
2. Follow the URL to log in to the management console:

`https://console.cloud.yandex.ru/federations/<federation_ID>`

3. Enter OpenAM user credentials and click Login.

On successful authentication, the IdP server will redirect you to URL `https://console.cloud.yandex.ru/federations/<federation_ID>`, which you have set in the `metadata.xml` file for the Service Provider in the OpenAM settings and then to the [management console](https://console.cloud.yandex.ru/) home page. In the top-right corner, you will be able to see you are logged in to the console as a federated user.
**[Testing Authentication](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-testing-authentication)**
322 changes: 27 additions & 295 deletions SSO-Configuration:-OpenIG-as-SAML-Service-Provider-for-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,321 +1,53 @@
## Introduction
This article has moved to the Open Identity Platform documentation site:

The SAML 2.0 protocol is the standard for Single Sign-On (SSO) in enterprise environments. In this guide, we will show you how to use OpenIG as a proxy and service provider to easily add SAML authentication to any of your applications without changing its code.
[SSO Configuration: OpenIG as SAML Service Provider for OpenAM](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam).

## Preparation
Please use the documentation site for the current version.

1. To simplify service deployment, we will use OpenAM and OpenIG's Docker images. Therefore, you must have Docker installed.
2. Enter the host names for OpenAM and OpenIG in the `hosts` file. On Windows systems, the hosts file is located in the `C:\Windows/System32/drivers/etc/hosts` directory, and on Linux or Mac OS, it is located in `/etc/hosts`.

```
127.0.0.1 openam.example.org openig.example.org
```
<a name="introduction"></a>

## Configuring OpenAM
**[Introduction](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-introduction)**

### Installing OpenAM
<a name="preparation"></a>

Deploy the OpenAM container with the command:
**[Preparation](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-preparation)**

```bash
docker run -h openam.example.org -p 8080:8080 --name openam openidentityplatform/openam
```
<a name="configuring-openam"></a>

And perform the initial configuration:
**[Configuring OpenAM](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-configuring-openam)**

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
<a name="installing-openam"></a>

### OpenAM Identity Provider Setup
**[Installing OpenAM](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-installing-openam)**

1. Access the administrator console via the link [http://openam.example.org:8080/openam](http://openam.example.org:8080/openam). Use the login `amadmin` and password `passw0rd`.
2. Select Top Level Realm
3. Go to **Create SAMLv2 Providers** → **Create Hosted Identity Provider**
4. Set Metadata Name: `openam`
5. In the Signing Key setting, select `test`
6. Enter the name of the Circle of Trust, for example, `cot`
7. In the Attribute Mapping section, add the mapping uid → uid, mail → mail
8. Click **Configure**
<a name="openam-identity-provider-setup"></a>

### OpenAM Fedlet Configuration
**[OpenAM Identity Provider Setup](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-openam-identity-provider-setup)**

1. Open the administrator console
2. Select Top Level Realm
3. Go to **Create Fedlet Configuration**
4. Enter the fedlet name in the Name field, for example, openig.
5. Set the **Destination URL of the Service Provider which will include the Fedlet** to the URL that points to OpenIG: `http://openig.example.org:8081/saml`
6. In the Attribute Mapping section, add the mapping uid → uid, mail → mail
7. Click **Create**

The Fedlet settings will be saved in the container in the directory `/usr/openam/config/myfedlets/openig/Fedlet.zip`.

Copy the settings to the host machine using the command:

```bash
docker cp openam:/usr/openam/config/myfedlets/openig/Fedlet.zip .
```
<a name="openam-fedlet-configuration"></a>

### Preparing a test user
**[OpenAM Fedlet Configuration](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-openam-fedlet-configuration)**

1. Open the administrator console
2. Select Top Level Realm
3. In the left pane, select Subjects
4. In the list of accounts, open the `demo` account
5. In the Email Address field, enter `demo@example.org` or another valid email
6. Click **Save**
<a name="preparing-a-test-user"></a>

## OpenIG Setup
**[Preparing a test user](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-preparing-a-test-user)**

### Preparing OpenIG Configuration Files
<a name="openig-setup"></a>

1. Create a directory for OpenIG configuration files `openig-saml`
2. Add a directory `config` to it
3. In the `config` directory, create the files `admin.json` and `config.json`:

`admin.json`:
```json
{
"prefix" : "openig",
"mode": "PRODUCTION"
}
```

`config.json`:
```json
{
"heap": [
{
"name": "JwtSession",
"type": "JwtSession"
},
{
"name": "capture",
"type": "CaptureDecorator",
"config": {
"captureEntity": true,
"_captureContext": true
}
}
],
"handler": {
"type": "Chain",
"config": {
"filters": [],
"handler": {
"type": "Router",
"name": "_router",
"capture": "all"
}
}
}
}
```

4. Add a directory for routes named `routes` to the `config` directory.
5. Add the default route `99-default.json` to the `routes` directory. OpenIG will serve static content on this route and will not require authentication:

```json
{
"handler": {
"type": "DispatchHandler",
"config": {
"bindings": [
{
"handler": {
"type": "StaticResponseHandler",
"config": {
"status": 200,
"reason": "OK",
"entity":
"<!doctype html>
<html>
<head>
<title>Home</title>
<meta charset='UTF-8'>
</head>
<body>
<h1><a href='/app'>Login</a></h1>
</body>
</html>"
}
}
}
]
}
},
"session": "JwtSession"
}
```

6. Start the OpenIG Docker container with the command. Note the mounted directory `/app-saml`.

```bash
docker run -h openig.example.org -p 8081:8080 --name openig \
-v ./app-saml:/usr/local/app-saml:ro \
-e "CATALINA_OPTS=-Dopenig.base=/usr/local/app-saml" \
openidentityplatform/openig
```
**[OpenIG Setup](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-openig-setup)**

7. Check if the application is working:
<a name="preparing-openig-configuration-files"></a>

```bash
$ curl -v http://openig.example.org:8081
* Trying 127.0.0.1:8081...
* Connected to openig.example.org (127.0.0.1) port 8081 (#0)
> GET / HTTP/1.1
> Host: openig.example.org:8081
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Content-Length: 146
< Date: Mon, 24 Nov 2025 12:46:56 GMT
<
<!doctype html>
<html>
<head>
<title>Home</title>
<meta charset='UTF-8'>
</head>
<body>
<h1><a href='/app'>Login</a></h1>
</body>
```
### Configuring SAML Fedlet in OpenIG
**[Preparing OpenIG Configuration Files](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-preparing-openig-configuration-files)**

1. In the `openig-saml` directory, create a directory named `SAML`.
2. Copy the contents of the Fedlet.zip archive that you received from OpenAM into this directory.
```bash
unzip Fedlet.zip
cp conf/* app-saml/SAML/
```
<a name="configuring-saml-fedlet-in-openig"></a>

3. Create a route for obtaining credentials from SAML assertions `05-saml.json`
```json
{
"handler": {
"type": "SamlFederationHandler",
"config": {
"assertionMapping": {
"uid": "uid",
"mail": "mail"
},
"redirectURI": "/app"
}
},
"condition": "${matches(request.uri.path, '^/saml')}",
"session": "JwtSession"
}
```
**[Configuring SAML Fedlet in OpenIG](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-configuring-saml-fedlet-in-openig)**

4. Create a route for the application requiring SAML authentication `05-app.json`:
<a name="test-the-solution"></a>

```json
{
"handler": {
"type": "DispatchHandler",
"config": {
"bindings": [
{
"condition": "${empty session.uid}",
"handler": {
"type": "StaticResponseHandler",
"config": {
"status": 302,
"reason": "Found",
"headers": {
"Location": [
"http://openig.example.org:8081/saml/SPInitiatedSSO"
]
}
}
}
},
{
"handler": {
"handler": {
"type": "StaticResponseHandler",
"config": {
"status": 200,
"reason": "OK",
"entity":
"<!doctype html>
<html>
<head>
<title>OpenID Connect Discovery</title>
<meta charset='UTF-8'>
</head>
<body>
<h1>User: ${session.uid}, email: ${session.mail} </h1>
</body>
</html>"
}
}
}
}
]
}
},
"condition": "${matches(request.uri.path, '^/app')}",
"session": "JwtSession"
}
```
**[Test the Solution](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-test-the-solution)**

5. Start the OpenIG container:
```bash
docker run -h openig.example.org -p 8081:8080 --name openig \
-v ./app-saml:/usr/local/app-saml:ro \
-e “CATALINA_OPTS=-Dopenig.base=/usr/local/app-saml” \
openidentityplatform/openig
```
<a name="conclusion"></a>

## Test the Solution
1. Exit the OpenAM console or open your browser in incognito mode.
2. Open the link to the OpenIG application, which does not require authentication: [http://openig.example.org:8081/](http://openig.example.org:8081/).
![OpenIG Application Login](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-saml/0-openig-application-login.png)
3. Click on the `Login` link.
4. The OpenAM authentication form will open.
5. Enter the demo user credentials. Login: `demo`, password: `changeit`, and click the **Login** button.
![OpenAM Login](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-saml/1-openam-login.png)
6. You will be redirected to the application with the demo user credentials:
![OpenIG Logged In](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-openig-saml/2-openig-logged-in.png)
## Conclusion.
We have successfully configured OpenIG as a Service Provider and implemented SAML 2.0 authentication via OpenAM. You can now use this approach to secure any applications in your infrastructure. The next step could be to configure Log Out.
For more details on configuring OpenAM and OpenIG, please refer to the documentation:
- [https://doc.openidentityplatform.org/openam](https://doc.openidentityplatform.org/openam/)
- [http://doc.openidentityplatform.org/openig](http://doc.openidentityplatform.org/openig)
**[Conclusion.](https://doc.openidentityplatform.org/openam/how-to/sso-configuration-openig-as-saml-service-provider-for-openam#sso-configuration-openig-as-saml-service-provider-for-openam-conclusion)**
63 changes: 17 additions & 46 deletions Setup-Tracing-with--OpenTelemetry-and-Jaeger.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,17 @@
# Preconditions
Download the OpenTelemetry agent file opentelemetry-javaagent.jar by link [https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest) each OpenAM и OpenIG host

If Jaeger is not installed it can be run as a Docker container:

```bash
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-e COLLECTOR_OTLP_ENABLED=true \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 14250:14250 \
-p 14268:14268 \
-p 14269:14269 \
-p 9411:9411 \
jaegertracing/all-in-one:1.43
```
# OpenAM
Set environment variables

Variable | Example | Description
-- | -- | --
OTEL_TRACES_EXPORTER | jaeger | An exporter of traces
OTEL_SERVICE_NAME |openam | Service name for monitoring
OTEL_EXPORTER_JAEGER_TIMEOUT | 10000 | Jaeger connection timeout in milliseconds
OTEL_EXPORTER_JAEGER_ENDPOINT | http://localhost:14250 | gRPC Jaeger URL endpoint
JAVA_TOOL_OPTIONS | -javaagent:/path/to/opentelemetry-javaagent.jar | Path to OpenTelemetry Java agent

Restart OpenAM instance

# OpenIG
Set environment variables

Variable | Example | Description
-- | -- | --
OTEL_TRACES_EXPORTER | jaeger | An exporter of traces
OTEL_SERVICE_NAME | openig | Service name for monitoring
OTEL_EXPORTER_JAEGER_TIMEOUT | 10000 | Jaeger connection timeout in milliseconds
OTEL_EXPORTER_JAEGER_ENDPOINT | http://localhost:14250 | gRPC Jaeger URL endpoint
JAVA_TOOL_OPTIONS | -javaagent:/path/to/opentelemetry-javaagent.jar | Path to OpenTelemetry Java agent

Restart OpenIG instance
This article has moved to the Open Identity Platform documentation site:

[Setup Tracing with OpenTelemetry and Jaeger](https://doc.openidentityplatform.org/openam/how-to/setup-tracing-with-opentelemetry-and-jaeger).

Please use the documentation site for the current version.

<a name="preconditions"></a>

**[Preconditions](https://doc.openidentityplatform.org/openam/how-to/setup-tracing-with-opentelemetry-and-jaeger#setup-tracing-with-opentelemetry-and-jaeger-preconditions)**

<a name="openam"></a>

**[OpenAM](https://doc.openidentityplatform.org/openam/how-to/setup-tracing-with-opentelemetry-and-jaeger#setup-tracing-with-opentelemetry-and-jaeger-openam)**

<a name="openig"></a>

**[OpenIG](https://doc.openidentityplatform.org/openam/how-to/setup-tracing-with-opentelemetry-and-jaeger#setup-tracing-with-opentelemetry-and-jaeger-openig)**
47 changes: 21 additions & 26 deletions Stateful-vs-Stateless-Authentication.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
## Preface
Authentication is a process that exists in almost every application to Identify the application client whether it is a user or another application. While authentication client sends credentials to the application. The application ensures that credentials are correct, generates an authentication token, and sends it back to the client. To access the application as an identified client, the client uses the received authentication token.

Authentication tokens could be Stateless and Stateful.

## Stateful Authentication
After successful authentication, the application generates a random token to send back to the client and then creates a client authenticated session in memory or an internal database. When a client tries to access the application with a given token, the application tries to retrieve session data from session storage, checks if the session valid, and then decides whether the client has access to the desired resource or not.

## Stateless Authentication
After successful authentication, the application generates a token with all necessary data, signs it with a public key, and sends it back to a client. There is a standard for token generation, it is JWT (JSON Web Token). The process is described in OpenID Connect (OIDC) specification. When a client tries to access the application with a token, the application verifies the token sign with a private key, checks if the token is expired, retrieves all session data from the token, and makes a decision if a client has access to the desired resource.

| |Stateful|Stateless|
|-|-|-|
|Session information could be stolen|&#9989; It is impossible to steal session information from the session identifier because it is just an identifier associated with the session|&#9940;Session identifier contains all authentication information and it is possible to steal sensitive information, it is not encrypted.|
|Resource consuming|&#9940;When retrieving session information, the service always gets access to session storage which causes additional resource consumption.|&#9989;The session identifier contains all session information.|
|Easy to implement|&#9940;When session information is stored in an external database, there is a need to implement session database persistence.|&#9989;Session identifier contains all session information, there is no need to implement additional functionality|
|Easy to scale|&#9940;While adding new instances, there is a need to implement additional scale to session storage as well|&#9989; Adding new service instances does not require additional effort|
|Possibility to compromise session data.|&#9989;Only the authentication system is able to retrieve session information from an authentication token, so there are no more vulnerabilities.|&#9940;To decrypt session information from a token, all parts of the system should share the same key. And, if at least one system is compromised, all parts of the system are under the threat.|
|Authentication token size|&#9989;An authentication token is just an identifier, so session data does not affect its size.|&#9940;If an authentication session contains a large amount of data, the authentication token also becomes large, which can cause additional load on a network.|
|Restrict access among different parts of an application|&#9989;It is possible to configure the system so different parts of the system will only have access to the data necessary for their work|&#9940;All parts of the system have access to all session data|
|Possibility to revoke session|&#9989;It is possible to revoke a session at any time|&#9940;Since the session token contains an expiration date, it is impossible to revoke the authentication session|
|Possibility to modify session data|&#9989;It is possible to modify any session data in session data storage.|&#9940;Since the session token contains all session data, it is not possible to modify it|
|SSO implementation|&#9989;The integration of different parts of the system is possible without modification of the source code, session information can come through the authentication system gateway.|&#9940;Changes must be made to each part of the system to retrieve data from an authentication token|

## Conclusion
Both approaches make sense, both have their advantages and disadvantages. Stateless authentication is easier to implement and scale, but stateful authentication is more secure and easier to manage.
This article has moved to the Open Identity Platform documentation site:

[Stateful vs Stateless Authentication](https://doc.openidentityplatform.org/openam/how-to/stateful-vs-stateless-authentication).

Please use the documentation site for the current version.

<a name="preface"></a>

**[Preface](https://doc.openidentityplatform.org/openam/how-to/stateful-vs-stateless-authentication#stateful-vs-stateless-authentication-preface)**

<a name="stateful-authentication"></a>

**[Stateful Authentication](https://doc.openidentityplatform.org/openam/how-to/stateful-vs-stateless-authentication#stateful-vs-stateless-authentication-stateful-authentication)**

<a name="stateless-authentication"></a>

**[Stateless Authentication](https://doc.openidentityplatform.org/openam/how-to/stateful-vs-stateless-authentication#stateful-vs-stateless-authentication-stateless-authentication)**

<a name="conclusion"></a>

**[Conclusion](https://doc.openidentityplatform.org/openam/how-to/stateful-vs-stateless-authentication#stateful-vs-stateless-authentication-conclusion)**
127 changes: 3 additions & 124 deletions TIP:-Bootstrap-OpenAM-and-OpenDJ-Docker-Containers.md
Original file line number Diff line number Diff line change
@@ -1,126 +1,5 @@
Create `docker-compose.yml` file with OpenAM and OpenDJ services with the following contents:
This article has moved to the Open Identity Platform documentation site:

```yaml
services:
opendj:
image: openidentityplatform/opendj:latest
container_name: opendj
environment:
- BASE_DN=dc=example,dc=com
- LDAP_PORT=1389
- ROOT_PASSWORD=admin_password
- REPLICATION_PORT=8989
ports:
- "1389:1389"
- "1636:1636"
- "4444:4444"
volumes:
- opendj-data:/opt/opendj/data
restart: always
[Bootstrap OpenAM and OpenDJ Docker Containers](https://doc.openidentityplatform.org/openam/how-to/bootstrap-openam-and-opendj-docker-containers).

openam:
image: openidentityplatform/openam:latest
container_name: openam
depends_on:
- opendj
ports:
- "8080:8080"
volumes:
- openam-data:/usr/openam/config
- ./openam-config.properties:/usr/openam/openam-config.properties:ro
- ./openam-init.sh:/usr/local/tomcat/bin/openam-init.sh:ro
command: |
bash /usr/local/tomcat/bin/openam-init.sh
restart: always

volumes:
opendj-data:
openam-data:

```

Create `openam-config.properties` file with the following contents:

```properties
# General Settings
SERVER_URL=http://localhost:8080
DEPLOYMENT_URI=/openam
BASE_DIR=/usr/openam/config
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=amadmin_password
AMLDAPUSERPASSWD=admin_password
COOKIE_DOMAIN=localhost
ACCEPT_LICENSES=true

# Data Store (OpenDJ)
DATA_STORE=dirServer
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=opendj
DIRECTORY_PORT=1389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1636
ROOT_SUFFIX=dc=example,dc=com
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=admin_password

# User Store (OpenDJ)
USERSTORE_TYPE=LDAPv3ForOpenDS
USERSTORE_SSL=SIMPLE
USERSTORE_HOST=opendj
USERSTORE_PORT=1389
USERSTORE_SUFFIX=dc=example,dc=com
USERSTORE_MGRDN=cn=Directory Manager
USERSTORE_PASSWD=admin_password
```

Create `openam-init.sh` file. This script waits for OpenDJ, then for OpenAM to start, and if OpenAM is not configured runs `openam-configurator-tool` with `openam-config.properties` file.

```bash
#!/bin/bash

until cat < /dev/null > /dev/tcp/opendj/1389; do
echo "Waiting for OpenDJ..."
sleep 5
done

/usr/local/tomcat/bin/catalina.sh run &
SERVER_PID=$!

# Wait for OpenAM to respond to isAlive.jsp
until curl -f -s -o /dev/null http://localhost:8080/openam/isAlive.jsp; do
echo "Waiting for OpenAM to fully initialize..."
sleep 5
done

if [[ -f /usr/openam/config/boot.json ]]; then
echo "OpenAM has already been configured."
else
echo "Setting up OpenAM..."
java -jar /usr/openam/ssoconfiguratortools/openam-configurator-tool*.jar --file /usr/openam/openam-config.properties
fi

wait $SERVER_PID
```

Run the `docker compose up` command. OpenAM and OpenDJ will be configured according to the `openam-config.properties` file

Test OpenAM with the following command:

```bash
curl \
--request POST \
--header "Content-Type: application/json" \
--header "X-OpenAM-Username: amadmin" \
--header "X-OpenAM-Password: amadmin_password" \

http://localhost:8080/openam/json/authenticate
{
"realm" : "/",
"successUrl" : "/openam/console",
"tokenId" : "AQIC5wM2LY4SfcxC_WOLjtSC7DdP5nIkhXU2DPuIWjHNlSE.*AAJTSQACMDEAAlNLABIxMjY1NTY0NTA4NDU3ODQyNTAAAlMxAAA.*"
}
```

Thanks to [@Lewiscowles1986](https://github.com/Lewiscowles1986). See [#817](https://github.com/OpenIdentityPlatform/OpenAM/discussions/817#discussioncomment-11440465)
Please use the documentation site for the current version.
10 changes: 3 additions & 7 deletions TIP:-How-to-Enable-CORS.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
Open the administrator console. In the top menu, select Configure → Global Services.
This article has moved to the Open Identity Platform documentation site:

![OpenAM Global Services](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/4-global-services.png)
[How to Enable CORS](https://doc.openidentityplatform.org/openam/how-to/how-to-enable-cors).

Next, go to CORS Settings and enable CORS support

![OpenAM CORS settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/openam-spa-oauth2/5-cors-settings.png)

Pres the `Save Changes` button.
Please use the documentation site for the current version.
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
Sometimes it is necessary to append a new system property to existing CATALINA_OTPS environment variable, for example -DXUI.enable=false
This article has moved to the Open Identity Platform documentation site:

You could do this with the following command:
[How to Pass Additional System Property to CATALINA_OPTS to OpenAM Docker Container](https://doc.openidentityplatform.org/openam/how-to/how-to-pass-additional-system-property-to-catalina-opts-to-openam-docker-container).

```bash
docker run --rm -h openam.example.org -p 8080:8080 --network openam --name openam openidentityplatform/openam \
"sh" "-c" "CATALINA_OPTS=\"\$CATALINA_OPTS -DXUI.enable=false\" && /usr/local/tomcat/bin/catalina.sh run"
```
Please use the documentation site for the current version.
Original file line number Diff line number Diff line change
@@ -1,37 +1,5 @@
Docker containers are stateless. So, if you want persist the OpenAM's configuration data, you need to specify a volume that maps `/usr/openam/config` container directory to a local directory.
Example with `docker-compose.yaml`
This article has moved to the Open Identity Platform documentation site:

```yaml
services:
openam:
image: openidentityplatform/openam:latest
ports:
- 8080:8080
- 8085:8085
volumes:
- ./openam-data:/usr/openam/config
[How to Persist OpenAM Docker Container Data Between Restarts](https://doc.openidentityplatform.org/openam/how-to/how-to-persist-openam-docker-container-data-between-restarts).

```

With `docker run` command:
```
docker run -v ./openam-data:/usr/openam/config \
-h openam.example.org \
-p 8080:8080 \
--name openam \
openidentityplatform/openam
```

If you are facing permisson issues in Lunux, use a named volume

```
docker volume create openam-data
```

```
docker run -v openam-data:/usr/openam/config \
-h openam.example.org \
-p 8080:8080 \
--name openam \
openidentityplatform/openam
```
Please use the documentation site for the current version.
68 changes: 3 additions & 65 deletions TIP:-Quick-OpenAM-Docker-Configuration-From-a-Command-Line.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,5 @@
Let OpenAM hostname is `openam.example.org` Before starting, add the hostname and IP address to the `hosts` file, for example `127.0.0.0.1 openam.example.org`.
This article has moved to the Open Identity Platform documentation site:

On Windows systems, the `hosts` file is located at `C:\Windows/System32/drivers/etc/hosts` , on Linux and Mac it is located at `/etc/hosts`.
[Quick OpenAM Docker Configuration From a Command Line](https://doc.openidentityplatform.org/openam/how-to/quick-openam-docker-configuration-from-a-command-line).

Next, start the OpenAM Docker container. Run the following command:

```bash
docker run -h openam.example.org -p 8080:8080 --name openam openidentityplatform/openam
```

There is no need to configure OpenAM manually via UI. The following command helps to automate the process:

```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=passw0rd
AMLDAPUSERPASSWD=p@passw0rd
COOKIE_DOMAIN=example.org
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=openam.example.org
DIRECTORY_PORT=50389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=openam,dc=example,dc=org
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=passw0rd" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```

For external LDAP server OpenDJ use:
```bash
docker exec -w '/usr/openam/ssoconfiguratortools' openam bash -c \
'echo "ACCEPT_LICENSES=true
SERVER_URL=http://openam.example.org:8080
DEPLOYMENT_URI=/$OPENAM_PATH
BASE_DIR=$OPENAM_DATA_DIR
locale=en_US
PLATFORM_LOCALE=en_US
AM_ENC_KEY=
ADMIN_PWD=ampassword
AMLDAPUSERPASSWD=password
COOKIE_DOMAIN=example.org
DATA_STORE=dirServer
DIRECTORY_SSL=SIMPLE
DIRECTORY_SERVER=opendj
DIRECTORY_PORT=1389
DIRECTORY_ADMIN_PORT=4444
DIRECTORY_JMX_PORT=1689
ROOT_SUFFIX=dc=example,dc=com
DS_DIRMGRDN=cn=Directory Manager
DS_DIRMGRPASSWD=password
USERSTORE_TYPE=LDAPv3ForOpenDS
USERSTORE_SSL=SIMPLE
USERSTORE_HOST=opendj
USERSTORE_PORT=1389
USERSTORE_SUFFIX=dc=example,dc=com
USERSTORE_MGRDN=cn=Directory Manager
USERSTORE_PASSWD=password
" > conf.file && java -jar openam-configurator-tool*.jar --file conf.file'
```
Please use the documentation site for the current version.
95 changes: 21 additions & 74 deletions Using-Google-Authenticator-with-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,41 @@
This article has moved to the Open Identity Platform documentation site:

This article is intended for technical specialists or security system architects who want to implement two-factor authentication (2FA) in an access control system to enhance the security of user accounts.
[Using Google Authenticator with OpenAM](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam).

Adding a second factor makes it significantly more difficult for attackers to compromise accounts.
Please use the documentation site for the current version.

## Stack Used
<a name="stack-used"></a>

**OpenAM** is an open-source access management system. It is designed for centralized management of authentication, authorization, and user accounts.
**[Stack Used](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-stack-used)**

**Google Authenticator** is a mobile application designed to be used as an additional authentication factor. It supports one-time passwords (TOTP), and biometric authentication.
<a name="installing-openam"></a>

In this article, we will deploy OpenAM, configure modules and authentication chains for use with Google Authenticator, and show you how to add a second factor authentication for a user.
**[Installing OpenAM](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-installing-openam)**

We will use authentication with one-time passwords generated using the TOTP (time-based one-time password) protocol. Such passwords do not need to be sent to the client device via SMS or PUSH notifications. These passwords are generated using a specific cryptographic algorithm directly on the device.
<a name="configuring-openam"></a>

## Installing OpenAM
**[Configuring OpenAM](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-configuring-openam)**

If you do not have OpenAM installed yet, you can deploy a Docker container as described in the [OpenAM wiki article](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP%3A-Quick-OpenAM-Docker-Configuration-From-a-Command-Line)
<a name="configuring-the-totp-authentication-module"></a>

## Configuring OpenAM
**[Configuring the TOTP Authentication Module](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-configuring-the-totp-authentication-module)**

We will configure the module and authentication chain.
<a name="configuring-the-device-registration-chain"></a>

The authentication module in OpenAM is responsible for a specific authentication method. This can be authentication with a username and password, via the Kerberos protocol, or using biometrics.
Modules can be organized into chains. This allows you to build chains of modules to authenticate users in multiple stages or using different methods. For example, if seamless authentication via the Kerberos protocol fails, you can ask the user for their login and password.
**[Configuring the Device Registration Chain](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-configuring-the-device-registration-chain)**

### **Configuring the TOTP Authentication Module**
<a name="configuring-the-authentication-chain"></a>

Open the administrator console at [http://openam.example.org:8080/openam/console](http://openam.example.org:8080/openam/console)
**[Configuring the Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-configuring-the-authentication-chain)**

In the login field, enter `amadmin`. In the password field, enter the administrator password specified during installation.
<a name="setting-up-google-authenticator"></a>

Open the root realm, select Authentication → Modules in the left menu, and click the `Add Module` button. In the form that appears, enter the module name, for example `totp`, and the module type - `Authenticator (OATH)`. Click the `Create` button.
**[Setting up Google Authenticator.](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-setting-up-google-authenticator)**

![OpenAM new TOTP module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/0-openam-new-totp-module.png)
<a name="registering-a-device"></a>

Set the `OATH Algorithm to Use` setting to `TOTP`, enter any non-empty value in the `Name of the Issuer` field, for example `OpenAM`, and click `Save Changes`.
**[Registering a Device](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-registering-a-device)**

![OpenAM TOTP module settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/1-openam-totp-module-settings.png)
<a name="authentication-with-one-time-password"></a>

### **Configuring the Device Registration Chain**

The registration chain is required so that authenticated users can add a second authentication factor using Google Authenticator.

In the administrator console, in the realm settings in the left menu, select Authentication → Chains and click the `Add Chain` button in the list that opens.

Enter the chain name `totp-register` and click the `Create` button.

In the chain settings, click the `Add a Module` button and add the created `totp` authentication module as shown in the figure. Click the `OK` button and then `Save Changes`.

![OpenAM TOTP registration chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/2-openam-totp-registration-chain.png)

### **Configuring the Authentication Chain**

In this chain, we will configure authentication so that after authenticating with a username and password, the user is required to enter a one-time password from the Google Authenticator mobile app.

In the administrator console, in the realm settings in the left menu, select Authentication → Chains and click the `Add Chain` button in the list that opens.

Enter the chain name `totp-login` and click the `Create` button. First, add the `DataStore` login and password authentication module. Then add the `totp` one-time code authentication module.

Click `Save Changes`.

![OpenAM TOTP authentication chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/3-openam-totp-authentication-chain.png)

## Setting up Google Authenticator.

Download the Google Authenticator app from the appropriate app store for your device.

### Registering a Device

Sign in to the console with a test user account. To do this, either sign out of the administrator console or open your browser in incognito mode. Go to the URL [http://openam.example.org:8080/openam/XUI/#login/](http://openam.example.org:8080/openam/XUI/#login/) and log in to OpenAM with the `demo` account. The default password is `changeit`.

After successful authentication, open the device registration chain link in your browser: [http://openam.example.org:8080/openam/XUI/#login&service=totp-register](http://openam.example.org:8080/openam/XUI/#login&service=totp-register).

![OpenAM register a device](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/4-openam-register-device.png)

Open the Goole Authenticator app and tap the `Add code` button.

![Google Authenticator Add Code](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/9-google-authenticator.png)

You will be prompted to scan a QR code. Scan the QR code displayed in the OpenAM browser window. After scanning, the OpenAM account will be added to the Google Authenticator app.

Locate the newly added account. A one-time password will be displayed.

![Google Authenticator One-Time Password](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/10-google-authenticator-otp.png)

In your browser, click the `Login Using Verification Code` button.

Enter the one-time password from the mobile app and click the `Submit` button.

### Authentication with One-Time Password

Exit the OpenAM console or open your browser in incognito mode. Follow the link [http://openam.example.org:8080/openam/XUI/#login&service=totp-login](http://openam.example.org:8080/openam/XUI/#login&service=totp-login).
Enter the username and password for the `demo` account. After entering the username and password, OpenAM will request a one-time password from the mobile app. Open the mobile app, select the `demo` user account. Enter the one-time password from the mobile app in the browser, and click the `Submit` button. If the one-time password is correct, you will be authenticated successfully.
**[Authentication with One-Time Password](https://doc.openidentityplatform.org/openam/how-to/using-google-authenticator-with-openam#using-google-authenticator-with-openam-authentication-with-one-time-password)**
101 changes: 21 additions & 80 deletions Using-Microsoft-Authenticator-with-OpenAM.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,41 @@
This article has moved to the Open Identity Platform documentation site:

This article is intended for technical specialists or security system architects who want to implement two-factor authentication (2FA) in an access control system to enhance the security of user accounts.
[Using Microsoft Authenticator with OpenAM](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam).

Adding a second factor makes it significantly more difficult for attackers to compromise accounts.
Please use the documentation site for the current version.

## Stack Used
<a name="stack-used"></a>

**OpenAM** is an open-source access management system. It is designed for centralized management of authentication, authorization, and user accounts.
**[Stack Used](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-stack-used)**

**Microsoft Authenticator** is a mobile application designed to be used as an additional authentication factor. It supports push notifications, one-time passwords (TOTP), and biometric authentication.
<a name="installing-openam"></a>

In this article, we will deploy OpenAM, configure modules and authentication chains for use with Microsoft Authenticator, and show you how to add a second factor authentication for a user.
**[Installing OpenAM](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-installing-openam)**

We will use authentication with one-time passwords generated using the TOTP (time-based one-time password) protocol. Such passwords do not need to be sent to the client device via SMS or PUSH notifications. These passwords are generated using a specific cryptographic algorithm directly on the device.
<a name="configuring-openam"></a>

## Installing OpenAM
**[Configuring OpenAM](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-configuring-openam)**

If you do not have OpenAM installed yet, you can deploy a Docker container as described in the [OpenAM wiki article](https://github.com/OpenIdentityPlatform/OpenAM/wiki/TIP%3A-Quick-OpenAM-Docker-Configuration-From-a-Command-Line)
<a name="configuring-the-totp-authentication-module"></a>

## Configuring OpenAM
**[Configuring the TOTP Authentication Module](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-configuring-the-totp-authentication-module)**

We will configure the module and authentication chain.
<a name="configuring-the-device-registration-chain"></a>

The authentication module in OpenAM is responsible for a specific authentication method. This can be authentication with a username and password, via the Kerberos protocol, or using biometrics.
Modules can be organized into chains. This allows you to build chains of modules to authenticate users in multiple stages or using different methods. For example, if seamless authentication via the Kerberos protocol fails, you can ask the user for their login and password.
**[Configuring the Device Registration Chain](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-configuring-the-device-registration-chain)**

### **Configuring the TOTP Authentication Module**
<a name="configuring-the-authentication-chain"></a>

Open the administrator console at [http://openam.example.org:8080/openam/console](http://openam.example.org:8080/openam/console)
**[Configuring the Authentication Chain](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-configuring-the-authentication-chain)**

In the login field, enter `amadmin`. In the password field, enter the administrator password specified during installation.
<a name="setting-up-microsoft-authenticator"></a>

Open the root realm, select Authentication → Modules in the left menu, and click the `Add Module` button. In the form that appears, enter the module name, for example `totp`, and the module type - `Authenticator (OATH)`. Click the `Create` button.
**[Setting up Microsoft Authenticator.](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-setting-up-microsoft-authenticator)**

![OpenAM new TOTP module](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/0-openam-new-totp-module.png)
<a name="registering-a-device"></a>

Set the `OATH Algorithm to Use` setting to `TOTP`, enter any non-empty value in the `Name of the Issuer` field, for example `OpenAM`, and click `Save Changes`.
**[Registering a Device](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-registering-a-device)**

![OpenAM TOTP module settings](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/1-openam-totp-module-settings.png)
<a name="authentication-with-one-time-password"></a>

### **Configuring the Device Registration Chain**

The registration chain is required so that authenticated users can add a second authentication factor using Microsoft Authenticator.

In the administrator console, in the realm settings in the left menu, select Authentication → Chains and click the `Add Chain` button in the list that opens.

Enter the chain name `totp-register` and click the `Create` button.

In the chain settings, click the `Add a Module` button and add the created `totp` authentication module as shown in the figure. Click the `OK` button and then `Save Changes`.

![OpenAM TOTP registration chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/2-openam-totp-registration-chain.png)

### **Configuring the Authentication Chain**

In this chain, we will configure authentication so that after authenticating with a username and password, the user is required to enter a one-time password from the Microsoft Authenticator mobile app.

In the administrator console, in the realm settings in the left menu, select Authentication → Chains and click the `Add Chain` button in the list that opens.

Enter the chain name `totp-login` and click the `Create` button. First, add the `DataStore` login and password authentication module. Then add the `totp` one-time code authentication module.

Click `Save Changes`.

![OpenAM TOTP authentication chain](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/3-openam-totp-authentication-chain.png)

## Setting up Microsoft Authenticator.

Download the [Microsoft Authenticator](https://www.microsoft.com/en/security/mobile-authenticator-app) app from the appropriate app store for your device.

### Registering a Device

Sign in to the console with a test user account. To do this, either sign out of the administrator console or open your browser in incognito mode. Go to the URL [http://openam.example.org:8080/openam/XUI/#login/](http://openam.example.org:8080/openam/XUI/#login/) and log in to OpenAM with the `demo` account. The default password is `changeit`.

After successful authentication, open the device registration chain link in your browser: [http://openam.example.org:8080/openam/XUI/#login&service=totp-register](http://openam.example.org:8080/openam/XUI/#login&service=totp-register).

![OpenAM register a device](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/4-openam-register-device.png)

Open the Microsoft Authenticator app and tap the `Add account` button.

![Microsoft Authenticator Add account](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/5-ms-authenticator-add-account.png)

Select `Other account`.

![Microsoft Authenticator Other account](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/6-ms-authenticator-other-account.png)

You will be prompted to scan a QR code. Scan the QR code displayed in the OpenAM browser window. After scanning, the OpenAM account will be added to the Microsoft Authenticator app.

![Microsoft Authenticator Account List](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/7-ms-authenticator-account-list.png)

Locate the newly added account. A one-time password will be displayed.

![Microsoft Authenticator One-Time Password](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/ms-authenticator/8-ms-authenticator-otp.png)

In your browser, click the `Login Using Verification Code` button.

Enter the one-time password from the mobile app and click the `Submit` button.

### Authentication with One-Time Password

Exit the OpenAM console or open your browser in incognito mode. Follow the link [http://openam.example.org:8080/openam/XUI/#login&service=totp-login](http://openam.example.org:8080/openam/XUI/#login&service=totp-login).
Enter the username and password for the `demo` account. After entering the username and password, OpenAM will request a one-time password from the mobile app. Open the mobile app, select the `demo` user account. Enter the one-time password from the mobile app in the browser, and click the `Submit` button. If the one-time password is correct, you will be authenticated successfully.
**[Authentication with One-Time Password](https://doc.openidentityplatform.org/openam/how-to/using-microsoft-authenticator-with-openam#using-microsoft-authenticator-with-openam-authentication-with-one-time-password)**
18 changes: 7 additions & 11 deletions What-is-Single-Sign-On-and-How-does-it-Work.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
This article has moved to the Open Identity Platform documentation site:

- [What is Single Sign-On](#what-is-single-sign-on)
- [How does Single Sign On Work](#how-does-single-sign-on-work)
[What is Single Sign On and How does it Work](https://doc.openidentityplatform.org/openam/how-to/what-is-single-sign-on-and-how-does-it-work).

## What is Single Sign-On
Single Sign-On (SSO) is a technology that allows users to authenticate into various systems using single credentials.
Please use the documentation site for the current version.

For example, Acme Corp uses various information systems and each system has its user database and its login processes. So, when Acme Corp hires a new employee, they should create an account for each system. To use each system, an employee should enter his credentials into each system as well. If the employee getting fired or promoted to a new position, all user accounts for the employee should also be changed. With an increasing number of employees and a number of information systems in the organization, user account management becomes more difficult and expensive.
<a name="what-is-single-sign-on"></a>

To simplify user account management, Acme Corp starts to use the SSO system. So, when an employee authenticates the operating system, he could use his operating system account to access all other information systems. If the employee got fired or promoted or just wants to change his password, only one user account should be modified. When Acme Corp stars using new software, they just set up it to use SSO for authentication and there’s no need to create user database in this software.
**[What is Single Sign-On](https://doc.openidentityplatform.org/openam/how-to/what-is-single-sign-on-and-how-does-it-work#what-is-single-sign-on-and-how-does-it-work-what-is-single-sign-on)**

<a name="how-does-single-sign-on-work"></a>

## How does Single Sign On Work

When an employee tries to login into an information system, SSO checks if he already logged in in SSO. If the employee is not logged in, SSO asks the employee for authentication. After authentication, SSO creates a session for the employee and redirects him to the desired system. If the employee is authenticated in SSO, SSO provides account information to the desired system, the employee tries to access.

![Single Sing On Flowchart](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/sso/sso-flowchart.png)
**[How does Single Sign On Work](https://doc.openidentityplatform.org/openam/how-to/what-is-single-sign-on-and-how-does-it-work#what-is-single-sign-on-and-how-does-it-work-how-does-single-sign-on-work)**
Original file line number Diff line number Diff line change
@@ -1,134 +1,57 @@
[English version](https://github.com/OpenIdentityPlatform/OpenAM/wiki/SAML-Authentication-in-Yandex-Cloud-via-OpenAM)
# Подготовка
This article has moved to the Open Identity Platform documentation site:

Для настройки SAML аутентификации требуется
[SAML Authentication in Yandex Cloud via OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam).

1. Платформа Docker и запущенный Docker Engine
2. Локально запущенный инстанс OpenAM. Для запуска OpenAM выполните команду.
Please use the documentation site for the current version.

```bash
docker run -h openam.example.org -p 8080:8080 --name openam openidentityplatform/openam
```
<a name="подготовка"></a>

Подробное описание установки и первоначальной настройки OpenAM по [ссылке](https://github.com/OpenIdentityPlatform/OpenAM/wiki/Quick-Start-Guide)
**[Подготовка](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-getting-started)**

# Настройка федерации в OpenAM
<a name="настройка-федерации-в-openam"></a>

## Создание и настройка Identity Provider в OpenAM
**[Настройка федерации в OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-setting-up-federation-in-openam)**

1. Откройте консоль администратора
2. Перейдите в нужный realm
3. Выберите в разделе Common Tasks **Configure SAMLv2 Provider**
<a name="создание-и-настройка-identity-provider-в-openam"></a>

![OpenAM Realm Common Tasks](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/realm-common-tasks.png)
**[Создание и настройка Identity Provider в OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-create-and-configure-identity-provider-in-openam)**

4. Далее **Create Hosted Identity Provider**
<a name="настройка-связи-пользователей-openam"></a>

![Configure SAML v2 Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/configure-saml-provider.png)
**[Настройка связи пользователей OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-setting-up-the-user-mapping-in-openam)**

5. Выберите ключ для подписи (для демонстрационных целей будем использовать **test**), введите имя круга доверия а так же свяжите атрибуты пользователей Yandex Cloud Organization c OpenAM. Для демонстрационных целей пользователи будут связаны по email.
<a name="создание-пользователей-openam"></a>

![Configure SAML Identity Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/configure-saml-identity-provider.png)
**[Создание пользователей OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-openam-users)**

6. Нажмите кнопку Configure.
<a name="создание-и-настройка-федерации-в-yandex-cloud-organization"></a>

## Настройка связи пользователей OpenAM
**[Создание и настройка федерации в Yandex Cloud Organization](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-and-setting-up-a-federation-in-yandex-cloud-organization)**

1. Откройте консоль администратора
2. Выберите требуемый realm
3. В меню слева выберите раздел Applications и перейдите в SAML 2.0
4. В списке Entity Providers выберите `http://openam.example.org:8080/openam`
5. На закладке Assertion Content в разделе **NameID Format** в список **NameID Value Map** добавьте элемент `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified=mail`
6. Нажмите Save
<a name="создайте-федерацию"></a>

## Создание пользователей OpenAM
**[Создайте федерацию](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-create-a-federation)**

1. Откройте консоль администратора
2. Выберите требуемый realm
3. Создайте пользователя и заполните у него атрибут Email Address
<a name="добавьте-сертификаты"></a>

# Создание и настройка федерации в Yandex Cloud Organization
**[Добавьте сертификаты](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-add-certificates)**

## Создайте федерацию
<a name="cоздание-и-настройка-service-provider-в-openam"></a>

1. Перейдите в сервис [Yandex Cloud Organization](https://org.cloud.yandex.ru/).
2. На панели слева выберите раздел [Федерации](https://org.cloud.yandex.ru/federations) .
3. Нажмите кнопку **Создать федерацию**.
4. Задайте имя федерации. Имя должно быть уникальным в каталоге.
5. При необходимости добавьте описание.
6. В поле **Время жизни cookie** укажите время, в течение которого браузер не будет требовать у пользователя повторной аутентификации.
7. В поле **IdP Issuer** вставьте ссылку: `http://openam.example.org:8080/openam`
8. В поле **Ссылка на страницу для входа в IdP** вставьте ссылку: `http://openam.example.org:8080/openam/SSORedirect/metaAlias/idp`
11. Нажмите кнопку **Создать федерацию**.
**[Cоздание и настройка Service Provider в OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-a-remote-service-provider-в-openam)**

## ****Добавьте сертификаты****
<a name="создайте-файл-метаданных-для-openam"></a>

При аутентификации у сервиса Cloud Organization должна быть возможность проверить сертификат IdP-сервера. Для этого добавьте сертификат в федерацию:
**[Создайте файл метаданных для OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-a-metadata-file-for-openam)**

1. Откройте ссылку OpenAM `http://openam.example.org:8080/openam/saml2/jsp/exportmetadata.jsp` и скопируйте значение тега ds:X509Certificate
2. Сохраните сертификат в текстовом файле с расширением `.cer` в следующем формате:
<a name="создание-service-provider-в-openam"></a>

```bash
----BEGIN CERTIFICATE-----
<значение ds:X509Certificate>
----END CERTIFICATE-----
```
**[Создание Service Provider в OpenAM](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-creating-a-service-provider-in-openam)**

1. На панели слева выберите раздел [Федерации](https://org.cloud.yandex.ru/federations) .
2. Нажмите имя федерации, для которой нужно добавить сертификат.
3. Внизу страницы нажмите кнопку **Добавить сертификат**.
4. Введите название и описание сертификата.
5. Нажмите **Выбрать файл** и укажите путь к нему.
6. Нажмите кнопку **Добавить**.
<a name="добавление-пользователей-в-yandex-cloud-organization"></a>

# Cоздание и настройка Service Provider в OpenAM
**[Добавление пользователей в Yandex Cloud Organization](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-adding-users-to-yandex-cloud-organization)**

## Создайте файл метаданных для OpenAM
<a name="проверка-аутентификации"></a>

1. Создайте файл `metadata.xml`со следующим содержимым, где ID_федерации - идентификатор федерации из консоли [Yandex Cloud Organization](https://org.cloud.yandex.ru)s, раздела [Федерации](https://org.cloud.yandex.ru/federations)

```xml
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://console.cloud.yandex.ru/federations/<ID_федерации>">
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://console.cloud.yandex.ru/federations/<ID_федерации>" index="1"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
```

## Создание Service Provider в OpenAM

1. Откройте консоль администратора
2. Перейдите в нужный realm
3. Выберите в разделе Common Tasks **Configure SAMLv2 Provider**
4. Далее **Configure Remote Service Provider**

![SAML Remote Service Provider](https://raw.githubusercontent.com/wiki/OpenIdentityPlatform/OpenAM/images/saml-yandex-cloud/saml-remote-service-provider.png)

1. В качестве метаданных загрузите созданный на предыдущем этапе файл `metadata.xml`
2. Выберите существующий Circle Of Trust, созданный на этапе **Создание и настройка Identity Provider в OpenAM**
3. Нажмите Configure

# ****Добавление пользователей в Yandex Cloud Organization****

При включенной опции **Автоматически создавать пользователей** в федерацию будут добавляться только пользователи, впервые авторизующиеся в облаке. Повторное добавление федеративного пользователя после его удаления из федерации возможно только вручную.

1. [Войдите в аккаунт](https://passport.yandex.ru/) администратора или владельца организации.
2. Перейдите в сервис [Yandex Cloud Organization](https://org.cloud.yandex.ru/).
3. На панели слева выберите раздел [Пользователи](https://org.cloud.yandex.ru/users) .
4. В правом верхнем углу нажмите **Добавить федеративных пользователей**.
5. Выберите федерацию, из которой необходимо добавить пользователей.
6. Введите email адреса пользователей из OpenAM
7. Нажмите кнопку **Добавить**. Пользователи будут подключены к организации.

# **Проверка аутентификации**

Когда вы закончили настройку SSO, протестируйте, что все работает:

1. Откройте браузер в гостевом режиме или режиме инкогнито.
2. Перейдите по URL для входа в консоль:

`https://console.cloud.yandex.ru/federations/<ID_федерации>`

3. Введите данные для аутентификации и нажмите кнопку Login.

После успешной аутентификации IdP-сервер перенаправит вас по URL `https://console.cloud.yandex.ru/federations/<ID_федерации>`, который вы указали файле метаданных для Service Provider в настройках OpenAM, а после — на главную страницу [консоли управления](https://console.cloud.yandex.ru/). В правом верхнем углу вы сможете увидеть, что вошли в консоль от имени федеративного пользователя.
**[Проверка аутентификации](https://doc.openidentityplatform.org/openam/how-to/saml-authentication-in-yandex-cloud-via-openam#saml-authentication-in-yandex-cloud-via-openam-testing-authentication)**