CAPTCHA
Les pages de compte d’un portail acceptent les soumissions de n’importe qui : un script peut créer des comptes, ou faire en sorte que le portail pose un mot de passe réinitialisé et des liens de confirmation vers les adresses qu’il choisit. Un CAPTCHA demande à chaque visiteur de prouver qu’il est une personne avant l’envoi du formulaire. Power Portals Pro prend en charge Cloudflare Turnstile, Google reCAPTCHA (v2 et v3) et hCaptcha, et reste désactivé jusqu’à ce que vous en configuriez un.
Note
Le serveur vérifie le défi, pas seulement la page. Une fois un fournisseur configuré, les terminaux d’authentification et les pages de compte rendues par le serveur refusent la soumission d’un formulaire protégé sans problème résolu, quel que soit l’envoi du navigateur.
Quelles formes sont protégées
CaptchaOptions.Forms choisit les formulaires, sous forme de combinaison de CaptchaForms valeurs. Le code par défaut protège les formulaires qu’un appelant automatisé peut abuser sans connaître de mot de passe.
| CaptchaForms | Forme | Par défaut |
|---|---|---|
Register |
Créer un compte local. | On |
ForgotPassword |
Demande un lien de réinitialisation du mot de passe. | On |
ResendEmailConfirmation |
Je demande un autre lien de confirmation par e-mail. | On |
Login |
Se connecter avec une adresse e-mail et un mot de passe. Activez-le pour ralentir la devinette de mot de passe ; les mots de passe incorrects répétés bloquent aussi le compte pendant un moment. | Off |
ExternalLogin |
Effectuer une connexion via Microsoft, Google ou un autre fournisseur avec une adresse e-mail que le fournisseur n’a pas vérifiée, à laquelle le portail envoie ensuite une confirmation par courrier. Une connexion dont l’adresse a été vérifiée par le fournisseur se termine sans contestation. | Off |
Choix d’un prestataire
Les trois fournisseurs fonctionnent de la même manière en ce qui concerne le portail ; ils diffèrent dans ce que le visiteur voit et dans le compte dont vous avez besoin. Chacun dispose d’un palier gratuit.
| Fournisseur | Compte dont vous avez besoin | Ce que le visiteur voit | Liens |
|---|---|---|---|
| Tourniquet de Cloudflare | Un compte Cloudflare gratuit. Votre portail n’a pas besoin d’être hébergé sur Cloudflare ni d’utiliser son DNS. | En général, il n’y a rien à faire : le contrôle se déroule seul et ne demande un clic qu’occasionnellement. | Tableau de bord · Documentation |
| Cherchez reCAPTCHA v2 sur Google | Un compte Google. | La case à cocher « Je ne suis pas un robot », parfois accompagnée d’un puzzle d’images. | Console d’administration · Documentation |
| hCaptcha | Un compte hCaptcha gratuit. | Une case à cocher, parfois suivie d’un puzzle d’images. | Tableau de bord · Documentation |
| Cherche sur Google reCAPTCHA v3 | Un compte Google. | Rien du tout : Google note chaque soumission, et le badge de Google est placé dans le coin de la page. Un visiteur qui a obtenu un score trop bas est refusé et ne peut pas prouver le contraire. | Console d’administration · Documentation |
Quelle que soit votre option, le fournisseur vous donne deux clés pour votre site : une clé de site, publique et envoyée à tous les navigateurs pour dessiner le widget, et une clé secrète, que seul le serveur utilise pour vérifier la réponse d’un visiteur. Gardez la clé secrète hors du contrôle de version.
Installation du tourniquet Cloudflare
- Inscrivez-vous gratuitement sur dash.cloudflare.com. Vous n’avez pas besoin d’ajouter un site web ni de déplacer un DNS.
- Ouvre Tourniquet depuis le menu du tableau de bord et choisis Ajouter widget.
- Nommez le widget et ajoutez tous les noms d’hôte d’où le portail est servi — son domaine de production, n’importe quel emplacement de déploiement, et
localhostsi vous testez avec de vraies clés. - Choisissez le mode widget géré, qui ne demande un clic que lorsque Cloudflare n’est pas sûr.
- Créez le widget et copiez sa clé du site et sa clé secrète.
Configuration de Google reCAPTCHA v2
- Connectez-vous à la console d’administration reCAPTCHA avec un compte Google et créez un nouveau site.
- Choisissez Défi (v2) puis la case « Je ne suis pas un robot ».
- Ajoutez tous les domaines d’où le portail est servi, et
localhostsi vous testez avec de vraies clés. - Laissez Verify the origin of reCAPTCHA activat, afin qu’un jeton résolu sur un autre site soit refusé. Soumettez, et copiez la clé du site ainsi que la clé secrète.
Important
Utilisez fournisseur
ReCaptchaV2et laCaptcha:ReCaptchaV2section uniquement pour une case à cocher v2 « Je ne suis pas un robot » — le widget affiche « Type de clé invalide » pour toute autre. Une clé v3 va sousReCaptchaV3, ci-dessous ; le badge v2 invisible n’est pas pris en charge. Google peut vous demander d’associer la clé à un projet Google Cloud ; cela ne change rien à la façon dont le portail l’utilise.
Configuration de Google reCAPTCHA v3
la version 3 ne montre aucun défi. La page demande à Google un jeton lorsque le formulaire est soumis, tagué avec le formulaire dont il provine, et le serveur refuse un jeton noté ci-dessous MinimumScore ou tagué pour un autre formulaire. Utilisez le fournisseur ReCaptchaV3 et sa propre section : Captcha:ReCaptchaV3une clé v3 est une clé différente d’une clé v2.
- Dans la console d’administration reCAPTCHA, créez un nouveau site et choisissez Score based (v3).
- Ajoutez tous les domaines d’où le portail est servi, et
localhostsi vous testez avec de vraies clés. Laissez Vérifier l’origine des solutions reCAPTCHA activé. - Soumettez, et copiez la clé du site et la clé secrète dans
Captcha:ReCaptchaV3. - Régler
MinimumScore, de 0.0 à 1.0. Par défaut, il est 0.5, le point de départ suggéré par Google ; la console d’administration affiche les scores obtenus par vos visiteurs, pour les ajuster.
Important
Un visiteur noté ci-dessous
MinimumScoreest refusé sans rien à résoudre, et on lui dit de réessayer dans un instant. Augmentez-le avec précaution, et regardez les scores dans la console d’administration après avoir fait cela. Google ne publie aucune clé de test pour la v3.
Mise en place de hCaptcha
- Inscrivez-vous gratuitement sur dashboard.hcaptcha.com.
- Dans Sites, ajoutez un nouveau site et copiez sa clé de site.
- Dans les paramètres du site, ajoutez tous les noms d’hôte d’où le portail est servi. hCaptcha n’accepte
localhostpas ou127.0.0.1: pour essayer de vraies clés sur votre machine, mappez un nom tel quedev.example.comto127.0.0.1dans le fichier de vos hôtes et ajoutez-le, ou utilisez les clés de test ci-dessous. - Copiez la clé secrète depuis les paramètres de votre compte (ou le secret propre du site, où le tableau de bord en propose une).
Clés de test pour le développement local
Chaque fournisseur publie une paire de clés de test qui fonctionnent sur n’importe quel nom d’hôte, localhost y compris, et qui passent toujours — vous pouvez donc tester les formulaires du portail avant de créer un compte. Le widget indique qu’il est en mode test.
| Fournisseur | Clé du site | Clé secrète |
|---|---|---|
Turnstile |
1x00000000000000000000AA |
1x0000000000000000000000000000000AA |
ReCaptchaV2 |
6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI |
6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe |
HCaptcha |
10000000-ffff-ffff-ffff-000000000001 |
0x0000000000000000000000000000000000000000 |
Important
Les clés de test acceptent tous les visiteurs, robots inclus. Ne les déployez jamais : remplacez-les par vos propres clés avant que le portail ne soit opérationnel.
Configuration du portail
Les projets générés à partir des modèles se lient CaptchaOptions à partir de la Captcha section de appsettings.json, qui commence par Provider définir à None. Chaque fournisseur a sa propre section pour ses clés — Turnstile, ReCaptchaV2, ReCaptchaV3 et HCaptcha — et Provider choisit laquelle est utilisée, ce qui permet de garder plusieurs configurées et de basculer entre elles avec un seul réglage. Mettez la clé de site de chaque fournisseur dans sa section. Forms Prend les noms du formulaire séparés par des virgules ; laissez-le de côté pour garder le défaut.
{
"Captcha": {
"Provider": "Turnstile",
"Forms": "Register, ForgotPassword, ResendEmailConfirmation",
"Turnstile": {
"SiteKey": "<Turnstile site key>"
},
"ReCaptchaV2": {
"SiteKey": "<reCAPTCHA v2 site key>"
},
"ReCaptchaV3": {
"SiteKey": "<reCAPTCHA v3 site key>",
"MinimumScore": 0.5
}
}
}
Gardez les clés secrètes dans les secrets utilisateur pendant le développement, ainsi que dans Key Vault ou les paramètres de l’App Service lors du déploiement — jamais dans appsettings.json. Dans Key Vault, nommez-les Captcha--Turnstile--SecretKey , etc. :
dotnet user-secrets set "Captcha:Turnstile:SecretKey" "<Turnstile secret key>"
dotnet user-secrets set "Captcha:ReCaptchaV2:SecretKey" "<reCAPTCHA v2 secret key>"
dotnet user-secrets set "Captcha:ReCaptchaV3:SecretKey" "<reCAPTCHA v3 secret key>"
dotnet user-secrets set "Captcha:HCaptcha:SecretKey" "<hCaptcha secret key>"
C’est la ligne Program.cs qui lit la section. Un portail qui n’a pas été généré à partir d’un modèle l’ajoute après AddPowerPortalsProWebServer():
builder.Services.Configure<CaptchaOptions>(builder.Configuration.GetSection("Captcha"));
Ou définissez les options dans le code, comme n’importe quelle autre IOptions classe :
builder.Services.Configure<CaptchaOptions>(options =>
{
options.Provider = CaptchaProvider.HCaptcha;
options.HCaptcha.SiteKey = "<site key>";
options.HCaptcha.SecretKey = builder.Configuration.GetRequiredValue("Captcha:HCaptcha:SecretKey");
options.Forms = CaptchaForms.Register | CaptchaForms.ForgotPassword | CaptchaForms.Login;
});
Conseil
Un fournisseur sans ses deux clés arrête le portail au démarrage avec un message indiquant ce qui manque, au lieu de commencer par des formulaires qui refuseraient tous les visiteurs.
Ajouter le défi à vos propres formulaires
Les pages de compte du modèle le contiennent déjà. Sur un formulaire à vous, placez le Captcha composant — il ne rend rien sauf si le formulaire que vous nommez nécessite un défi — et envoyez le jeton qu’il remet lors de la soumission du formulaire : TakeTokenAsync() dans Blazor, takeToken() sur le référent dans React. Une soumission refusée par le serveur pour le défi apparaît CaptchaVerificationException dans Blazor et CaptchaVerificationError dans React.
const captcha = useRef<CaptchaHandle>(null);
const register = async () => {
try {
await auth.registerAsync({ email, password, captchaToken: (await captcha.current?.takeToken()) ?? null });
} catch (error) {
// Il dit au visiteur de résoudre à nouveau le défi, puis le réinitialise.
if (error instanceof CaptchaVerificationError) captcha.current?.reportNotSolved();
}
};
<Captcha ref={captcha} form={CaptchaForms.Register} /><Captcha @ref="_captcha" Form="CaptchaForms.Register" />
@code {
private Captcha? _captcha;
private async Task RegisterAsync()
{
try
{
await AuthService.RegisterAsync(new RegisterRequest
{
Email = _email,
Password = _password,
CaptchaToken = await _captcha!.TakeTokenAsync(),
});
}
catch (CaptchaVerificationException)
{
// Il dit au visiteur de résoudre à nouveau le défi, puis le réinitialise.
await _captcha!.ReportNotSolvedAsync();
}
}
}Un jeton est bon pour une soumission, donc le prendre réinitialise aussi le défi : quel que soit le résultat — un mauvais mot de passe, une adresse déjà utilisée — la tentative suivante en obtient un nouveau sans que la page ne fasse rien. Sous reCAPTCHA v3, il n’y a pas de jeton tant qu’il n’est pas pris, donc ne maintenez pas un bouton d’envoi avant TokenChanged que (Blazor) ou onTokenChange (React) en signalent un.
Une page Blazor rendue par serveur qui s’appelle UserManager elle-même, plutôt que de passer par IAuthService, vérifie le jeton avant ICaptchaVerifier d’agir :
@inject ICaptchaVerifier CaptchaVerifier
if (!await CaptchaVerifier.VerifyAsync(CaptchaForms.Register, await _captcha!.TakeTokenAsync()))
{
await _captcha!.ReportNotSolvedAsync();
return;
}
Limiter les tentatives par adresse
Qu’un CAPTCHA soit configuré ou non, le portail limite la fréquence à laquelle une adresse soumet chaque formulaire que quelqu’un peut soumettre sans se connecter — connexion, inscription, réinitialisation d’un mot de passe, réenvoi d’une confirmation, acceptation d’une invitation. Par défaut, une adresse peut soumettre chaque adresse 20 fois par minute ; au-delà, elle est répondue par 429 Too Many Requests jusqu’à la fin de la minute. Chaque formulaire est compté seul. Changez la limite sous PowerPortalsPro:SignInRateLimit; a PermitLimit de 0 le désactive.
{
"PowerPortalsPro": {
"SignInRateLimit": {
"PermitLimit": 20,
"Window": "00:01:00"
}
}
}
Important
La limite compte l’adresse d’où provient une requête. Derrière un proxy ou une passerelle qui ne transmet pas l’adresse du visiteur — Azure Front Door, Application Gateway, un balanceur de charge à votre propre — chaque visiteur arrive depuis les proxys, et ils partagent un compte. Transférez l’adresse du visiteur avec
UseForwardedHeaders, en nommant le proxy dansKnownProxiesouKnownNetworks.
Politique de sécurité du contenu
Le widget est chargé depuis le site du fournisseur. Si votre portail envoie un Content-Security-Policy en-tête, autorisez les hôtes du fournisseur à entrer script-src et frame-src (hCaptcha nécessite style-src également et connect-src) :
| Fournisseur | Animateurs |
|---|---|
Turnstile |
https://challenges.cloudflare.com |
ReCaptchaV2 |
https://www.google.com/recaptcha/, https://www.gstatic.com/recaptcha/ |
HCaptcha |
https://hcaptcha.com, https://*.hcaptcha.com |
Dépannage
- Chaque soumission est refusée. La clé secrète est incorrecte, ou appartient à une autre clé de site. Le serveur enregistre une erreur nommant la plainte du fournisseur à chaque fois.
- Le formulaire indique que le défi n’a pas pu être chargé. Le script du fournisseur a été bloqué — par une extension de navigateur, un filtre réseau ou une politique de sécurité de contenu — ou bien le navigateur est hors ligne.
- Le widget affiche une erreur concernant le domaine. Le nom d’hôte d’où le portail est servi n’apparaît pas dans la liste du fournisseur pour cette clé de site.
- Un défi résolu est refusé. Les jetons expirent après quelques minutes et peuvent être utilisés une seule fois. Le widget se renouvelle généralement lui-même ; si un visiteur laisse le formulaire ouvert, il le résout à nouveau.
- Le portail ne démarre pas après avoir défini un fournisseur. Celui de
SiteKeyce fournisseur ouSecretKeymanque — sousCaptcha:Turnstile,Captcha:ReCaptchaV2,Captcha:ReCaptchaV3ouCaptcha:HCaptcha— ou, pour reCAPTCHA v3,MinimumScoren’est pas entre 0 et 1. L’erreur de démarrage indique quelles options ont échoué.
