| name | coldbox-security-implementation |
|---|---|
| description | Use this skill when setting up the full CBSecurity framework in ColdBox, configuring the security firewall, creating authentication services, implementing security event handlers, configuring security rules and validators, or building a complete security layer for a ColdBox application. |
CBSecurity is ColdBox's enterprise security framework providing authentication, authorization, firewall rules, security handlers, and a security event model that protects all routes/events.
Examples use BoxLang (.bx) syntax by default. Adapt for your target language:
| Concept | BoxLang (.bx) |
CFML (.cfc) |
|---|---|---|
| Class declaration | class [extends="..."] { |
component [extends="..."] { |
| DI annotation | @inject above property name="svc"; |
property name="svc" inject="svc"; |
| View templates | .bxm suffix |
.cfm / .cfml suffix |
| Tag prefix | <bx:if>, <bx:output>, <bx:set> |
<cfif>, <cfoutput>, <cfset> |
CFML Compat Mode: With BoxLang + CFML Compat module,
.bxand.cfcfiles coexist freely. BoxLang-native classes useclass {}(.bxfiles); CFML-compat classes usecomponent {}(.cfcfiles).
box install cbsecurity
box install cbauth
box install bcrypt// config/ColdBox.cfc
moduleSettings = {
cbsecurity: {
// Authentication service
authenticationService: "SecurityService@models",
// Firewall
firewall: {
enabled: true,
defaultAction: "redirect",
defaultRedirect: "/login",
// For APIs: use "block" with 401
statusCode: 401,
// Override rejection targets
invalidAuthenticationEvent: "auth.login",
invalidAuthorizationEvent: "main.accessDenied"
},
// Security rules (processed top-to-bottom, first match wins)
rules: [
{
whitelist: "auth\\..*,main\\.index,main\\.about",
match: "event"
},
{
secureList: "^admin\\.",
match: "event",
roles: "admin,superadmin",
action: "redirect",
redirect: "/login"
},
{
secureList: ".*",
match: "event",
action: "redirect",
redirect: "/login"
}
]
}
}
/**
* models/SecurityService.cfc
*/
class singleton {
property name="userService" inject="UserService"
property name="bcrypt" inject="@BCrypt"
property name="sessionStorage" inject="sessionStorage@cbstorages"
function authenticate( required username, required password ) {
try {
var user = userService.findByUsername( arguments.username )
if ( !bcrypt.checkPassword( arguments.password, user.password ) ) {
throw( type: "InvalidCredentials" )
}
sessionStorage.set( "currentUser", user )
return true
} catch ( any e ) {
return false
}
}
function getUser() {
return sessionStorage.get( "currentUser", {} )
}
function isLoggedIn() {
return sessionStorage.exists( "currentUser" )
}
function logout() {
sessionStorage.delete( "currentUser" )
}
function hasRole( required role ) {
var user = getUser()
return structIsEmpty( user ) ? false : listContains( user.roles, arguments.role )
}
function can( required permission ) {
var user = getUser()
return structIsEmpty( user ) ? false : listContains( user.permissions, arguments.permission )
}
}
CFML (.cfc):
/**
* models/SecurityService.cfc
*/
component {
property name="userService" inject="UserService"
property name="bcrypt" inject="@BCrypt"
property name="sessionStorage" inject="sessionStorage@cbstorages"
function authenticate( required username, required password ) {
try {
var user = userService.findByUsername( arguments.username )
if ( !bcrypt.checkPassword( arguments.password, user.password ) ) {
throw( type: "InvalidCredentials" )
}
sessionStorage.set( "currentUser", user )
return true
} catch ( any e ) {
return false
}
}
function getUser() {
return sessionStorage.get( "currentUser", {} )
}
function isLoggedIn() {
return sessionStorage.exists( "currentUser" )
}
function logout() {
sessionStorage.delete( "currentUser" )
}
function hasRole( required role ) {
var user = getUser()
return structIsEmpty( user ) ? false : listContains( user.roles, arguments.role )
}
function can( required permission ) {
var user = getUser()
return structIsEmpty( user ) ? false : listContains( user.permissions, arguments.permission )
}
}/**
* interceptors/SecurityInterceptor.cfc
* Runs on every request to check auth status
*/
class extends="coldbox.system.Interceptor" {
property name="cbsecurity" inject="@cbsecurity"
function preProcess( event, interceptData ) {
// Skip public routes
if ( isPublicRoute( event.getCurrentEvent() ) ) {
return
}
// Check authentication
if ( !cbsecurity.isLoggedIn() ) {
flash.put( "redirectTo", cgi.script_name & "?" & cgi.query_string )
relocate( "auth.login" )
}
}
private function isPublicRoute( required eventName ) {
var publicRoutes = [
"auth.login", "auth.doLogin",
"auth.register", "auth.doRegister",
"main.index"
]
return publicRoutes.contains( arguments.eventName )
}
}
CFML (.cfc):
/**
* interceptors/SecurityInterceptor.cfc
* Runs on every request to check auth status
*/
component extends="coldbox.system.Interceptor" {
property name="cbsecurity" inject="@cbsecurity"
function preProcess( event, interceptData ) {
// Skip public routes
if ( isPublicRoute( event.getCurrentEvent() ) ) {
return
}
// Check authentication
if ( !cbsecurity.isLoggedIn() ) {
flash.put( "redirectTo", cgi.script_name & "?" & cgi.query_string )
relocate( "auth.login" )
}
}
private function isPublicRoute( required eventName ) {
var publicRoutes = [
"auth.login", "auth.doLogin",
"auth.register", "auth.doRegister",
"main.index"
]
return publicRoutes.contains( arguments.eventName )
}
}/**
* handlers/Auth.cfc
*/
class extends="coldbox.system.EventHandler" {
property name="security" inject="SecurityService@models"
function login( event, rc, prc ) {
if ( security.isLoggedIn() ) {
relocate( uri = "main.dashboard" )
}
event.setView( "auth/login" )
}
function doLogin( event, rc, prc ) {
event.paramValue( "email", "" )
event.paramValue( "password", "" )
if ( security.authenticate( rc.email, rc.password ) ) {
// Redirect to originally requested URL if available
var destination = flash.get( "redirectTo", "main.dashboard" )
relocate( uri = destination )
} else {
flash.put( "error", "Invalid credentials" )
relocate( "auth.login" )
}
}
function doLogout( event, rc, prc ) {
security.logout()
relocate( "auth.login" )
}
}
CFML (.cfc):
/**
* handlers/Auth.cfc
*/
component extends="coldbox.system.EventHandler" {
property name="security" inject="SecurityService@models"
function login( event, rc, prc ) {
if ( security.isLoggedIn() ) {
relocate( uri = "main.dashboard" )
}
event.setView( "auth/login" )
}
function doLogin( event, rc, prc ) {
event.paramValue( "email", "" )
event.paramValue( "password", "" )
if ( security.authenticate( rc.email, rc.password ) ) {
// Redirect to originally requested URL if available
var destination = flash.get( "redirectTo", "main.dashboard" )
relocate( uri = destination )
} else {
flash.put( "error", "Invalid credentials" )
relocate( "auth.login" )
}
}
function doLogout( event, rc, prc ) {
security.logout()
relocate( "auth.login" )
}
}/**
* interceptors/SecurityEvents.cfc
* Log security events for audit trail
*/
class extends="coldbox.system.Interceptor" {
property name="logger" inject="logbox:logger:{this}"
function CBSecurity_onInvalidAuthentication( event, interceptData ) {
logger.warn( "Authentication failure: event=#interceptData.event#, ip=#cgi.remote_addr#" )
}
function CBSecurity_onInvalidAuthorization( event, interceptData ) {
logger.warn( "Authorization failure: event=#interceptData.event#, user=#interceptData.userId#" )
}
function CBSecurity_onAuthentication( event, interceptData ) {
logger.info( "User logged in: #interceptData.userId#" )
}
function CBSecurity_onLogout( event, interceptData ) {
logger.info( "User logged out: #interceptData.userId#" )
}
}
CFML (.cfc):
/**
* interceptors/SecurityEvents.cfc
* Log security events for audit trail
*/
component extends="coldbox.system.Interceptor" {
property name="logger" inject="logbox:logger:{this}"
function CBSecurity_onInvalidAuthentication( event, interceptData ) {
logger.warn( "Authentication failure: event=#interceptData.event#, ip=#cgi.remote_addr#" )
}
function CBSecurity_onInvalidAuthorization( event, interceptData ) {
logger.warn( "Authorization failure: event=#interceptData.event#, user=#interceptData.userId#" )
}
function CBSecurity_onAuthentication( event, interceptData ) {
logger.info( "User logged in: #interceptData.userId#" )
}
function CBSecurity_onLogout( event, interceptData ) {
logger.info( "User logged out: #interceptData.userId#" )
}
}/**
* handlers/Main.cfc
*/
function accessDenied( event, rc, prc ) {
event.setHTTPHeader( statusCode: 403 )
event.setView( "errors/403" )
}
- Install cbsecurity, cbauth, bcrypt
- Configure
authenticationServicein moduleSettings - Define firewall rules (whitelist public routes, secure the rest)
- Use BCrypt for password hashing — never store plain text passwords
- Implement role/permission checking in handlers with
@secured - Log security events with LogBox
- Use HTTPS in production
- Set
JWT_SECRETand other secrets via environment variables - Validate all user input at system boundaries