4.2. Security / Authentication

PHOCOA includes a simple yet extensible security architecture. PHOCOA's WFAuthorizationManager is in charge of coordinating security and authentication.

PHOCOA maintains a session object which is an instance of WFAuthorizationInfo. This class contains basic information about the currently logged in user (if there is one), such as the user's id, is the user a "super-user", has the user authenticated "recently", etc. This is enough information for most applications, but if you have more complicated access control, you can subclass WFAuthorizationInfo and add any information you need for your system.

The basic granularity of security is at the module level. This assumption is made since modules typically include related pages which share the same access restrictions. Thus, usually a user that can access one page in a module should be able to access all others.

Access control to a module is determined by the checkSecurity method. The default implementation allows unrestricted access. To secure access to a module, you simply override the checkSecurity method in your WFModule subclass. The only parameter to this function is the current WFAuthorizationInfo instance, and you return either WFAuthorizationManager::ALLOW or WFAuthorizationManager::DENY. You can use whatever logic you want to in this method to determine access rights.

function checkSecurity (WFAuthorizationInfo $authInfo)
{
    if ($authInfo->isSuperUser()) return WFAuthorizationManager::ALLOW;
    return WFAuthorizationManager::DENY;
}
Of course, data security also is important at the object level. For instance, a logged-in customer should only be able to edit his own record. To implement security at this level, the programmer should check the credentials of the logged in user against the data being edited. If the logged in user should be denied access, this can be done simply by throwing a WFAuthorizationException.

PHOCOA automatically handles logins. When a client attempts to access a module, and the checkSecurity method returns DENY, PHOCOA will automatically handle the situation. If the user is already logged in, they will be shown an "Access Denied" message. If there is no logged in user, the client will be redirected to the login page, and upon successful login, will be redirected back to the original request.

PHOCOA's login system handles all of the details of login except for determining if a given user/pass is valid, and setting up the "permissions" for the user. Your application need only supply PHOCOA with a WFAuthorizationDelegate instance to provide that functionality.

Your application tells PHOCOA which WFAuthorizationDelegate instance to use. We recommend that you do this in your WFWebApplicationDelegate's initialize() delegate method:

WFAuthorizationManager::sharedAuthorizationManager()->setDelegate( new MyAuthorizationDelegate() );

WFAuthorizationDelegate is an informal protocol that contains a number of methods which help PHOCOA automate authorization-related tasks. There is only one required method, login():

object WFAuthorizationInfo login (string $username, string $password, boolean $passIsToken)

All this function needs to do is determine whether or not the username/password combo is valid, and then create a WFAuthorizationInfo instance for the user's session. If the login is not valid, then return NULL.

Notice the $passIsToken parameter; this is used for a "Remember me" feature. If the user chooses to preserve his login info on his computer, and the session times out, PHOCOA will automatically try to log in the user again with a stored token. If this parameter is true, the password will be a hash of the password stored in the user's cookie rather than the actual password.

Note

If you think need to use multiple delegates in your application, we recommend that you set a different php_ini "session.name" for each authorization delegate. Since PHOCOA stores the WFAuthorizationInfo instance in a session, it is important to ensure that the proper instance is recalled for the current request.