Blog

Gavin Pickin

December 23, 2017

Spread the word


Share your thoughts

At Ortus Solutions, we love the holidays, and we wanted to gift you a gift of developer productivity, we will share a few tips and tricks that will keep giving all year around. In this series we'll be giving you 12 ContentBox tips. Keep your eye out for other 12 tips of Christmas series on our blog, including a new one this year, 12 modules of Christmas on ForgeBox.

Day 10 - Security and Permissions in ContentBox Modules - One of the reasons I love working with ContentBox is all of the built in User management, permissions, roles, and creating ColdBox modules to extend ContentBox is easy. Today we'll look at how to use Security and Permissions in your ContentBox modules.

If your Module is using the ContentBox Module lifecycle, ContentBox preps your request, and handles tasks like themes, settings, checking for a logged in user etc. The current logged in user, is always available to you in the prc. This is handled by an interceptor, to ensure it is done on every request. Whether you are using a front end or admin module, you can access that user with `prc.oCurrentAuthor`

A great addition to your ContentBox Module ( also works with straight ColdBox apps ) is a module designed by Eric Peterson, called CB Guard. https://github.com/coldbox-modules/cbguard

This gives us a simple but powerful convention based security approach. There is a lot of great information on using this module in the readme on github, but we'll give you a run down here, and some secrets to using it with ContentBox.

To ensure a user is logged in to access a handler, you can add the metadata `secured` to your handler. This locks down the entire handler

component secured {

    function index( event, rc, prc ) {
        // ...
    }

    function show( event, rc, prc ) {
        // ...
    }

}

To ensure a user is logged in to access an action, you can add the metadata `secured` to your action.

component {

    function create( event, rc, prc ) secured {
        // ...
    }

}

To ensure a user is logged in and has the correct permission to access a handler, you can add the metadata `secured=”list,of,permissions”` to your handler. The user must have one of the listed permissions.

component secured="admin" {
	
    function index( event, rc, prc ) {
        // ...
    }

    function show( event, rc, prc ) {
        // ...
    }

}

To ensure a user is logged in and has the correct permission to access an action, you can add the metadata `secured=”list,of,permissions”` to your action. The user must have one of the listed permissions.

component {
	
    function show( event, rc, prc ) secured="admin,reviews_posts" {
        // ...
    }

}

These two approaches can be combined and both handler and actions can be secured together:
While the user needs to be logged in to interact at all with this handler, they also need the create_posts permission to interact with the new action.

component secured {

    function index( event, rc, prc ) {
        // ...
    }

    function new( event, rc, prc ) secured="create_posts" {
        // ...
    }

}

Configuration

CBGuard can be used with any ColdBox app, all you have to do is configure it. You can set settings for redirects:

  • authenticationOverrideEvent 
  • authorizationOverrideEvent 
  • authenticationAjaxOverrideEvent 
  • authorizationAjaxOverrideEvent 

As well as the redirects, you have to define how CBGuard checks your user is authenticated, and if the authenticated user is authorized ( has permission ), by defining the CFC that conforms to AuthenticationServiceInterface and HasPermissionInterface.

To configure the AuthenticationService, set the value of authenticationService in your moduleSettings to a WireBox mapping:

moduleSettings = {
    cbguard = {
        authenticationService = "SecurityService@myapp"
    }
};

The default authenticationService for cbguard is AuthenticationService@cbauth. cbauth follows the AuthenticationServiceInterface out of the box.

Advanced Setup - Overriding the Interface to work with ContentBox

You can change the method names called on the AuthenticationService and the returned User if you need to. We highly discourage this use case, as it makes it harder to utilize the cbguard conventions across projects. However, should the need arise, you can modify the method names as follows:

moduleSettings = {
    cbguard = {
        methodNames = {
            isLoggedIn    = "getIsLoggedIn",
            getUser       = "retrieveUser",
            hasPermission = "checkPermission"
        }
    }
};

Using CBGuard in a ContentBox App

Here is an example config for a real ContentBox app using CBGaurd, just add this into you /config/ColdBox.cfc

moduleSettings = {
	cbguard = {
		authenticationService = "UserService@rccore",
		methodNames = {
			isLoggedIn    = "isLoggedIn",
			getUser       = "getAuthorSession",
			hasPermission = "checkPermission"
		},
		authenticationOverrideEvent			= "security:login.new",
		authorizationOverrideEvent			= "ui:auth.onAuthorizationFailure",
		authenticationAjaxOverrideEvent		= "security:login.new",
		authorizationAjaxOverrideEvent		= "ui:auth.onAuthorizationFailure"
	}
};

What are we doing in this config?

  • We are using a custom authenticationService CFC, we'll share below
  • We are changing method names, so they match ContentBox's normal methods for checking Permission, and checking if a user is logged in for example.
  • We set authentication ( not logged in error ) redirects to the security module, with the action login.new.
  • We set authorization ( logged in but not the right permission ) redirects to the UI module, with the action auth.onAuthorizationFailure.

UserService.cfc required for CBGuard with ContentBox

Other than this configuration, the only code changes we need to implement, are in the UserService, lets look at that UserService.cfc.
We are looking at merging these requirements of CBGuard to make this even easier, but for now, you need to create a CFC like so.

/**
* User Service
* This User Service extends the ContentBox Author Service, allowing us to override and extend ContentBox's author service for the needs of this application
*/
component singleton extends="contentbox.models.security.AuthorService" {
	

	/**
	* Constructor
	*/
	public UserService function init(){
		super.init();
		return this;
	}

	/**
	* Proxy the getAuthorSession to the ContentBox security service getAuthorSession()
	*
	* @return author entity of the logged in user, or an empty author entity
	*/
	function getAuthorSession(){
		return securityService.getAuthorSession();
	}

	/**
	* Determinies if there is currently a user logged in
	*
	* @return boolean value - if there is a user logged in, or not.
	*/
	function isLoggedIn(){
		var author = getAuthorSession();
		return ( author.isLoaded() && author.isLoggedIn() );
	}
}

With some simple meta data, a little config, and this simple CFC, you can now use authentication and authorization all over your ContentBox modules.
Try it out, and let us know what you think.

Happy Holidays

Add Your Comment

Recent Entries

BoxLang Is Heading to JavaLand 2026! 🚀

BoxLang Is Heading to JavaLand 2026! 🚀

We’re excited to announce that the team behind BoxLang will be attending JavaLand 2026 as Startup Sponsors!

From March 10–12, 2026, the Java community will gather at Europa-Park for one of the most unique and immersive developer conferences in Europe. With nearly 130 presentations across multiple tracks, workshops, and community activities, JavaLand brings together developers, architects, and technology leaders from across the JVM ecosystem.

For the BoxLang team, this is a fantastic opportunity to connect with the Java community and continue our mission: modernizing software development on the JVM while empowering developers with productive, flexible tools.

Maria Jose Herrera
Maria Jose Herrera
March 06, 2026
The CFML Talent Gap Is Real: Scale Your ColdFusion Team Without Hiring Full-Time

The CFML Talent Gap Is Real: Scale Your ColdFusion Team Without Hiring Full-Time

ColdFusion applications still power critical systems across industries.

From universities and healthcare platforms to financial services and enterprise internal tools, CFML continues to run many systems organizations depend on every day.

But there’s a growing challenge many teams are quietly facing:

Finding experienced CFML developers is getting harder.

And when internal teams are already stretched thin, even small projects or performance issues can quickly turn ...

Cristobal Escobar
Cristobal Escobar
March 06, 2026
Discover the tools, tricks, and techniques every modern CFML and BoxLang developer needs!

Discover the tools, tricks, and techniques every modern CFML and BoxLang developer needs!

Into the Box 2026 is officially on the horizon, and it’s shaping up to be our most impactful conference yet.

Our mission this year is simple: **Make modernization approachable for everyone.** Whether you’re a seasoned ColdFusion veteran or a developer just starting your BoxLang journey, we’ve priced this event to ensure the entire community can join us in person.

Victor Campos
Victor Campos
March 05, 2026