セキュリティと権限
セッション認証、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 ã¬ã€ã¢ãŠãã䜿çšãããã°ã€ã³ç»é¢ãã·ã³ã°ã«ãµã€ã³ãªã³
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 飿º ãåç
§ããŠãã ããã
ãããžã§ã¯ãã®ã«ãŒããããSSO ã¢ã€ãã³ãã£ãã£ã®ãã€ã°ã¬ãŒã·ã§ã³ãå®è¡ããŸãã
box migrate up
ããã«ãããããŒã«ã«ã¢ã«ãŠã³ããšã¢ã€ãã³ãã£ãã£ãããã€ããŒã®ãµããžã§ã¯ããçŽã¥ããããã«
䜿çšããã user_sso_identities ããŒãã«ãäœæãããŸããæåã® SSO ãã°ã€ã³ã詊ã¿ãåã«
ãããå®è¡ããŠãã ããã
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 ã§ãµã€ã³ã€ã³
ã§ããããã«ãªããŸãã
éåžžã®éçºãŸãã¯ãããã€ã®ã³ãã³ãã§ã¢ããªã±ãŒã·ã§ã³ãèµ·åãã/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 ã§ç·šéã§ããŸã - 詳现㯠ã¢ããªèšå® ãåç
§ããŠãã ããã
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 ã«ãã£ãŠã·ãŒããããŸãã
| ãªãœãŒã¹ | ã¢ã¯ã·ã§ã³ |
|---|---|
users | readãwriteãdeleteãadmin |
roles | readãwriteãdeleteãadmin |
permissions | readãwriteãdeleteãadmin |
settings | readãwriteãdeleteãadmin |
auditlog | readãexportãdeleteã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
é¢é£ããã»ãã¥ãªãã£ãµãŒãã¹
| ã¢ãã« | ç®ç |
|---|---|
SecurityService | cbauth ã®èªèšŒãµãŒãã¹ãã©ããããŸããlogin()/authenticate()ãããŒã¯ã³ããŒããŒã·ã§ã³ä»ãã®ãªã¡ã³ããŒããŒã¯ãããŒç®¡çãlogout()ããã¹ã¯ãŒããªã»ããããŒã¯ã³ã®çºè¡/æ€èšŒ(DB ã§ã¯ãªããã£ãã·ã¥ããŒã¹) |
UserService | requestEmailChange()/confirmEmailChange()/cancelEmailChange() - ã»ã«ããµãŒãã¹ã®ã¡ãŒã«ã¢ãã¬ã¹å€æŽã§ãPURPOSE_EMAIL_CHANGE ã¢ã¯ã·ã§ã³ããŒã¯ã³ã«ãã£ãŠã²ãŒããããŠãããããæ°ããã¢ãã¬ã¹ã¯ãŠãŒã¶ãŒãåä¿¡ãã¬ã€ã«ãã確èªããŠåããŠé©çšãããŸã |
APIToken / APITokenService | SHA/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 / PasskeyService | cbsecurity-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 ã§ã¢ããªã±ãŒã·ã§ã³ãéããŠãã ããããããªãªãžã³åãã«ç»é²ããããã¹ããŒã¯å¥ã®ãªãªãžã³ãšã¯äºææ§ããªããããå¥ã®ãã¹ãåã䜿çšããŠãããšãã«äœæããããã¹ããŒã¯ãåé€ããŠåç»é²ããŠãã ããã
ãã¹ãŠã® @secured ã¢ãããŒã·ã§ã³ãããã³ãã©ãŒããšã«æèã®äžã§ç¢ºèªããŸãããã
ã©ã®æš©éãã©ã® URL ãä¿è·ããŠããããäžç®ã§ç¢ºèªã§ããŸãã
æ°ããæš©éã远å ãããã³ãã©ãŒããã¥ãŒãã·ãŒããŒãéããŠé ç·ããŸãã