Auth
TsgcHTMLAuth: sgcHTML アプリケーション向けの、サーバーサイドのセッション、ログイン状態、CSRF 保護を、Delphi、C++ Builder、.NET で提供します。
TsgcHTMLAuth: sgcHTML アプリケーション向けの、サーバーサイドのセッション、ログイン状態、CSRF 保護を、Delphi、C++ Builder、.NET で提供します。
すべてのリクエストについて、セッション Cookie、サインイン中のユーザー、CSRF トークンを管理する非ビジュアルコンポーネントです。セッションストアを割り当て、OnAuthenticate を処理してパスワードを確認し、HTMX エンジンの Auth プロパティを設定して、ルートに RequireLogin を指定します。sgcHTML の一部で、sgcHTML はスタンドアロンのパックとして独立して販売されています。
TsgcHTMLAuth、TsgcHTMLSessionStore_Memory、TsgcHTMLSessionStore_File、TsgcHTMLSession(ユニットは sgcHTML_Auth と sgcHTML_Session)
マークアップなし: セッション Cookie、CSRF トークン、ログインへのリダイレクト
Delphi, C++ Builder, .NET
セッションストアを割り当て、OnAuthenticate を処理し、エンジンの Auth を設定して、保護するルートを指定します。以降、エンジンはすべてのリクエストのセッションを読み取り、CSRF トークンを確認し、未認証のユーザーを LoginPath にリダイレクトします。
uses
sgcHTML_Session, sgcHTML_Auth, sgcHTMX_Router, sgcHTMX_Engine_Server;
// oHTMX is a TsgcHTMX_Engine_Server, oRouter is a TsgcHTMX_Router
var
oStore: TsgcHTMLSessionStore_Memory;
oAuth: TsgcHTMLAuth;
oRoute: TsgcHTMX_Route;
begin
oStore := TsgcHTMLSessionStore_Memory.Create(Self);
oStore.SweepInterval := 60;
oAuth := TsgcHTMLAuth.Create(Self);
oAuth.SessionStore := oStore;
oAuth.IdleTimeout := 1800; // seconds without a request
oAuth.AbsoluteTimeout := 43200; // seconds since sign-in
oAuth.LoginRateLimit.MaxAttempts := 5;
oAuth.OnAuthenticate := AuthAuthenticate;
oHTMX.Auth := oAuth;
// only a signed-in user reaches /orders
oRoute := oRouter.Routes.Add;
oRoute.Path := '/orders';
oRoute.RequireLogin := True;
oRoute.OnRoute := OrdersRoute;
// only a session with one of these roles reaches /admin
oRoute := oRouter.Routes.Add;
oRoute.Path := '/admin';
oRoute.RequireRoles := 'admin,manager';
oRoute.OnRoute := AdminRoute;
end;
procedure TForm1.AuthAuthenticate(Sender: TObject;
const aUser, aPassword: string; var aAccept: Boolean;
var aUserID, aDisplayName: string; const aRoles: TStrings);
begin
// LoadPasswordHash reads the value stored when the user was created
aAccept := sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
if aAccept then
begin
aUserID := aUser;
aDisplayName := aUser;
aRoles.Add('admin');
end;
end;
// when you create a user, store this hash, never the password
vHash := sgcHTMLPasswordHash('secret');
// includes: sgcHTML_Session.hpp, sgcHTML_Auth.hpp, sgcHTMX_Router.hpp, sgcHTMX_Engine_Server.hpp
// oHTMX is a TsgcHTMX_Engine_Server, oRouter is a TsgcHTMX_Router
TsgcHTMLSessionStore_Memory *oStore = new TsgcHTMLSessionStore_Memory(this);
oStore->SweepInterval = 60;
TsgcHTMLAuth *oAuth = new TsgcHTMLAuth(this);
oAuth->SessionStore = oStore;
oAuth->IdleTimeout = 1800; // seconds without a request
oAuth->AbsoluteTimeout = 43200; // seconds since sign-in
oAuth->LoginRateLimit->MaxAttempts = 5;
oAuth->OnAuthenticate = AuthAuthenticate;
oHTMX->Auth = oAuth;
// only a signed-in user reaches /orders
TsgcHTMX_Route *oRoute = oRouter->Routes->Add();
oRoute->Path = "/orders";
oRoute->RequireLogin = true;
oRoute->OnRoute = OrdersRoute;
// only a session with one of these roles reaches /admin
oRoute = oRouter->Routes->Add();
oRoute->Path = "/admin";
oRoute->RequireRoles = "admin,manager";
oRoute->OnRoute = AdminRoute;
void __fastcall TForm1::AuthAuthenticate(TObject *Sender,
const UnicodeString aUser, const UnicodeString aPassword, bool &aAccept,
UnicodeString &aUserID, UnicodeString &aDisplayName, TStrings *const aRoles)
{
// LoadPasswordHash reads the value stored when the user was created
aAccept = sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
if (aAccept)
{
aUserID = aUser;
aDisplayName = aUser;
aRoles->Add("admin");
}
}
// when you create a user, store this hash, never the password
String hash = sgcHTMLPasswordHash("secret");
using esegece.sgcWebSockets;
// htmx is a TsgcHTMX_Engine_Server, router is a TsgcHTMX_Router
var store = new TsgcHTMLSessionStore_Memory();
store.SweepInterval = 60;
var auth = new TsgcHTMLAuth();
auth.SessionStore = store;
auth.IdleTimeout = 1800; // seconds without a request
auth.AbsoluteTimeout = 43200; // seconds since sign-in
auth.LoginRateLimit.MaxAttempts = 5;
auth.OnAuthenticate += AuthAuthenticate;
htmx.Auth = auth;
// only a signed-in user reaches /orders
var route = router.Routes.Add();
route.Path = "/orders";
route.RequireLogin = true;
route.OnRoute += OrdersRoute;
// only a session with one of these roles reaches /admin
route = router.Routes.Add();
route.Path = "/admin";
route.RequireRoles = "admin,manager";
route.OnRoute += AdminRoute;
void AuthAuthenticate(object sender, string aUser, string aPassword,
ref bool aAccept, ref string aUserID, ref string aDisplayName,
List<string> aRoles)
{
// LoadPasswordHash reads the value stored when the user was created
aAccept = sgcHTMLAuthHelpers.sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
if (aAccept)
{
aUserID = aUser;
aDisplayName = aUser;
aRoles.Add("admin");
}
}
// when you create a user, store this hash, never the password
string hash = sgcHTMLAuthHelpers.sgcHTMLPasswordHash("secret");
最もよく使うメンバーです。
CookieName(既定値 sgcsid)、CookiePath、CookieDomain で Cookie の内容を決めます。CookieSecure と CookieHttpOnly は既定で True、CookieSameSite は hssLax で、ほかの値は hssStrict と hssNone です。hssNone には常に Secure が追加されます。
IdleTimeout(1800 秒)は使用されなかったセッションを終了し、AbsoluteTimeout(43200 秒)は、アクティビティに関係なく、サインインからその時間が経過するとセッションを終了します。0 はどちらのチェックも無効にします。CurrentSession は両方を検証し、リクエストのたびにセッションのアクセス時刻を更新します。
CSRFProtection は既定でオンです。すべてのセッションにランダムなトークンが割り当てられます。IssueCSRF(session) がそれを返し、ValidateCSRF(session, token) が定数時間で比較します。エンジンはトークンを CSRFHeaderName ヘッダー(X-CSRF-Token)または CSRFFieldName フィールド(csrf_token)から読み取り、状態を変更するリクエストにトークンがなければ 403 を返します。
サインイン中のセッション向けにレンダリングされたページは、head に <meta name="csrf-token"> と <meta name="csrf-header"> を持ち、同梱の htmx スクリプトは、GET、HEAD、OPTIONS 以外のすべてのリクエストで、そのヘッダーにトークンを付けて送信します。hx-post と hx-delete に追加のマークアップは不要です。
RememberMeDays(0 はオフ、最大 3650)で有効になり、RememberCookieName は Cookie の名前(sgcrem)です。リクエストに有効なセッションがなく、有効なトークンがある場合、OnLoadUser がユーザーを再読み込みし、新しいセッションが発行され、トークンはローテーションされます。ストアが保持するのは検証子のハッシュだけです。
LoginRateLimit は TsgcHTMLAuthRateLimit_Options です。失敗したログインは、WindowSeconds(300)の間、クライアント IP とユーザー名ごとに数えられ、MaxAttempts(5)に達するとその IP またはユーザーが LockoutSeconds(900)の間ロックされ、ロック中は OnAuthenticate が呼び出されません。MaxAttempts = 0 でレート制限は無効になり、IsLoginLocked(ip, user) はロックの有無を返します。
sgcHTMLPasswordHash(password, iterations) は、pbkdf2-sha256$iterations$salt$hash を返します。ソルトはランダムな 16 バイト、反復回数の既定値は 210000 です。sgcHTMLPasswordVerify(password, hash) はパスワードを定数時間で確認し、形式が正しくないハッシュには False を返します。
TsgcHTMLSessionStore_Memory はセッションをプロセス内に保持し、SweepInterval でバックグラウンドの掃除を行います。その IdleTimeout と AbsoluteTimeout は Auth の値と同じにしてください。TsgcHTMLSessionStore_File はセッションごとに 1 つの JSON ファイルを Folder に書き込むため、複数のプロセスで共有でき、ファイルの書き換えは TouchInterval 秒(60)に 1 回までです。どちらもスレッドセーフです。
TsgcHTMLSession は ID、UserID、DisplayName、Roles、自由な Values(name=value)、CSRFToken、CreatedAt、LastSeen、RemoteIP、UserAgentHash を保持し、HasRole も備えます。ルートは TsgcHTMXRequest.Session としてこれを読み取り、匿名の場合は nil です。ストアはコピーを渡すため、変更を保持するには SessionStore.Put を呼び出してください。
Authenticate はレート制限を適用して OnAuthenticate を発生させます。SignIn は常に新しいセッション ID を作成し、古いものを削除して新しい CSRF トークンを発行するため、セッション固定攻撃を防げます。SignOut は 1 つのセッションを終了し、SignOutEverywhere(userID) はユーザーのすべてのセッションとログイン状態保持のトークンを終了します。エンジンの外では、Admin CRUD デモのように、CurrentSession(cookieHeader, remoteIP, userAgent, setCookies) を自分で呼び出します。
TsgcHTMX_Route に RequireLogin または RequireRoles(カンマ区切りで、1 つ一致すれば十分)を指定します。匿名のリクエストは 302 で LoginPath?next= にリダイレクトされ、htmx が送信した場合は 401 と HX-Redirect が返ります。ロールを持たないセッションには 403 が返ります。エンジンは LoginPath と LogoutPath への POST にも応答し、その後 AfterLoginPath に移動します。
メッセージは、WebSocket ハンドシェイクで送信された Cookie のセッションで実行されます。ただし、そのハンドシェイクが同一オリジンから来たものである場合に限ります。それ以外のメッセージは匿名で、拒否されたメッセージには応答がありません。TsgcHTMX_Engine_Server.MessageSession(aConnection) は、OnHTMXMessage に自分で応答するホスト向けに、接続の背後にあるセッションを返し、呼び出し側が解放します。
| オンラインヘルプこのコンポーネントの完全な API リファレンスと使用ガイドです。 | 開く | |
| セッションと認証のガイドCookie、CSRF、ルートのゲート、ログイン状態の保持、ログインのレート制限を、順を追って解説します。 | 開く | |
| すべての sgcHTML コンポーネント80 以上のコンポーネントの全機能マトリックスを閲覧できます。 | 開く | |
| 無料体験版のダウンロード30 日間の体験版には 60.HTML デモプロジェクトが付属し、TsgcHTMLAuth でサインインする 02.AdminCRUD も含まれます。 | 開く | |
| 価格完全なソースコード付きの Single、Team、Site ライセンス。 | 開く |