Overview
In this page you will find a thorough overview of the capabilities of the ColdBox Security module.
Last updated
In this page you will find a thorough overview of the capabilities of the ColdBox Security module.
Last updated
For any security system you need to know who is authenticated (authentication) and what (authorization) this user is allowed to do. cbsecurity
is no different, so it provides an:
Authentication system which performs the following functions:
Validates user credentials
Logs them in and out
Tracks their security in sessions or any custom storage
Authorization system which:
validates permissions or roles or both
With the ColdBox security module you will be able to secure all your incoming ColdBox events from execution either through security rules or discrete annotations within your code. You will also be able to leverage our CBSecurity
service model to secure any code context anywhere.
The module wraps itself around the preProcess
interception point (The first execution of a ColdBox request) and will try to validate if the request has been authenticated and authorized to execute. This is done via security rules and/or annotations on the requested handler actions through a CBSecurity Validator
. The job of the validator is to make sure user requests have been authenticated and authorized:
CBAuth Validator: this is the default (and recommended) validator, which makes use of the cbauth module. It provides authentication and permission based security.
CFML Security Validator: Coldbox security has had this validator since version 1, and it will talk to the ColdFusion engine's security methods (cflogin,cflogout
). It provides authentication and roles based security.
JWT Validator: If you want to use Json Web Tokens the JWT Validator provides authorization and authentication by validating incoming access/refresh tokens for RESTFul APIs.
Custom Validator: You can define your own authentication and authorization engines and plug them in to the cbsecurity framework.
How does the interceptor know a user doesn't or does have access? Well, here is where you register a Validator CFC (validator
setting) with the interceptor that implements two validation functions: ruleValidator()
and annotationValidator()
that will allow the module to know if the user is logged in and has the right authorizations to continue with the execution.
You can find an interface for these methods in cbsecurity.interfaces.ISecurityValidator
The validator has two options to determine if the user will be allowed access:
The ruleValidator
() function will evaluate configured security rules
The annotationValidator()
function will look at security annotations in your handler and handler actions.
You can use rules, annotations or even both. Rules are much more flexible, but more complex. Rules will be evaluated before annotations.
The validators' job is to tell back to the firewall if they are allowed access and if they don't, what type of validation they broke: authentication or authorization.
Authentication
is when a user is NOT logged in
Authorization
is when a user does not have the right permissions to access an event/handler or action.
Once the firewall has the results and the user is NOT allowed access, the following will occur:
The request that was blocked will be logged via LogBox with the offending IP and extra metadata
The current requested URL will be flashed as _securedURL
so it can be used in relocations
If using a rule, the rule will be stored in prc
as cbsecurity_matchedRule
The validator results will be stored in prc
as cbsecurity_validatorResults
If the type of invalidation is authentication
the cbSecurity_onInvalidAuthentication
interception will be announced
If the type of invalidation is authorization
the cbSecurity_onInvalidAuthorization
interception will be announced
If the type is authentication
the default action (defaultAuthenticationAction
) for that type will be executed (An override or a relocation) will occur against the setting invalidAuthenticationEvent
which can be an event or a destination URL.
If the type is authorization
the default action (defaultAuthorizationAction
) for that type will be executed (An override or a relocation) invalidAuthorizationEvent
which can be an event or a destination URL.
Your application can be secured with security rules or handler and method annotations. Before making your choice, you should take the following arguments into consideration:
annotations are directly visible in your code, but very static.
annotations can protect events. Rules can protect events and incoming Url's.
rules allow you to change your action (override or redirect) and target on each rule. With annotations you can only use your configured default action and target.
when stored in a file or database, rules can be edited by admins at runtime.
Global Rules can be declared in your config/ColdBox.cfc
in plain CFML or in any module's ModuleConfig.cfc
or they can come from the following global sources:
A json file
An xml file
The database by adding the configuration settings for it
A model by executing a getSecurityRules()
method from it
A rule is a struct that can be composed of the following elements. All of them are optional except the secureList
.
Rules can be declared globally in your config/ColdBox.cfc
or they can also be place in any custom module in your application:
The firewall will inspect handlers for the secured
annotation. This annotation can be added to the entire handler or to an action or both. The default value of the secured
annotation is a Boolean true
. Which means, we need a user to be authenticated in order to access it.
You can also give the annotation some value, which can be anything you like: A list of roles, a role, a list of permissions, metadata, etc. Whatever it is, this is the authorization context and the user validator must be able to not only authenticate but authorize the context or an invalid authorization will occur.
By having the ability to annotate the handler and also the action you create a cascading security model where they need to be able to access the handler first and only then will the action be evaluated for access as well.
As we mentioned at the beginning of this overview, the security module will use a Validator object in order to determine if the user has authentication/authorization or not. This setting is the validator
setting and will point to the WireBox ID that implements the following methods: ruleValidator() and annotationValidator().
Each validator must return a struct
with the following keys:
allow:boolean
A Boolean indicator if authentication or authorization was violated
type:stringOf(authentication|authorization)
A string that indicates the type of violation: authentication or authorization.
messages:string
Info or debugging messages
ColdBox security ships with the CBAuthValidator@cbsecurity
which is the default validator in the configuration setting validator
setting.
When using the default CBAuthValidator@cbsecurity
you also have to configure the cbauth module.
ColdBox security ships also with a CFML authentication and authorization validator called CFSecurity
which has the following WireBox ID: CFValidator@cbsecurity
and can be found at cbsecurity.models.CFSecurity
You basically use cfloginuser
to log in a user and set their appropriate roles in the system. The module can then match to these roles via the security rules you have created.
The second method of authentication is based on your custom security logic. You will be able to register a validation object with the module. Once a rule is matched, the module will call your validation object, send in the rule/annotation value and ask if the user can access it or not. It will be up to your logic to determine if the rule is satisfied or not. Below is a sample permission based security validator:
The security module can distinguish between authentication issues and authorization issues. Once these actions are identified, the security module can act upon the result of these actions. These actions are based on the following 4 settings, but they all come down to two outcomes:
a relocation to another event or URL
an event override
Setting
Default
Description
invalidAuthenticationEvent
---
The global invalid authentication event or URI or URL to go if an invalid authentication occurs
defaultAuthenticationAction
redirect
Default Authentication Action: override or redirect when a user has not logged in
invalidAuthorizationEvent
---
The global invalid authorization event or URI or URL to go if an invalid authorization occurs
defaultAuthorizationAction
redirect
Default Authorization Action: override or redirect when a user does not have enough permissions to access something
When invalid authentication or authorizations occur the interceptor will announce the following events:
cbSecurity_onInvalidAuthentication
cbSecurity_onInvalidAuthorization
You will receive the following data in the interceptData
struct:
ip
: The offending IP address
rule
: The security rule intercepted or empty if annotations
settings
: The firewall settings
validatorResults
: The validator results
annotationType
: The annotation type intercepted, handler
or action
or empty if rule driven
processActions
: A Boolean indicator that defaults to true. If you change this to false, then the interceptor won't fire the invalid actions. Usually this means, you manually will do them.
You can use these security listeners to do auditing, logging, or even override the result of the operation.
There are many more interception points available to you, check them out in our Interceptions page.
The CBSecurity
model was introduced in version 2.3.0 and it provides you with a way to provide authorization checks and contexts anywhere you like: handlers, layouts, views, interceptors and even models.
Getting access to the model is easy via our cbSecure()
mixin (handlers/layouts/views/interceptors) or injecting it via WireBox:
Once injected you can leverage it using our awesome methods listed below:
When certain permission context is met, if not throws NotAuthorized
secure( permissions, [message] )
secureAll( permissions, [message] )
secureNone( permissions, [message] )
secureWhen( context, [message] )
When certain permission context is met, execute the success function/closure, else if a fail
closure is defined, execute that instead.
when( permissions, success, fail )
whenAll( permissions, success, fail )
whenNone( permissions, success, fail )
Verify permissions or user equality
has( permissions ):boolean
all( permissions ):boolean
none( permissions ):boolean
sameUser( user ):boolean
secureView( permissions, successView, failView )
This module also ships with a security visualizer that will document all your security rules and your settings in a nice panel. In order to activate it you must add the enableSecurityVisualizer
setting to your config and mark it as true
. Once enabled you can navigate to: /cbsecurity
and you will be presented with the visualizer.
Important The visualizer is disabled by default and if it detects an environment of production, it will disable itself.
ColdBox Security offers a comprehensive feature set for RESTFul applications that require JSON web tokens. We offer both access and refresh token capabilities. Check out our JWT Section for an in-depth overview.