コンテンツにスキップ

.NET

パッケージ: Tenon.Auth 1.0.0。

  • 対象: .NET 8 以降と、.NET Framework 4.7.2 以降向けの .NET Standard 2.0。
  • 依存関係: .NET 8 以降はなし。.NET Standard 2.0 では System.Text.Json。
  • スレッド: クライアントはスレッドセーフなので、シングルトンとして登録してください。

ダウンロードからパッケージを取得し、SHA-256 を確認してフォルダーに置き、ローカルのソースとして追加します:

ターミナルウィンドウ
dotnet nuget add source ./packages --name local
dotnet add package Tenon.Auth --version 1.0.0
builder.Services.AddSingleton(new TenonAuthClient(new TenonAuthClientOptions
{
BaseUrl = builder.Configuration["TenonAuth:Url"], // https://api.glow-kin.com
ApiKey = builder.Configuration["TenonAuth:ApiKey"], // ユーザーシークレット、Key Vault
}));
// ロードバランサーの背後で、訪問者の IP アドレスを得るために:
builder.Services.Configure<ForwardedHeadersOptions>(o => o.ForwardedHeaders = ForwardedHeaders.XForwardedFor);

オプション:

  • Timeout(30秒)と ConnectTimeout(5秒)
  • Headers
  • 独自の HttpClient:new TenonAuthClient(options, httpClient)(IHttpClientFactory からなど。リダイレクトは無効にしてください)
[HttpPost("/login")]
public async Task<IActionResult> Login(LoginForm form)
{
var account = await _accounts.CheckPasswordAsync(form.Username, form.Password); // あなたの処理
SecondStep step;
try
{
step = await _tenonAuth.BeginSecondStepAsync(account.Id.ToString(),
new SignInContext(HttpContext.Connection.RemoteIpAddress?.ToString(), Request.Headers.UserAgent),
Request.Cookies["tenon_device"]);
}
catch (TenonAuthUnavailableException)
{
return EmergencyOrRefuse(account); // フェイルクローズ
}
HttpContext.Session.SetString("SecondStep", JsonSerializer.Serialize(step));
return step.Kind switch
{
SecondStepKind.CodeEntry => Redirect("/login/code"),
SecondStepKind.PushWait => Redirect("/login/approve"),
SecondStepKind.RecoveryOnly => Redirect("/login/recover"),
_ => await SignInAsync(account), // Trusted または NoMethod
};
}
[HttpPost("/login/code")]
public async Task<IActionResult> Code(string code)
{
var step = JsonSerializer.Deserialize<SecondStep>(HttpContext.Session.GetString("SecondStep")!)!;
var result = await _tenonAuth.CompleteWithCodeAsync(step, code);
if (result.Approved) return await SignInAsync(step.UserId);
if (result.Status == SecondStepStatus.WrongCode) return Redirect($"/login/code?left={result.AttemptsRemaining}");
return Redirect("/login"); // Failed、Expired
}

待機画面では2秒ごとに PollApprovalAsync(step)、リカバリー画面では CompleteWithRecoveryCodeAsync(step, code) を呼びます。

すべて TenonAuthException のサブクラスです:

  • TenonAuthUnavailableException(Reason)
  • ApiKeyRejectedException、ForbiddenException
  • InvalidRequestException、NotFoundException、InvalidCodeException
  • FactorLockedException、TooManyRequestsException
  • EmailRefusedException、EmailUnavailableException
  • ConflictException

エラーを参照してください。