getPlugin in an Inteceptor

I am trying to write a basic security inteceptor and I am having an
issue. In my pre process I am trying to get the session using the
session storage plugin. When I make a method call getPlugin() i get
the following error.

Application Execution Exception
Error Type: Expression : [N/A]
Error Messages: Cannot invoke method getPlugin on an object of type
coldfusion.runtime.Struct with named arguments.
Use ordered arguments instead.

Any ideas?

<cfcomponent displayname="Security Interceptor" output="false"
extends="coldbox.system.interceptor">

  <cffunction name="init" access="public" returntype="any"
output="false">
    <cfargument name="web" type="coldbox.system.web.Controller"
required="true">
    <cfargument name="params" type="struct" default="">
    <cfset setBlackList(arguments.params.blacklist)>
    <cfreturn this>
  </cffunction>

  <cffunction name="configure" access="public" returntype="any"
output="false">
  </cffunction>

  <cffunction name="preProcess" access="public" returntype="void"
output="false">
    <cfargument name="event" type="any" required="true">
    <cfset var loggedin = false />
    <cfset var rc = event.getCollection()>
    <cfset oSession = getPlugin("SessionStorage")>

    <cfif listContains(getBlackList(),rc.event)>
      <!--- this page is a secure page and the user needs to be logged in
to get there --->

      <cfset event.overrideEvent("login.index") />
    </cfif>

  </cffunction>

  <!--- accessors --->
  <cffunction name="setBlackList" access="private" returntype="void"
output="false">
    <cfargument name="blacklist" type="string" required="true">
    <cfset variables.blacklist = arguments.blacklist>
  </cffunction>
  <cffunction name="getBlackList" access="private" returntype="string"
output="false">
    <cfreturn variables.blacklist>
  </cffunction>

</cfcomponent>

Dan you cannot create an init method for an interceptor unless you
override it and make sure it implements the right argument signature
and call super.init on it. We tried to made interceptors auto inited
by coldbox. Please take a look at some interceptor samples for
direction. Basically you use the configure method as your constructor.
Just beware on what you do in the configure method as most likely it
is called in onapplicationstart so session might not be defined yet or
other application aspects like IOC javaloader etc.

I was really just trying to follow this example

http://www.dougboude.com/blog/1/2008/11/Basic-Security-in-Coldbox-using-Transfer-and-Coldspring--Part-I.cfm

He does the same thing

<cfset oSession = getPlugin("sessionstorage") />

But when I do that I get an error.

Hi Dan.

The error almost makes it look as if your interceptor isn’t being instantiated correctly, as it refers to your interceptor as a structure…I don’t think CF is"seeing" it properly. I opened my own security interceptor to compare code, and the glaring difference is that you have an init method whereas I don’t. I think (as Luis pointed out) that you may have better success if you find another way of injecting the required startup arguments into your interceptor, perhaps using a combination of your interceptor properties in coldbox.xml.cfm and the “config” method of the interceptor. For instance, in another of my interceptors, within its config method, I grab the sessionstorage plugin via “instance.session = getPlugin(“sessionstorage”)” so that it’s globally available to all methods within that interceptor.

You can also do autowiring in interceptors, or leverage one of the other pre-canned methods such as “AfterAspectsLoad” to inject the needed values. So definitely I believe the key to resolving this one is in looking for those alternative ways (besides an init method) of getting the needed values into the interceptor during initialization.

Doug Boude

Dan,

The problem is that if you override the init() method, it has to have the interceptor base signature:

super.init(argumentCollection=arguments);

///Your code here

However, for interceptors the configure() method is the way to configure them right after the framework creates them. As far as dependencies go, you can use what you are doing or just add cfproperties so the objects are autowired automatically. I usually go this way.

Luis

Thanks for responding guys.. I am still a coldbox newbie so I
appreciate the help!

Makes a lot more sense now that I have a basic understanding of what's
going on. I have updated my code but from what I understand I am not
sure how this would work. If the interceptor gets cached in the
onApplicationStart the session variables will never exist. When I go
to grab the values in my pre process they are always undefined.

If the event is in the black list and the user is not logged in I want
to show the login form. That works, but even when I get "logged in" it
always shows the login screen because those session vars don't exist.

What am I missing?

<cfcomponent displayname="Security Interceptor" output="false"
extends="coldbox.system.interceptor">

  <cffunction name="configure" access="public" returntype="any"
output="false">
    <cfset setBlackList(getProperty("blacklist"))>
  </cffunction>

  <cffunction name="preProcess" access="public" returntype="void"
output="false">
    <cfargument name="event"
type="coldbox.system.web.context.RequestContext" required="true">
    <cfargument name="interceptData" type="struct" required="true">
    <cfset var rc = event.getCollection()>
    <cfset var oSession = getPlugin("SessionStorage")>

    <cfif listContains(getBlackList(),rc.event)>
      <!--- this page is a secure page and the user needs to be logged in
to get there --->
      <cfif NOT oSession.exists("isLoggedIn") OR NOT oSession.getVar
("isLoggedIn")>
        <cfset event.overrideEvent("login.index") />
      </cfif>
    </cfif>

  </cffunction>

  <!--- accessors --->
  <cffunction name="setBlackList" access="private" returntype="void"
output="false">
    <cfargument name="blacklist" type="string" required="true">
    <cfset variables.blacklist = arguments.blacklist>
  </cffunction>

  <cffunction name="getBlackList" access="private" returntype="string"
output="false">
    <cfreturn variables.blacklist>
  </cffunction>

</cfcomponent>

in the code that performs your login, it is there that you should be explicitly setting a value in session that indicates your user is logged in. Once you’ve done that, when the interceptor preprocess event checks session, it will see that value. Even though the interceptor itself is cached, its call to check the variable in session is fresh every time it is executed.

Am I missing something?

Doug Boude