カプチャ
ポータルのアカウントページは誰からの投稿でも受け付けます。スクリプトでアカウントを作成したり、選択したアドレスへのパスワードリセットや確認リンクをポータルに送信したりできます。CAPTCHAは、フォームを送信する前に各訪問者に本人であることを示すよう求めます。Power Portals Proは Cloudflare Turnstile、 Google reCAPTCHA (v2およびv3)、 hCaptchaをサポートしており、設定するまでは使えません。
注記
サーバーはチャレンジをチェックするのであって、ページ自体だけでなく。プロバイダーが設定されると、認証エンドポイントやサーバーレンダリングされたアカウントページは、ブラウザが送信するチャレンジが解決されていない保護フォームの提出を拒否します。
どのフォームが保護されているか
CaptchaOptions.FormsCaptchaForms値の組み合わせでフォームを選択します。デフォルトはパスワードを知らずに自動発信者が悪用できるフォームを保護します。
| キャプチャフォーム | 形式 | デフォルトで |
|---|---|---|
Register |
ローカルアカウントの作成。 | オン |
ForgotPassword |
パスワードリセットリンクをリクエストしています。 | オン |
ResendEmailConfirmation |
もう一つの確認メールリンクをお願いしています。 | オン |
Login |
メールアドレスとパスワードでサインインすること。パスワードの推測を遅らせるためにオンにしてください。繰り返し間違ったパスワードを入力すると、しばらくアカウントがロックされます。 | 消えろ |
ExternalLogin |
Microsoft、Google、または他のプロバイダーが認証しなかったメールアドレスでサインインを行い、ポータルがそのメールアドレスに確認メールを送る場合。プロバイダーが認証したアドレスのサインインは、問題なく完了します。 | 消えろ |
提供者の選択
ポータルに関しては、3つのプロバイダーは同じ仕組みで動作します。訪問者が見るものや、どのアカウントで必要なかが異なります。それぞれに無料プランがあります。
| 提供者 | 必要なアカウント | 訪問者が見るもの | リンク |
|---|---|---|---|
| クラウドフレア・ターンスタイル | 無料のCloudflareアカウント。ポータルはCloudflareでホストされている必要も、そのDNSを使う必要 もありません 。 | 通常は何もすることがありません。チェックは自動で動作し、時折クリックを求めるだけです。 | ダッシュボード · ドキュメント |
| GoogleでreCAPTCHA v2を検索してみてください | Googleアカウント。 | 「私はロボットじゃない」というチェックボックス、時には画像パズルが続きます。 | 管理コンソール · ドキュメント |
| hCaptcha | 無料のhCaptchaアカウント。 | チェックボックス、時には画像パズルが続きます。 | ダッシュボード · ドキュメント |
| GoogleでreCAPTCHA v3を検索してみてください。 | Googleアカウント。 | 何もありません:Googleは各投稿にスコアをつけ、Googleのバッジはページの隅に置かれています。スコアが低すぎる訪問者は拒否され、それ以外の証拠もありません。 | 管理コンソール · ドキュメント |
どちらを選んでも、プロバイダーはサイト用の2つの鍵を渡します。 サイトキーは公開で、すべてのブラウザに送信されてウィジェットを描画します。もうひとつはサーバーのみが訪問者の回答を確認するために使う 秘密鍵です。秘密鍵はソース管理から除外してください。
Cloudflare Turnstile の設定
- dash.cloudflare.com で無料アカウントに登録してください。ウェブサイトの追加やDNSの移動は必要ありません。
- ダッシュボードのメニューから Turnstile を開き、「 Add Widget」を選択してください。
- ウィジェットに名前を付け、ポータルがサービスを提供するすべてのホスト名(本番ドメイン、展開スロット、そして実際のキーでテストした場合の
localhost)を追加します。 - 管理されたウィジェットモードを選びますが、Cloudflareが確信が持てない時だけクリックを求められます。
- ウィジェットを作成し、 そのサイトキー と シークレットキーをコピーします。
Google reCAPTCHA v2の設定方法
- Googleアカウントで reCAPTCHA管理コンソール にサインインし、新しいサイトを作成します。
- チャ レンジ(v2) を選択し、「 私はロボットじゃない」というチェックボックスを選びます。
- ポータルがサービスを提供するすべてのドメインを追加し、実際のキーでテストする場合は
localhostしてください。 - 「 ReCAPTCHA解法の起源を検証」のま まにして、別のサイトで解決されたトークンは拒否されます。サイト 鍵 と 秘密鍵を送信し、コピーします。
重要
プロバイダー
ReCaptchaV2とCaptcha:ReCaptchaV2セクションは、v2の「私はロボットではない」チェックボックスキーにのみ適用してください。それ以外の場合はウィジェットに「無効なキータイプ」が表示されます。v3キーは下記のReCaptchaV3の下にあります;見えないv2バッジはサポートされていません。GoogleはキーをGoogle Cloudプロジェクトに紐付けるよう求めるかもしれませんが、それはポータルの使い方を変えません。
Google reCAPTCHA v3の設定方法
v3ではチャレンジがありません。フォームが提出されると、そのページは元のフォームでタグ付けされるとGoogleにトークンを求めますが、サーバーは MinimumScore 未満のスコアや別のフォームのタグ付きトークンを拒否します。プロバイダー ReCaptchaV3 と独自のセクションを使いましょう。 Captcha:ReCaptchaV3:v3キーはv2キーとは異なるキーです。
- reCAPTCHA管理コンソールで新しいサイトを作成し、「スコアベース(v3)」を選択してください。
- ポータルがサービスを提供するすべてのドメインを追加し、実際の鍵でテストする場合はそれを
localhostしてください。 reCAPTCHAソリューションの出所を検証 する。 - 送信して、 サイトキー と 秘密鍵 を
Captcha:ReCaptchaV3にコピーしてください。 MinimumScoreを0.0から1.0に設定してください。デフォルトはGoogleの推奨スタートポイント0.5です。管理コンソールは訪問者のスコアを表示し、それで調整します。
重要
MinimumScore点未満の訪問者は解答ができず拒否され、すぐに再挑戦するように言われます。慎重に提出し、その後管理者コンソールでスコアを確認してください。Googleはv3のテストキーを公開していません。
hCaptchaの設定
- dashboard.hcaptcha.com で無料アカウントに登録してください。
- 「サイト」の「サイト」で新しいサイトを追加し、そのサイトキーをコピーします。
- サイトの設定で、ポータルがサービスを提供するすべてのホスト名を追加してください。hCaptchaは
localhostや127.0.0.1を受け付けません。実際のキーを自分のマシンで試すには、ホストファイルにdev.example.comto127.0.0.1の名前をマッピングして追加するか、下記のテストキーを使ってください。 - アカウント設定から シークレットキー をコピーしてください(またはダッシュボードにシークレットがあるサイト独自のシークレットキーも含めて)。
ローカル開発のためのテストキー
各プロバイダーは、どのホスト名にも対応できるテストキーのペアを公開しており、 localhost も含めて常に合格します。アカウント作成前にポータルのフォームを試すことができます。ウィジェットはテストモードであることを示しています。
| 提供者 | サイトキー | 秘密鍵 |
|---|---|---|
Turnstile |
1x00000000000000000000AA |
1x0000000000000000000000000000000AA |
ReCaptchaV2 |
6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI |
6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe |
HCaptcha |
10000000-ffff-ffff-ffff-000000000001 |
0x0000000000000000000000000000000000000000 |
重要
テストキーはすべての訪問者を受け入れ、ロボットも含まれます。絶対に展開しないでください。ポータルが稼働する前に自分の鍵に差し替えてください。
ポータルの設定
テンプレートから生成されたプロジェクトは、appsettings.jsonのCaptchaセクションからCaptchaOptionsバインドします。ProviderはNoneに設定されています。各プロバイダーはキー用のセクション(Turnstile、ReCaptchaV2、ReCaptchaV3、HCaptcha)を持ち、Providerがどれを使うかを選びます。複数のキーを設定し、1つの設定で切り替えることができます。各プロバイダーのサイトキーをそのセクションに入れてください。Formsはカンマで区切られた名前の形を取ります。デフォルトを保つために除外してください。
{
"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
}
}
}
開発中は秘密鍵をユーザーシークレットに保存し、展開時はKey VaultやApp Serviceの設定に保管し、 appsettings.jsonには絶対に残さないようにしてください。Key Vaultでは、名前を Captcha--Turnstile--SecretKey にし、以下のように設定してください。
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>"
この Program.cs の行がセクションを読み取っています。テンプレートから生成されていないポータルが AddPowerPortalsProWebServer()の後に追加します:
builder.Services.Configure<CaptchaOptions>(builder.Configuration.GetSection("Captcha"));
または、他のクラスと同様にコードでオプションを設定する IOptions :
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;
});
ヒント
両方のキーを持たないプロバイダーセットは、起動時にポータルを停止し、欠けているものを指定するメッセージでポータルを停止します。すべての訪問者を拒否するフォームから始めるのではなく。
自分のフォームに挑戦を加えること
テンプレートのアカウントページにはすでに掲載されています。自分のフォームには Captcha コンポーネントを配置してください。名前のフォームにチャレンジが必要な場合を除き、フォームが提出された際に渡されるトークンを送ります。Blazorで TakeTokenAsync() 、Reactで参照 takeToken() 。サーバーがチャレンジで拒否した投稿はBlazorで CaptchaVerificationException 、Reactで CaptchaVerificationError します。
const captcha = useRef<CaptchaHandle>(null);
const register = async () => {
try {
await auth.registerAsync({ email, password, captchaToken: (await captcha.current?.takeToken()) ?? null });
} catch (error) {
// 訪問者にチャレンジをもう一度解くよう指示し、リセットします。
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)
{
// 訪問者にチャレンジをもう一度解くよう指示し、リセットします。
await _captcha!.ReportNotSolvedAsync();
}
}
}トークンは1回の投稿に有効なので、それを取るとチャレンジもリセットされます。結果がどうであれ(パスワードの誤りや既使用中のアドレス)、次の挑戦ではページが何も起こらず新しいトークンが発行されます。reCAPTCHA v3ではトークンが取られるまでトークンが存在しないため、 TokenChanged (Blazor)や onTokenChange (React)が報告するまで送信ボタンを押し続けないでください。
サーバーレンダリングされたBlazorページは、IAuthServiceを経ずに自分自身UserManager呼び出し、行動前にICaptchaVerifierでトークンを確認します。
@inject ICaptchaVerifier CaptchaVerifier
if (!await CaptchaVerifier.VerifyAsync(CaptchaForms.Register, await _captcha!.TakeTokenAsync()))
{
await _captcha!.ReportNotSolvedAsync();
return;
}
アドレスごとの試行数制限
CAPTCHAが設定されているかどうかにかかわらず、ポータルはサインインせずに提出できる各フォーム(サインイン、登録、パスワードリセット、確認再送信、招待受諾)を1つのアドレスで送信する頻度を制限しています。デフォルトでは、アドレスは1分間に20回ずつ送信できます。それ以上は1分が経過するまで429 Too Many Requestsで応答されます。各フォームはそれぞれ個別にカウントされます。PowerPortalsPro:SignInRateLimitの制限を変更してください;その0PermitLimitでオフになります。
{
"PowerPortalsPro": {
"SignInRateLimit": {
"PermitLimit": 20,
"Window": "00:01:00"
}
}
}
重要
リミットはリクエストからのアドレスをカウントします。訪問者のアドレスを渡さないプロキシやゲートウェイ(Azure Front Door、Application Gateway、自社のロードバランサーなど)では、すべての訪問者がプロキシから到着し、1つのカウントを共有します。訪問者のアドレスを
UseForwardedHeadersで転送し、プロキシ名を1つにして、その名前をKnownProxiesまたはKnownNetworksで伝えます。
コンテンツセキュリティポリシー
ウィジェットはプロバイダーのサイトから読み込みます。ポータルが Content-Security-Policy ヘッダーを送信する場合は、プロバイダーのホストを script-src と frame-src で許可してください(hCaptchaは style-src と connect-srcも必要です):
| 提供者 | 司会者 |
|---|---|
Turnstile |
https://challenges.cloudflare.com |
ReCaptchaV2 |
https://www.google.com/recaptcha/, https://www.gstatic.com/recaptcha/ |
HCaptcha |
https://hcaptcha.com, https://*.hcaptcha.com |
トラブルシューティング
- すべての投稿は拒否されます。 秘密鍵が誤っているか、別のサイトキーに属しています。サーバーは毎回プロバイダーの苦情を記載したエラーを記録します。
- フォームにはチャレンジが読み込めなかったと記載されています。 プロバイダーのスクリプトがブロックされたか、ブラウザ拡張機能、ネットワークフィルター、コンテンツセキュリティポリシーによってブロックされたか、ブラウザがオフラインになっていること。
- ウィジェットにはドメインに関するエラーが表示されます。 ポータルがサービス提供されるホスト名が、このサイトキーのプロバイダーリストに含まれていません。
- 解決したチャレンジは拒否されます。 トークンは数分後に期限切れとなり、一度だけ使用可能です。ウィジェットは通常自動的に更新されます。訪問者がフォームを開いたままにすると、再度解決します。
- プロバイダーを設定した後もポータルが起動しません。 そのプロバイダーの
SiteKeyやSecretKeyが欠けています(Captcha:Turnstile、Captcha:ReCaptchaV2、Captcha:ReCaptchaV3、Captcha:HCaptchaのいずれか、またはreCAPTCHA v3の場合、MinimumScoreが0から1の間にはありません。起動エラーはどのオプションが失敗したかを示しています。
