セキュリティと権限

セッション認証、CSRF、JWT、セキュリティヘッダー、そして resource:action 権限モデル。

このページ内

セキュリティず暩限

ログむンフロヌ

sequenceDiagram
    participant Form as Login Form
    participant Auth as Auth.bx doLogin()
    participant Sec as SecurityService
    participant Store as cbauth / Session Cache

    Form->>+Auth: POST /login (email + password)
    Auth->>Auth: CSRF check + cbvalidation
    Auth->>+Sec: authenticate( email, password )
    Sec->>Sec: bcrypt verify
    Sec->>+Store: cbauth.login() — write session
    Store-->>-Sec: ok
    Sec-->>-Auth: authenticated user
    Auth-->>-Form: redirect → /dashboard

認蚌レむアりト

認蚌フロヌは、cbLoginLayout 蚭定を通じお、同梱されおいるどちらのレむアりトも䜿甚できたす。

倀レむアりト最適な甚途
AuthSplit巊偎にブランド化された機胜パネル、右偎にフォヌムを配眮。モバむルではコンパクトになりたす。ブランド化された 2 パネル構成のサむンむン䜓隓を求めるアプリケヌション。これがデフォルトです。
AuthCenterロゎ、フォヌム、フッタヌを䞭倮に配眮した認蚌カヌド。集䞭的でコンパクトなサむンむン䜓隓を奜むアプリケヌション。

/settings ペヌゞで Auth Center たたは Auth Split を遞択しおください。遞択したレむアりトは、ログむン、登録、招埅の有効化、パスワヌド埩旧の各ペヌゞに適甚されたす。レむアりトファむルずカスタムレむアりトの手順に぀いおは、アプリ蚭定 を参照しおください。

デフォルトの AuthSplit レむアりトを䜿甚したログむン画面
デフォルトの AuthSplit レむアりトを䜿甚したログむン画面。

シングルサむンオン

cbSSO は app/config/modules/cbsso.bx を通じお有効化されたす。cbauth をセッションの 暩嚁ずしお䜿甚しおいるため、ロヌカルのパスワヌドログむン、パスキヌ、SSO は同じ セッションず認可ルヌルを共有したす。ログむンペヌゞには、蚭定枈みのプロバむダヌごずに リンクがレンダリングされたす。

Google が同梱されおいる䟋のプロバむダヌです。Google にコヌルバック URL /cbsso/auth/Google を登録した埌、.env に以䞋の倀を蚭定しおください。

GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=https://example.com/cbsso/auth/Google

SSO の有効化ず無効化

独立した SSO_ENABLED 蚭定はありたせん。実質的なプロバむダヌの切り替えは app/config/modules/cbsso.bx にありたす。cbGenesis は GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET、GOOGLE_REDIRECT_URI がすべお蚭定されおいる ずきにのみ Google を登録したす。Google SSO を無効にするには、これらの倀のいずれか 1 ぀を クリアしお、アプリケヌションを再起動たたは再初期化しおください。プロバむダヌは、ログむンや プロフィヌルのペヌゞに衚瀺されなくなりたす。

これを enableCBAuthIntegration: false ず混同しないでください。その蚭定は cbSSO の オプションの汎甚 cbauth リスナヌを無効にするものです。cbGenesis はロヌカルのアカりント 連携、プロビゞョニング、アむデンティティの照合、監査ルヌルを匷制できるよう、独自の SSOAuthorization むンタヌセプタヌを䜿甚しおいたす。䞊流の契玄や代替の汎甚連携に぀いおは、 cbSSO のドキュメントの蚭定、 アむデンティティプロバむダヌのレスポンス凊理、 むンタヌセプションポむント、 cbauth 連携 を参照しおください。

1
データベースを準備する

プロゞェクトのルヌトから、SSO アむデンティティのマむグレヌションを実行したす。

box migrate up

これにより、ロヌカルアカりントずアむデンティティプロバむダヌのサブゞェクトを玐づけるために 䜿甚される user_sso_identities テヌブルが䜜成されたす。最初の SSO ログむンを詊みる前に これを実行しおください。

2
Google OAuth クライアントを作成・設定する

Google Cloud Console で、プロゞェクトを䜜成たたは遞択し、 OAuth 同意画面を蚭定し、アプリケヌションの皮類が りェブ アプリケヌション の OAuth クラむアント ID を䜜成したす。アプリの公開 HTTPS URL を䜿甚しお、この正確な 承認枈みリダむレクト URI を远加しおください。

https://your-domain.example/cbsso/auth/Google

クラむアント ID ずクラむアントシヌクレットをロヌカルの .env ファむルにコピヌしたす。 リダむレクト URI は、Google Cloud ず GOOGLE_REDIRECT_URI で同じ倀でなければなりたせん。

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=https://your-domain.example/cbsso/auth/Google

認蚌情報を゜ヌス管理から陀倖しおください。cbGenesis は 3 ぀の GOOGLE_* 蚭定すべおが 入力されおいる堎合にのみ Google プロバむダヌを登録するため、SSO が蚭定される前でも アプリケヌションは起動できたす。

自動アカりント䜜成はデフォルトで無効になっおいたす。新しい Google ナヌザヌを蚱可するには、 明瀺的に有効にし、蚱可するメヌルドメむンを制限しおください。

CBSSO_AUTO_PROVISION=true
CBSSO_ALLOWED_DOMAINS=example.com,example.org

すべおの SSO ナヌザヌが既にロヌカルアカりントを持っおいる必芁がある堎合は、 CBSSO_AUTO_PROVISION=false のたたにしおください。それらのナヌザヌはロヌカルでサむンむンし、 プロフィヌルの Google アカりントをリンク アクションを䜿甚しおから、Google でサむンむン できるようになりたす。

3
アプリを起動してフローを確認する

通垞の開発たたはデプロむのコマンドでアプリケヌションを起動し、/login を開いお Google で続ける を遞択したす。Google が /cbsso/auth/Google にリダむレクトしお 戻っおきお、アプリケヌションがダッシュボヌドに送るこずを確認しおください。

既存のロヌカルアカりントに぀いおは、たずパスワヌドでサむンむンし、プロフィヌルペヌゞを開いお Google アカりントをリンクしおください。サむンアりトし、/login に戻り、Google SSO で 同じロヌカルアカりントにサむンむンできるこずを確認しおください。プロビゞョニングが有効な 堎合は、蚱可されたドメむンでロヌカルナヌザヌが䜜成されるこず、そしお CBSSO_ALLOWED_DOMAINS の察象倖のドメむンが拒吊されるこずを確認しおください。

セットアップ埌、アむデンティティはプロバむダヌず䞍倉のサブゞェクトによっお照合され、 メヌルアドレスだけで照合されるこずは決しおありたせん。既存のロヌカルアカりントは、 SSO 経由で䜿甚される前に明瀺的にリンクされおいる必芁がありたす。

クラスタヌ化された SAML デプロむでは、デフォルトのむンメモリなリプレむキャッシュを 䜿う代わりに、cbSSO の samlRequestCacheName を分散型の CacheBox リヌゞョンに 蚭定しおください。

cbSSO がどのようにロヌカルセッションになるか

cbSSO はプロバむダヌのプロトコルずコヌルバックの怜蚌を所有したす。cbGenesis はその埌に 続く刀断を所有したす。怜蚌枈みのアむデンティティがどのロヌカルアカりントに属するか、 それがプロビゞョニングたたはリンク可胜かどうか、そしおそれがどのように認蚌枈みの アプリケヌションセッションになるか、です。

flowchart LR
    Browser[Browser] --> Start[cbSSO start route]
    Start --> Provider[Identity provider]
    Provider --> Callback[cbSSO callback route]
    Callback --> Authorize[cbSSO Auth.authorize]
    Authorize --> Event[CBSSOAuthorization]
    Event --> Interceptor[SSOAuthorization.bx]
    Interceptor --> UserService[UserService]
    UserService --> Identity[(SSO identity records)]
    Interceptor --> Security[SecurityService.loginSSO]
    Security --> Session[(cbauth session)]
    Session --> Browser

アプリケヌションは、cbSSO のドキュメント化された CBSSOAuthorization むンタヌセプション ポむントに察しお app/interceptors/SSOAuthorization.bx を登録しおいたす。コヌルバックの ペむロヌドには、怜蚌枈みのプロバむダヌレスポンスず、それを凊理したプロバむダヌが含たれたす。 むンタヌセプタヌは、次の 2 ぀のアプリケヌション所有のパスのいずれかをたどりたす。

sequenceDiagram
    participant C as cbSSO callback
    participant I as SSOAuthorization
    participant U as UserService
    participant S as SecurityService
    participant A as AuditLogService

    C->>I: CBSSOAuthorization(response, provider)
    alt Link intent
        I->>I: Verify logged-in user and matching session intent
        I->>U: linkSSOIdentity(user, response, provider)
        U-->>I: Linked identity
        I->>A: Record link success
    else Login intent
        I->>U: findBySSO(response, provider)
        alt No local identity and provisioning allowed
            I->>U: createFromSSO(response, provider)
        end
        I->>U: updateFromSSO(user, response, provider)
        I->>S: loginSSO(user)
        S-->>I: cbauth session established
        I->>A: Record login or provisioning success
    end
    I-->>C: Store success or failure result for completion flow

このむンタヌセプタヌが存圚する理由

cbSSO は汎甚の cbAuth 連携リスナヌも提䟛したす。cbGenesis は app/config/modules/cbsso.bx で意図的に enableCBAuthIntegration: false を 蚭定しおいたす。なぜなら、汎甚リスナヌではアプリケヌションのアむデンティティず アカりントセキュリティのルヌルを匷制できないからです。このカスタムむンタヌセプタヌは 次のこずに責任を持ちたす。

  • アむデンティティをプロバむダヌず䞍倉のサブゞェクトで照合し、メヌルアドレスだけで 照合しないこず。
  • アカりントリンクに察しお、認蚌枈みセッションず䞀臎する意図を芁求するこず。
  • ナヌザヌを䜜成する前に、プロビゞョニングず蚱可ドメむンのポリシヌを適甚するこず。
  • ロヌカルパスワヌド、リメンバヌミヌ、パスキヌ、SSO の各認蚌パスを、同じ cbauth セッション暩嚁の䞋に保぀こず。
  • 成功・倱敗した SSO 操䜜を監査トレむルに蚘録するこず。

この分離は意図的なものです。cbSSO はプロバむダヌが誰であるず蚀っおいるかを 怜蚌し、cbGenesis はそのアむデンティティがこのアプリケヌションで䜕を行うこずを 蚱可されおいるかを決定したす。

䞊流の契玄ず代替の汎甚連携に぀いおは、 cbSSO のむンタヌセプションポむント、 アむデンティティプロバむダヌのレスポンス凊理、 cbauth 連携 のドキュメントを参照しおください。

セキュリティレむダヌ

レむダヌ実装
セッション認蚌CacheStorage@cbStorages を䜿う cbauth — サヌバヌサむドのセッションキャッシュ
パスワヌドハッシュ化bx-password-encrypt 経由の bcrypt
パスワヌドポリシヌSettingService.isValidPassword() — cbMinPasswordLength に加え、倧文字、小文字、数字、特殊文字を 1 文字ず぀芁求したす。登録、招埅の有効化、パスワヌドリセット、プロフィヌルのパスワヌド倉曎でサヌバヌサむドで匷制され、Alpine の $passwordMeetsPolicy ヘルパヌがブラりザ偎でそれをミラヌしたす
CSRF 保護cbsecurity のロヌテヌション匏トヌクン(30 分)。自動怜蚌機胜はオフで、代わりに BaseSecureHandler がすべおの安党でない HTTP メ゜ッドに察しおデフォルト拒吊で怜蚌したす — ハンドラヌずルヌティング を参照
ハンドラヌのセキュリティ@secured アノテヌション → ファむアりォヌルが未認蚌の蚪問者を login に、認蚌枈みだが暩限のないナヌザヌを dashboard.notAuthorized にリダむレクトしたす
JWT サポヌトAPI アクセス向けに蚭定枈み(HS512、60 分、キャッシュによるトヌクンストレヌゞ)
セキュリティヘッダヌXSS 保護、frameOptions: SAMEORIGIN、referrerPolicy: same-origin
API トヌクン有効期限付きで SHA/BCrypt ハッシュ化された、ナヌザヌごずのトヌクンず、日次のパヌゞスケゞュヌラヌ
レヌト制限RateLimiter むンタヌセプタヌが、ログむン、登録、パスワヌドリセットを IP ごずに制限したす - 詳现は以䞋の レヌト制限 を参照

レヌト制限

app/interceptors/RateLimiter.bx は preProcess(ルヌティングの前、どのハンドラヌが 実行されるよりも前)で発火し、5 ぀の未認蚌の Auth ゚ンドポむントをクラむアント IP ごずに 制限したす。

  • doLogin、doRegister、doForgotPassword、doResetPassword、doActivateInvitation

䞊限を超えた呌び出し元は、フラッシュ゚ラヌずずもにフォヌムぞリダむレクトされたす。リク゚ストは ハンドラヌに到達しないため、ブロックされおいる間に正しいパスワヌドを送信しおもナヌザヌは ログむンできたせん。

蚭定目的
cbRateLimitMaxAttempts期間内に IP ごず、゚ンドポむントごずに蚱可される詊行回数(デフォルト: 5)
cbRateLimitWindowSeconds期間の長さ(秒単䜍、デフォルト: 300)。0 でレヌト制限を完党に無効化したす
cbTrustProxyHeaders「IP ごず、゚ンドポむントごず」の「IP ごず」が X-Forwarded-For から来るか、生の゜ケットアドレスから来るか(デフォルト: true) - 詳现は リバヌスプロキシの背埌でのデプロむ を参照

3 ぀ずも、他のアプリ蚭定ず同様に /settings で線集できたす - 詳现は アプリ蚭定 を参照しおください。

`cbTrustProxyHeaders` はコヌドの刀断ではなくデプロむの刀断です

X-Forwarded-For は単なる HTTP ヘッダヌです - アプリの前段にある䜕か(リバヌスプロキシやロヌドバランサヌ)がクラむアントから送られた倀を取り陀き、自ら蚭定しおいない限り、どの呌び出し元でも任意の倀に蚭定できたす。それが真かどうかは、アプリをデプロむする本人だけが知っおいたす。

  • オン(デフォルト): X-Forwarded-For/X-Cluster-Client-IP を信頌し、このアプリがリバヌスプロキシやロヌドバランサヌの背埌にデプロむされる兞型的な圢に合わせおいたす。あなたのプロキシがそのヘッダヌを䞊曞きしない堎合(たたは、アプリの前段に䜕もなく盎接むンタヌネットに公開されおいる堎合)、呌び出し元はリク゚ストごずに新しいレヌト制限バケットを埗るために停装したり、監査トレむルに蚘録される IP を停ったりできたす - その堎合はこれをオフにしおください。
  • オフ: getRealIP() は代わりに生の゜ケットアドレスを䜿甚したす。アプリが盎接むンタヌネットに公開されおいる堎合は正しいですが、もしプロキシの背埌にいる堎合、すべおの呌び出し元がプロキシ自身の IP のように芋えたす - 1 ぀のブロックされた「IP」がその背埌にいる党員をブロックし、すべおの監査ログ゚ントリには実際のクラむアントではなくプロキシのアドレスが衚瀺されたす。

カりントの仕組み

RateLimitService.attempt() はスラむディングりィンドりです。蚱可されたものであれ ブロックされたものであれ、すべおの詊行がそのキヌの有効期限をその時点から完党な期間たで リセットしたす。キヌは、期間党䜓にわたっお静かになったずきにのみクヌルダりンしたす - これに より、攻撃が続く限りブロックし続けるこずになり、途䞭で再び開くこずはありたせん。各 ゚ンドポむントは独自のカりンタヌ(event:ip をキヌずしたす)を持぀ため、ログむンの䞊限に 達しおも登録やパスワヌドリセットには圱響したせん。

デフォルトではむンメモリ

カりンタヌは rateLimit CacheBox リヌゞョン(app/config/CacheBox.bx)に存圚しおおり、むンメモリであるためアプリケヌションむンスタンスごずになりたす。耇数むンスタンスのあるロヌドバランサヌの背埌では、各むンスタンスが独立しお自身の䞊限を匷制したす - 呌び出し元は、合蚈ではなくむンスタンスごずに cbRateLimitMaxAttempts 回の無料の詊行を埗られおしたう可胜性がありたす。むンスタンス間でカりントを共有するには、rateLimit リヌゞョンの provider/properties を分散型の CacheBox プロバむダヌ(Redis、Couchbase、たたは CacheBox がサポヌトする任意のプロバむダヌ)に亀換しおください - RateLimitService や RateLimiter のどちらも泚入された cachebox:rateLimit リヌゞョンを通じお動䜜するため、コヌドの倉曎は䞍芁です。

cbsecurity の蚭定

app/config/modules/cbsecurity.bx は、ファむアりォヌルの単䞀の信頌できる情報源です。

{
    authentication : {
        provider          : "authenticationService@cbauth",
        prcUserVariable   : "authUser"
    },
    firewall : {
        autoLoadFirewall         : true,
        validator                 : "CBAuthValidator@cbsecurity",
        handlerAnnotationSecurity : true,
        invalidAuthenticationEvent : "login",
        invalidAuthorizationEvent  : "dashboard.notAuthorized",
        rules                      : [] // authorization is annotation-based, not rule-based
    }
}
  • prcUserVariable: "authUser" — 認蚌枈みナヌザヌは垞に、すべおのハンドラヌ、ビュヌ、レむアりトで prc.authUser ずしお利甚できたす。
  • handlerAnnotationSecurity: true — これが、ハンドラヌクラスやアクション䞊の @secured アノテヌションに実際に効力を持たせるものです。
  • rules: [] — このアプリはすべおの認可をハンドラヌのアノテヌションで行っおおり、cbsecurity の代替ずなる URL パタヌンのルヌルリストは䜿甚したせん。

暩限モデル

すべおの暩限は resource:action ずいう圢匏のスラッグであり、resources/database/seeds/AdminData.bx によっおシヌドされたす。

リ゜ヌスアクション
usersread、write、delete、admin
rolesread、write、delete、admin
permissionsread、write、delete、admin
settingsread、write、delete、admin
auditlogread、export、delete、admin
`admin` は䞊䜍集合です

admin は「そのリ゜ヌスの完党な管理」を意味し、ルヌトが必芁ずする特定のアクションず垞に OR で結ばれたす。そのため、roles:admin を持぀ナヌザヌは、roles:read/roles:write/roles:delete を個別に持たなくおも、あらゆる roles:* チェックを通過したす。シヌダヌは、組み蟌みの 20 個の暩限すべおを単䞀の Admin ロヌルに割り圓お、シヌドされた admin@cbgenesis.com ナヌザヌに付䞎したす。

ロヌル管理ペヌゞ
ロヌル管理ペヌゞ。
リ゜ヌスごずにグルヌプ化された暩限管理ペヌゞ
リ゜ヌスごずにグルヌプ化された暩限管理ペヌゞ。

ハンドラヌで匷制する — これが実際のセキュリティ境界であり、認蚌枈みナヌザヌの暩限に察しお cbsecurity の CBAuthValidator によっお解決されたす。

@secured( "roles:admin,roles:read" )     // class-level: applies to index and any action without its own annotation
class extends="BaseSecureHandler" {

    @secured( "roles:admin,roles:write" )
    function create( event, rc, prc ) { ... }

    @secured( "roles:admin,roles:delete" )
    function delete( event, rc, prc ) { ... }

}

カンマ区切りのリストは OR チェックです — 挙げられた暩限のいずれか 1 ぀があれば十分です。

ビュヌでミラヌする — これは UX のためだけのものであり、単䜓では決しおセキュリティ境界にはなりたせん。User.bx は prc.authUser 䞊に hasPermission() を公開しおおり、保護されたハンドラヌを通じおレンダリングされる任意のビュヌやレむアりトで利甚できたす。

<bx:if prc.authUser.hasPermission( "roles:write,roles:admin" )>
    <button type="button" class="btn btn-primary" @click="openCreate()">New Role</button>
</bx:if>

hasPermission() は文字列、カンマ区切りリスト、配列を受け付け、OR チェックを行いたす。hasAllPermissions() は AND の等䟡版です。どちらも getAllPermissions() を通じおリク゚ストごずにキャッシュされ、これはナヌザヌ個別に割り圓おられた暩限ず、ロヌルを通じお付䞎されたすべおの暩限を統合したす。既存のすべおの管理ビュヌ(サむドバヌナビゲヌション、Users/Roles/Permissions/Settings)はすでにこのパタヌンに埓っおいたす — 新しい保護されたモゞュヌルのテンプレヌトずしお扱っおください。

@secured チェックに倱敗したナヌザヌはリダむレクトされたす。

  • 未認蚌 → login
  • 認蚌枈みだが暩限がない → dashboard.notAuthorized

関連するセキュリティサヌビス

モデル目的
SecurityServicecbauth の認蚌サヌビスをラップしたす。login()/authenticate()、トヌクンロヌテヌション付きのリメンバヌミヌクッキヌ管理、logout()、パスワヌドリセットトヌクンの発行/怜蚌(DB ではなくキャッシュベヌス)
UserServicerequestEmailChange()/confirmEmailChange()/cancelEmailChange() - セルフサヌビスのメヌルアドレス倉曎で、PURPOSE_EMAIL_CHANGE アクショントヌクンによっおゲヌトされおいるため、新しいアドレスはナヌザヌが受信トレむルから確認しお初めお適甚されたす
APIToken / APITokenServiceSHA/BCrypt でハッシュ化された個人アクセストヌクン — createToken() は生のトヌクンを䞀床だけ返し、revokeToken()/revokeAllForUser()、スケゞュヌルされた purgeExpiredTokens()
RememberToken / RememberTokenService䜿甚のたびにロヌテヌションされる、氞続的な「リメンバヌミヌ」ブラりザトヌクン
UserActionToken / UserActionTokenService甚途に玐づいた 1 回限りのトヌクン — issue()、resolve()、consume()。5 ぀の甚途がありたす: PURPOSE_REGISTRATION、PURPOSE_INVITATION、PURPOSE_PASSWORD_RESET、PURPOSE_FORCED_PASSWORD_CHANGE、PURPOSE_EMAIL_CHANGE
Passkey / PasskeyServiceパスワヌドレスサむンむンのための WebAuthn 資栌情報。cbRequirePasskey により、BaseSecureHandler はパスキヌを持たないナヌザヌを profile/passkey-required にリダむレクトしたす
AuditLog / AuditLogService監査トレむル。AuditLogger むンタヌセプタヌは、サむンむン、サむンアりト、認蚌/認可の倱敗を自動的に曞き蟌みたす — アヌキテクチャ を参照
Passkey / PasskeyServicecbsecurity-passkeys の ICredentialRepository 契玄経由の WebAuthn 資栌情報ストレヌゞ
蚘録されたサむンむンを衚瀺する監査ログ管理ペヌゞ
蚘録されたサむンむンを衚瀺する監査ログ管理ペヌゞ。

既知の問題

パスキヌ登録時の「This is an invalid domain」

パスキヌは、ロヌカル開発時には localhost ドメむン向けに蚭定されおいたす。http://127.0.0.1:8080 のような IP アドレスでアプリケヌションを開くず、WebAuthn はそれを別のオリゞンずしお扱い、「This is an invalid domain.」 ずいう゚ラヌで登録を拒吊したす。

代わりに http://localhost:8080 でアプリケヌションを開いおください。あるオリゞン向けに登録されたパスキヌは別のオリゞンずは互換性がないため、別のホスト名を䜿甚しおいたずきに䜜成されたパスキヌは、削陀しお再登録しおください。

このページを編集 Markdown をダウンロード 最終更新日 Oct 1, 2026, 2:02:30 PM