Trouble with implementing Oauth2 library in ColdBox

Hello!

I’ve been trying to implement a ColdFusion Oauth2 library onto my ColdBox application for the purpose of allowing users to log in with their Microsoft accounts. This is the Oauth2 library in question.

I have used the following code in a handler for sessions to attempt to instantiate a new component from this Oauth2 library that will allow me to obtain tokens for authorization.

image

The following are the injections I have made at the top of this handler file:

image

The following is the constructor method for the ‘microsoft’ component.

When I trigger this event and call the constructor for this ‘microsoft’ object, I get an error telling me that I did not provide the first argument to the constructor, which seems odd to me, as I obviously have.

My question to you all is, am I sane? I am fairly new to ColdBox, so there’s a definite possibility that I’m missing something trivial here. I can provide additional information if needed.

Instead of new microsoft(...), try microsoft.init(...). I’m not super knowledgeable on the nuts-and-bolts of how Wirebox works, but I do know that you don’t need the new keyword when you’re working with injected components.

1 Like

Thanks for the response!

I tried this and, unfortunately, it yielded the same error message.

I tried both

getInstance(“microsoft”).init(…)

and

microsoft.init(…)

Hmm. I’m not sure, then. You can always fall back to vanilla CFML: new microsoft(...), just remember to remove the injection from the top of your handler and reinit the application to pick up the injection changes.

1 Like

Hi Michael, thanks again for being willing to help out.

I did a bit of testing where I removed the injections and still got similar error messages, as well as using include statements for the .cfc file of the ‘microsoft’ component. Strangely enough, Coldbox couldn’t even find the component from the includes. That’s a problem for another day though!

The farthest I’ve gotten with making the library cooperate is using the injections and reaching the error message where ColdBox says that I’m not passing in the first argument. This really is quite strange, given I have other custom components that I can inject and use in the application in other places. However, in those other custom components, the constructors do not have parameters.

This ‘microsoft’ component only has one constructor, and it is parametric. My experience in C++ tells me that I should create a default one in order for an object to work, but I know CFML is a horse of a different color.

Update:
It appears wirebox can successfully inject the component AND get past the errors regarding the missing argument if I remove all of the arguments from the the init() method. This is definitely a non-fix, but at least I know I have isolated the problem to knowing that when wirebox tries to inject the .cfc, it runs the init() method without any arguments.

Now, I’m doing some research of my own right now on this question, but how do I inject a component with arguments to its init() method?

I’m really out of my depth with this one, but I would take a look at this page in the Wirebox docs:

You may want something like this:

map("microsoft")
    .to("oauth2.whatever.microsoft")
    .initWith(
           client_id=getSystemSetting('MS_CLIENT_ID'),
           client_secret=getSystemSetting('MS_CLIENT_SECRET'),
           // and so forth...
    );

then you should be able to define your MS_CLIENT_ID and etc. values in a .env file, or use getProperty() to grab those creds from the coldbox settings in config/ColdBox.cfc.

The docs are your friend here, I’ve only grabbed an example which I think might work. :slight_smile:

1 Like

Got it. I’ll start looking around here!

This code is starting look complex for me just wanting to construct a component with required parameters, though. I’ll also consider looking back at getting the simple include statement working.

I’ll also consider looking back at getting the simple include statement working.

This confuses me… how do you “include” a cfc? I did suggest a vanilla CFML approach, but you said you “still got similar error messages”. Which, IMO, means you got a different error message, and declined to share. :smiley: Hard to help without seeing what that error message was.

Right, sorry about not elaborating on that!

I’m very new to ColdFusion and ColdBox, and I’ve been taking the Adobe ColdFusion Specialist certification course. One part of the course discussed an “include ‘path/to/file’” statement which seemed near equivalent to the include and import statements from C and Python respectively. My understanding is that if I included a .cfc file, I could use the component defined within it in the file that the include statement was called from.

However, include statements were not discussed in the ColdBox training I’ve seen, so if you’ve never heard of the use and you’re part of Team Ortus, it’s definitely not something normal to do in ColdBox.

And yes, you are correct! If vanilla CFML means using include statements, then it was a different error message that was something to the degree of not knowing what the microsoft object was when I was attempting to create a new one. The include statement worked in that it found the microsoft.cfc file, but ColdFusion still didn’t know what the microsoft component was.

EDIT: This is the include statement at the top of the sessions handler and the error message from trying to use it to define the microsoft component.

image

If that’s not a vanilla CFML approach, then I’m just unaware of what the vanilla one actually is.

1 Like

Ok, so yeah, that’s a totally different issue. I didn’t realize you were this new to CFML. (And welcome aboard! :partying_face: )

I was confused because include "path/to/file" only works on .cfm files. Period. This is commonly used for templates, i.e. for fleshing out your HTML. You wouldn’t want to use include in your business logic. For more info, check out this helpful guide on include:

It sounds like you also need a refresher on the vanilla CFML way to create and init a component:

The “vanilla CFML” way to create your microsoft component would look something like this:

var microsoftAPI = new models.microsoft();

Forgive me, as it’s been a while since I used the above syntax, but I think you can provide your client_id, etc. args right in those parantheses above. If not, you can append a .init( myArg = "value1", etc... )

There are a few beginner things you’ll have to be aware of. For example, you can’t do path traversal when creating components. i.e., this won’t work: new ../models.microsoft(). This is why we use Wirebox, so we can setup “mappings” to a package and inject that package’s components from any location in our app.

See also createObject() examples in the LearnCFInAWeek.com tutorial on Components:

http://learncfinaweek.com/course/index/section/Code_Reuse/item/Components

Good luck!

1 Like

Thank you so much, Michael!

I’m still a bit intimidated by wirebox and its trappings, so this vanilla method works great for me. Will update with results.

1 Like

Additional update on this solution:

I was able to successfully use this library: https://github.com/jeffstevens98/oauth2

But I needed to modify it to get it working with the changes the Azure Application development platform has made since the last update. Once I was able to bring the oauth2 object into the application (Thanks to Michael Born) I made a token request and then received a code which I pointed the user’s browser to which returned a JSON file containing an access token.

I had some trouble with this initially, but I needed to sent JUST the token access code from the JSON, nothing else from the JSON, in my API request.

After that, we were in business! No other problems seeming to originate from ColdBox.