Securing AMFPHP 1.9 via Authentication

With the loss of the methodTable in AMFPHP 1.9, comes a loss of the easily defined ‘roles.’

Background

Roles, for those of you who aren’t familiar, allow you to ‘protect’ who can invoke your AMFPHP services. For example, you probably wouldn’t want the following function accessible to everyone


public function SetEmployeeSalary($amount)

Users are ‘authenticated’ in AMFPHP via a call to


Authenticate::login($username,$roles);

Where $roles is a comma delimited set of roles for the user. If you open up \core\shared\util\Authenticate.php you’ll find the login method


function login($name, $roles) {
if(!session_id())
{
session_start();
}
$_SESSION['amfphp_username'] = $name;
$_SESSION['amfphp_roles'] = $roles;
}

Authentication in AMFPHP 1.9

To utilize authentication in 1.9, create a function with the following signature in your service (class).


public function beforeFilter($function_called)

A quick peek in /core/shared/app/BasicActions.php and you’ll see that, should your service (class) define this function, AMFPHP will call it before invoking your function. If beforeFilter returns true, the function is invoked, otherwise a security error is thrown.

Here’s the simple approach I’ve taken..


public function beforeFilter($function_called)
{
$memberName = $function_called."Roles";
return (@$this->$memberName) ? Authenticate::isUserInRole($this->$memberName) : true;
}

So to secure any function, I simply define a member variable with the roles required.


var $SetEmployeeSalaryRoles = "admin,hr";
public function SetEmployeeSalary($amount)

My beforeFilter function looks to see if functionNameRoles exists, if it does, than the user must have a role found in functionNameRoles. If functionNameRoles does not exist, no authentication is required.

13 Replies to “Securing AMFPHP 1.9 via Authentication”

  1. Good post. Do you know if it’s possible to return different values when beforeFilter fails? I want one failing state to return a message that says “This happened” and the other failing state to return a message that says “That happened”. The problem is that AMFPHP is the one sending the fault and it always comes back as:

    faultCode String AMFPHP_AUTHENTICATE_ERROR
    faultDetail String /amfphp/core/shared/app/BasicActions.php on line 121
    faultString String Method access blocked by beforeFilter in PublisherService class

    Any ideas?

  2. Ben,
    Take a look at line 120 of AMFPHP’s core/shared/app/BasicActions.php. Here’s the code

    if ($allow === ‘__amfphp_error’ || $allow === false) {
    $ex = new MessageException(E_USER_ERROR, “Method access blocked by beforeFilter in ” . $className . ” class”, __FILE__, __LINE__, “AMFPHP_AUTHENTICATE_ERROR”);
    MessageException::throwException($amfbody, $ex);
    return false;
    }

    You could do something along the lines of

    if ($allow !== true)
    {

    if($allow === ‘__amfphp_error’ || $allow === false)
    $ex = new MessageException(E_USER_ERROR, “Method access blocked by beforeFilter in ” . $className . ” class”, __FILE__, __LINE__, “AMFPHP_AUTHENTICATE_ERROR”);
    else
    $ex = new MessageException(E_USER_ERROR, $allow . ” ” . $className . ” class”, __FILE__, __LINE__, “AMFPHP_AUTHENTICATE_ERROR”);

    MessageException::throwException($amfbody, $ex);
    return false;
    }

    Where you return the error string (instead of false) from your before filter. If you *do* return false from your before filter, the legacy AMFPHP error is thrown.

    Hope that helps!!

  3. cooljack

    Make a call to a php script that validates the login credentials. If successful you could call

    Authenticate::login($usrer,$roles);

    and to destroy the session (logout)

    Authenticate::logout();

    Let me know if you need further assistance.

  4. Hi,

    I’m having a bit of trouble understanding how to implement this and was hoping you could point me in the right direction..

    I defined a class as follows but when I call the getData method from Flex, it returns fine without any authentication occuring:

    memberName) ? Authenticate::isUserInRole($this->$memberName) : true;
    }

    var $SecuredClassRoles = “admin”;
    var $GetDataRoles = “admin”;

    public function SecuredClass() {

    }

    public function GetData() {

    return “You Got In”;

    }

    }

    ?>

    Also, I noticed you posted on Wade’s site asking whether this is the ‘best’ way to implement auth – did he give you an answer or have you an updated opinion?

    cheers!

  5. I’m having troubles understanding it too…
    Can you post a full example? (I mean, the AS3 and PHP side).

    Where and when must we call Authenticate::login($username,$roles);?

    And what happens if the user doesn’t have cookies enabled?

    Thanks!!

  6. Enrique,
    You’d want to create a login function. The normal workflow would be to pass a username/password from Flex to your login function. This function would validate the username / password. (Database lookup, LDAP, etc).

    *If* it’s a valid username/password, you’d then call Authenticate::login($username,$roles) which provides the needed authentication for the subsequent AMFPHP calls.

    AMFPHP stores the authentication info in session vars so normal session rules apply.

    Josh

  7. Hello Josh,

    if it is ok with you, kindly post a working sample of this authentication thing? I could hardly, and sorry for that. I am just beginning with AMFPHP.

    thanks for caring.

Leave a Reply

Your email address will not be published. Required fields are marked *