[CBSecurity 3] Is it Possible to Use More than One Authentication Method?

Is it possible to use different authentication methods for different paths (rules) within a Coldbox application? For example, can I use JWT authentication to secure all of the api/v1/ REST endpoints and Basic Authentication for the documentation path (`/cbswaggerui/')?

Currently, I have my CBSecurity rules configuration in the root /coldbox/coldbox.cfc config file.

The short answer is yes, you can use different authentication methods for different modules. I am not sure if it can be done within the same module, but for my needs, I wanted to use JWT auth for the API (/api/v1) module, and Basic HTTP Auth for the /sbswagger (docs) module.

CBSecurity added support for Basic Auth in Version 3 which is still in development as of this writing and hasn’t been documented yet.

I was able to set up some different rules via the /coldbox/coldbox.cfc configuration:

moduleSettings = {
    cbsecurity: {
        // .. settings for rest of app here

        // set up BasicAuth
        "basicAuth" : {
            // Hashing algorithm to use
            "hashAlgorithm"  : "SHA-512",
            // Iterates the number of times the hash is computed to create a more computationally intensive hash.
            "hashIterations" : 5,
            // User storage: The `key` is the username. The value is the user credentials that can include
            // { roles: "", permissions : "", firstName : "", lastName : "", password : "" }
            "users"          : {
                "user" : { password : "userpass", permissions : "read" }
            }
        }
    }

    // cbswagger settings
    cbSwagger = {
        // ... cbswagger config here
        // override cbsecurity for this module
        cbSecurity = {
            "validator": "BasicAuthValidator@cbsecurity",
            "rules" : [
                {
                    secureList: "cbswagger:"
                }
            ]
        }
    }
}

I was able to extend my JWT requirement to /cbswagger, but I wasn’t able to get Basic HTTP Auth working with cbSecurity V3. It’s possible I screwed something up in configuring it. Once the docs are written, I will test again and update this post with my findings.

Hi @DaveL, this is something that needs testing. Right now, every module can dictate which validator to use for authentication purposes.

I have not yet tested the ability of each module to use its own Authentication provider. I will need help in this area. What you are trying to do is something imperative for me to work on before I release v3. I have not released it yet, due to this. So if you can assist me with what we need to do to get it working, please let me know.

You know I love a challenge, @lmajano and I would be more than happy to help!
I have a perfect test-case in mind but I have yet to get Basic HTTP authentication to work with cbSecurity on its own.

Can you share an example configuration that has Basic HTTP auth working? I assumed the below would work, but I can never pass validation, even with proper credentials:

moduleSettings = {
    cbsecurity: {
        // set the validator to Basic HTTP Auth
        "validator": "BasicAuthValidator@cbsecurity",
        "rules" : [
            {
                secureList: "cbswagger:"
            }
        ],
        // set up BasicAuth
        "basicAuth" : {
            // Hashing algorithm to use
            "hashAlgorithm"  : "SHA-512",
            // Iterates the number of times the hash is computed to create a more computationally intensive hash.
            "hashIterations" : 5,
            // User storage: The `key` is the username. The value is the user credentials that can include
            // { roles: "", permissions : "", firstName : "", lastName : "", password : "" }
            "users"          : {
                "testuser" : { password : "testuserpass", permissions : "read" }
            }
        }
    }
}

Basic auth settings and users are global. So they have to be in the main application configuration

I created a cbSecurity testing app. The idea is simple. The Main handler is public, the Private handler is protected.

I am not sure if I configured it correctly for basic http auth and if I need to specify provider, userService (both in cbsecurity and cbauth settings), and a validator. Regardless, I set all properties just in case.

Here are the settings. Currently, cbSecurity isn’t protecting the Private handler:

moduleSettings = {
            cbauth: {
                "userServiceClass": "BasicAuthUserService@cbsecurity"
            },
            cbsecurity: {
                // The global invalid authentication event or URI or URL to go if an invalid authentication occurs
                "invalidAuthenticationEvent"	: "main.onAuthenticationFailure",
                // Default Auhtentication Action: override or redirect when a user has not logged in
                "defaultAuthenticationAction"	: "override",
                // The global invalid userServiceClass event or URI or URL to go if an invalid authorization occurs
                "invalidAuthorizationEvent"		: "main.onAuthorizationFailure",
                // Default Authorization Action: override or redirect when a user does not have enough permissions to access something
                "defaultAuthorizationAction"	: "override",
                // The WireBox ID of the authentication service to use which must adhere to the cbsecurity.interfaces.IAuthService interface.
                "provider"                      : "BasicAuthUserService@cbsecurity",
                // WireBox ID of the user service to use when leveraging user authentication, we default this to whatever is set
                // by cbauth or basic authentication. (Optional)
                "userService"                   : "BasicAuthUserService@cbsecurity",
                // The name of the variable to use to store an authenticated user in prc scope on all incoming authenticated requests
                "prcUserVariable"               : "oCurrentUser",
                // set the validator to Basic HTTP Auth
                "validator"                     : "BasicAuthValidator@cbsecurity",
                "rules" : [
                    {
                        secureList: "private"
                    }
                ],
                // set up BasicAuth
                "basicAuth" : {
                    // Hashing algorithm to use
                    "hashAlgorithm"  : "SHA-512",
                    // Iterates the number of times the hash is computed to create a more computationally intensive hash.
                    "hashIterations" : 5,
                    // User storage: The `key` is the username. The value is the user credentials that can include
                    // { roles: "", permissions : "", firstName : "", lastName : "", password : "" }
                    "users"          : {
                        "testuser" : { password : "testuserpass", permissions : "read" }
                    }
                },
                visualizer : {
                    "enabled"      : true,
                    "secured"      : false,
                    "securityRule" : {}
                }
            }
        }

Attempting to load the visualizer brings up an exception error:
image

This dummy app doesn’t use a datasource, but the visualizer must require one.

@lmajano I’m still unable to get basic HTTP auth working on its own. Do you have an example repo I can use as a model to get my test app set up?

Dave

I will check on this but I am off on holiday right now.

Have a great vacation!

Ok, I am working on this now. I will be adding the docs and more configurations. As of now, basic authentication is application wide and not module centered. Meaning, that basic authentication MUSt be configured at the main application level in the config/coldbox.cfc or config/modules/cbsecurity.cfc if using ColdBox 7.

It works by adding the users in the basicAuth section and configuring the validator to be BasicAuthValidator@cbsecurity. This will still use cbauth as the authentication service, but it will automatically configure the user service to be BasicAuthUserService@cbsecurity for you.

cbSecurity : {

	basicAuth : {
		users : {
			"lmajano" : { password : 'test', permissions : "", roles : "admin" }
		}
	},

	authentication : {
		// The WireBox ID of the authentication service to use in cbSecurity which must adhere to the cbsecurity.interfaces.IAuthService interface.
		"provider"      : "authenticationService@cbauth"
	},

	firewall : {
		// Global Relocation when an invalid access is detected, instead of each rule declaring one.
		"invalidAuthenticationEvent" : "main.index",
		// Default invalid action: override or redirect when an invalid access is detected, default is to redirect
		"defaultAuthenticationAction" : "redirect",
		// Global override event when an invalid access is detected, instead of each rule declaring one.
		"invalidAuthorizationEvent"  : "main.index",
		// Default invalid action: override or redirect when an invalid access is detected, default is to redirect
		"defaultAuthorizationAction" : "redirect",
		// Firewall Validator
		"validator"                   : "BasicAuthValidator@cbsecurity",
		"logs" : {
			enabled : true
		}
	}
}

This configures the following:

  • Authentication Service : cbauth
  • User Service : BasicAuthUserService
  • Validator : BasicAuthService

Now, after seeing this, I will create a new ticket to allow for modular overrides. However, this complicates things because technically a Module could have it’s own authentication, user service and validator. So I will target this for 3.1.

Also, please check the new configuration items here: https://coldbox-security.ortusbooks.com/getting-started/configuration

I have finalized the basic authentication page too now: https://coldbox-security.ortusbooks.com/usage/basic-authentication

Comments, questions, suggestions?

1 Like

Thanks Luis! I haven’t had free minute to experiment. I’ll carve out some time this weekend or next week to start playing with it.