Skip to content

Commit

Permalink
feat: acr can be used to force identity with IAL=2
Browse files Browse the repository at this point in the history
  • Loading branch information
rdubigny committed Oct 18, 2024
1 parent bc4c527 commit 4d1a73b
Show file tree
Hide file tree
Showing 18 changed files with 452 additions and 40 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/end-to-end.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
- signin_from_standard_client
- signin_with_email_verification_renewal
- signin_with_magic_link
- signin_with_right_acr
- signin_with_totp
- signup_entreprise_unipersonnelle
- update_personal_information
Expand Down Expand Up @@ -95,6 +96,19 @@ jobs:
MCP_PROVIDER: ${{ env.MONCOMPTEPRO_HOST }}
MCP_SCOPES: openid email profile phone organizations
STYLESHEET_URL: ""
moncomptepro-acr-client:
image: ghcr.io/numerique-gouv/moncomptepro-test-client
ports:
- 4003:3000
environment:
SITE_TITLE: moncomptepro-acr-client
HOST: http://localhost:4003
MCP_CLIENT_ID: acr_client_id
MCP_CLIENT_SECRET: acr_client_secret
MCP_PROVIDER: ${{ env.MONCOMPTEPRO_HOST }}
MCP_SCOPES: openid email profile organization
ACR_VALUE_FOR_2FA: urn:dinum:ac:classes:consistency-checked
STYLESHEET_URL: ""
redis:
image: redis:7.2
ports:
Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,21 @@ d’usurpations d’identités liés aux attaques par _phishing_ par exemple.

Vous pouvez tester la cinématique via le lien suivant : https://test.moncomptepro.beta.gouv.fr/#force-2fa

Pour ce faire, vous devez passer les paramètres `claims={"id_token":{"acr":{"essential":true,value:"https://refeds.org/profile/mfa"}}}` comme suit :
Pour ce faire, vous devez passer les paramètres `claims={"id_token":{"acr":{"essential":true,value:"urn:dinum:ac:classes:consistency-checked-2fa"}}}` comme suit :

https://app-sandbox.moncomptepro.beta.gouv.fr/oauth/authorize?client_id=client_id&scope=openid%20email%20profile%20organization&response_type=code&redirect_uri=https%3A%2F%2Ftest.moncomptepro.beta.gouv.fr%2Flogin-callback&claims=%7B%22id_token%22%3A%7B%22acr%22%3A%7B%22essential%22%3Atrue%2C%22value%22%3A%22https%3A%2F%2Frefeds.org%2Fprofile%2Fmfa%22%7D%7D%7D

Les valeurs `acr` utilisées par ProConnect Identité sont les suivantes :

- `eidas1` authentification simple facteur avec une identité de niveau faible.
- `https://refeds.org/profile/mfa` authentification par double facteur sans preuve d’identité particulière.
- `eidas1` authentification simple facteur avec une identité de niveau faible ;
- `urn:dinum:ac:classes:self-asserted` : identité déclarative ;
- `urn:dinum:ac:classes:self-asserted-2fa` : identité déclarative ;
- `urn:dinum:ac:classes:consistency-checked` : identité déclarative + un des tests de cohérence suivant :
- contrôle du référencement du nom de domaine
- code à usage unique envoyé par courrier postal au siège social
- code à usage unique envoyé par email à l'adresse de contact référencée dans un annuaire de référence
- identité du dirigeant d'association conforme
- `urn:dinum:ac:classes:consistency-checked-2fa` : `urn:dinum:ac:classes:consistency-checked` + authentification à double facteur

## 3. 👋 Contribuer à ProConnect Identité

Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/signin_with_right_acr/env.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DO_NOT_SEND_MAIL="True"
57 changes: 57 additions & 0 deletions cypress/e2e/signin_with_right_acr/fixtures.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
INSERT INTO users
(id, email, email_verified, email_verified_at, encrypted_password, created_at, updated_at,
given_name, family_name, phone_number, job, encrypted_totp_key, totp_key_verified_at, force_2fa)
VALUES
(1, '[email protected]', true, CURRENT_TIMESTAMP,
'$2a$10$kzY3LINL6..50Fy9shWCcuNlRfYq0ft5lS.KCcJ5PzrhlWfKK4NIO', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP,
'Jean', 'IAL2 AAL2', '0123456789', 'Sbire',
'kuOSXGk68H2B3pYnph0uyXAHrmpbWaWyX/iX49xVaUc=.VMPBZSO+eAng7mjS.cI2kRY9rwhXchcKiiaMZIg==',
CURRENT_TIMESTAMP, false
),
(2, '[email protected]', true, CURRENT_TIMESTAMP,
'$2a$10$kzY3LINL6..50Fy9shWCcuNlRfYq0ft5lS.KCcJ5PzrhlWfKK4NIO', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP,
'Jean', 'IAL1 AAL2', '0123456789', 'Sbire',
'kuOSXGk68H2B3pYnph0uyXAHrmpbWaWyX/iX49xVaUc=.VMPBZSO+eAng7mjS.cI2kRY9rwhXchcKiiaMZIg==',
CURRENT_TIMESTAMP, false
),
(3, '[email protected]', true, CURRENT_TIMESTAMP,
'$2a$10$kzY3LINL6..50Fy9shWCcuNlRfYq0ft5lS.KCcJ5PzrhlWfKK4NIO', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP,
'Jean', 'IAL2 AAL1', '0123456789', 'Sbire',
null, null, false),
(4, '[email protected]', true, CURRENT_TIMESTAMP,
'$2a$10$kzY3LINL6..50Fy9shWCcuNlRfYq0ft5lS.KCcJ5PzrhlWfKK4NIO', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP,
'Jean', 'IAL1 AAL1', '0123456789', 'Sbire',
null, null, false);

INSERT INTO organizations
(id, siret, created_at, updated_at)
VALUES
(1, '21340126800130', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

INSERT INTO users_organizations
(user_id, organization_id, is_external, verification_type, has_been_greeted)
VALUES
(1, 1, false, 'domain', true),
(2, 1, false, null, true),
(3, 1, false, 'domain', true),
(4, 1, false, null, true);

INSERT INTO oidc_clients
(client_name, client_id, client_secret, redirect_uris,
post_logout_redirect_uris, scope, client_uri, client_description,
userinfo_signed_response_alg, id_token_signed_response_alg,
authorization_signed_response_alg, introspection_signed_response_alg)
VALUES
('Oidc Test Client',
'acr_client_id',
'acr_client_secret',
ARRAY [
'http://localhost:4003/login-callback'
],
ARRAY [
'http://localhost:4003/'
],
'openid email profile organization',
'http://localhost:4003/',
'MonComptePro test client. More info: https://github.com/numerique-gouv/moncomptepro-test-client.',
null, 'RS256', null, null);
31 changes: 31 additions & 0 deletions cypress/e2e/signin_with_right_acr/index.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//

describe("sign-in with a client requiring consistency-checked identity", () => {
it("should sign-in an return the right acr value", function () {
cy.visit("http://localhost:4003");
cy.get("button#force-2fa").click();

cy.login("[email protected]");

cy.contains('"acr": "urn:dinum:ac:classes:consistency-checked"');
});
it("should return an error with ial1", function () {
cy.visit("http://localhost:4003");
cy.get("button#force-2fa").click();

cy.login("[email protected]");

cy.contains("access_denied (none of the requested ACRs could be obtained)");
});

// TODO add tests:
// - log with a client requiring consistency-checked and consistency-checked-mfa
// - with a consistency checked user and MFA => see the right acr returned
// - with a self-asserted user and MFA => see an error
// - log with a client not requiring any acr
// - with a self-asserted user => see acr self-asserted
// - with a consistency checked user => see acr consistency-checked
// - log with acr_values=eidas1 and ENABLE_FIXED_ACR=True
// - with all type of acr => see the right acr
// these tests required the mcp-test-client to be modifiable like fc-mock
});
23 changes: 22 additions & 1 deletion cypress/e2e/signin_with_totp/index.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ describe("sign-in with TOTP on untrusted browser", () => {

cy.login("[email protected]");

cy.contains("Vérifier votre email");
// TODO get browser enrollment code

cy.contains("moncomptepro-standard-client");
});

it("should sign-in with password and TOTP when forced by SP", function () {
Expand All @@ -26,6 +28,25 @@ describe("sign-in with TOTP on untrusted browser", () => {
cy.contains('"amr": [\n "pwd",\n "totp",\n "mfa"\n ],');
});

it("should only show totp step when already logged", function () {
cy.visit("http://localhost:4000");
cy.get("button.proconnect-button").click();

cy.login("[email protected]");

// TODO get browser enrollment code

cy.contains("moncomptepro-standard-client");

cy.get("button#force-2fa").click();

cy.contains("merci de valider votre deuxième étape de connexion");

cy.fillTotpFields();

cy.contains('"amr": [\n "pwd",\n "totp",\n "mfa"\n ],');
});

it("should trigger totp rate limiting", function () {
cy.visit("/users/start-sign-in");

Expand Down
14 changes: 14 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ services:
STYLESHEET_URL:
network_mode: "host"

moncomptepro-acr-client:
image: ghcr.io/numerique-gouv/moncomptepro-test-client
environment:
PORT: 4003
SITE_TITLE: moncomptepro-acr-client
HOST: http://localhost:4003
MCP_CLIENT_ID: acr_client_id
MCP_CLIENT_SECRET: acr_client_secret
MCP_PROVIDER: http://localhost:3000
MCP_SCOPES: openid email profile organization
ACR_VALUE_FOR_2FA: urn:dinum:ac:classes:consistency-checked
STYLESHEET_URL:
network_mode: "host"

maildev:
image: soulteary/maildev
network_mode: "host"
Expand Down
4 changes: 4 additions & 0 deletions src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export const {
ACCESS_LOG_PATH,
API_AUTH_PASSWORD,
API_AUTH_USERNAME,
ACR_VALUE_FOR_IAL1_AAL1,
ACR_VALUE_FOR_IAL1_AAL2,
ACR_VALUE_FOR_IAL2_AAL1,
ACR_VALUE_FOR_IAL2_AAL2,
BREVO_API_KEY,
CRISP_BASE_URL,
CRISP_IDENTIFIER,
Expand Down
12 changes: 12 additions & 0 deletions src/config/env.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ export const secretEnvSchema = z.object({

export const paramsEnvSchema = z.object({
ACCESS_LOG_PATH: z.string().optional(),
ACR_VALUE_FOR_IAL1_AAL1: z
.string()
.default("urn:dinum:ac:classes:self-asserted"),
ACR_VALUE_FOR_IAL1_AAL2: z
.string()
.default("urn:dinum:ac:classes:self-asserted-2fa"),
ACR_VALUE_FOR_IAL2_AAL1: z
.string()
.default("urn:dinum:ac:classes:consistency-checked"),
ACR_VALUE_FOR_IAL2_AAL2: z
.string()
.default("urn:dinum:ac:classes:consistency-checked-2fa"),
DEPLOY_ENV: z.enum(["preview", "production", "sandbox"]).default("preview"),
DIRTY_DS_REDIRECTION_URL: z
.string()
Expand Down
14 changes: 13 additions & 1 deletion src/config/oidc-provider-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import epochTime from "../services/epoch-time";
import { findAccount } from "../services/oidc-account-adapter";
import policy from "../services/oidc-policy";
import { renderWithEjsLayout } from "../services/renderer";
import {
ACR_VALUE_FOR_IAL1_AAL1,
ACR_VALUE_FOR_IAL1_AAL2,
ACR_VALUE_FOR_IAL2_AAL1,
ACR_VALUE_FOR_IAL2_AAL2,
} from "./env";

//

Expand All @@ -13,7 +19,13 @@ export const oidcProviderConfiguration = ({
shortTokenTtlInSeconds = 10 * 60,
tokenTtlInSeconds = 60 * 60,
}): Configuration => ({
acrValues: ["eidas1", "https://refeds.org/profile/mfa"],
acrValues: [
"eidas1",
ACR_VALUE_FOR_IAL1_AAL1,
ACR_VALUE_FOR_IAL1_AAL2,
ACR_VALUE_FOR_IAL2_AAL1,
ACR_VALUE_FOR_IAL2_AAL2,
],
claims: {
amr: null,
// claims definitions can be found here: https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
Expand Down
Loading

0 comments on commit 4d1a73b

Please sign in to comment.