php-uniauth - v1.1.1 -------------------------------------------------------------------------------- This PHP extension provides authentication session management via a uniauth server. The extension implements an authentication flow designed to make user authentication universal among applications talking to the same uniauth server. The implementation consists of an extension that provides PHP userspace a high-level interface for connecting with a uniauth server and manipulating sessions. Uniauth server implementations: *NOTE* The following implementation is used for this extension. Linux: https://git.rserver.us/network/uniauthd.git Primary author: Roger Gee <rpg11a@acu.edu> -------------------------------------------------------------------------------- The Uniauth Flow Uniauth implements a user authentication flow for web applications. This flow involves a persistent uniauth server and a stateless client. Whenever the client needs to check user authentication, it connects to the server and queries a session record by ID. Likewise, when the client needs to create and authenticate a session, it uses the server to store and update the session information. There are two roles in the flow taken by applications: 1. applicant 2. registrar The applicant endpoint queries authentication status and, if none is found, redirects to the registrar endpoint for registration, during which process authentication occurs. The registrar then redirects the user-agent back to the applicant, upon which event the applicant queries authentication status and finds that it exists. This entire process happens transparently in the applicant: the applicant does not have to handle both cases separately. The registrar endpoint provides a means to collect user credentials and authenticate users. Once the registrar has verified user credentials, it submits the collected user ID and name (along with a display name) to the uniauth server. The server assigns this information to an internal session, thus registering the user as authenticated. Internally, this uniauth registration is shared among all applications that use the registrar endpoint for the same user. While the specifics of uniauth sessions may differ between server implementations, the basic idea is that a single registration is maintained among all applicants targeting the same registrar. The means that the server internally connects the applicant and registrar sessions so that they point at the same registration. This allows applicants from different domains (i.e. having different session IDs) to utilize the same registration. -------------------------------------------------------------------------------- Storage A uniauth server maintains a database of authentication records that hold information about the user session. Records are keyed by a session ID (sometimes called a session key in this document). This ID may be provided by the userspace script. If the userspace script does not provide a session ID, the PHP session ID will be used as the uniauth session ID instead. (This means you must have already called session_start() in your program). *NOTE* The extension does not actually manipulate the PHP session data itself if it uses the session ID. Instead it uses the configured session ID to key the uniauth records it creates with the server. This frees PHP userspace from having to track this information in its session. You can however still use the PHP session backend to store additional session values. If a PHP session is not required, then a separate cookie can be used instead. To avoid boilerplate associated with creating cookies and generating uniauth keys, the uniauth_cookie() function is provided. This function generates a random cookie session, overriding the default behavior of using the PHP session when using the other extension functions. It also sets the cookie so it gets transmitted to the user agent. -------------------------------------------------------------------------------- PHP Userspace Functions Overview Applicant Endpoint: The core function used by applicants is uniauth(), which checks to see if a registration exists for session (i.e. checks if the session is authenticated). If not, it transparently redirects the user-agent to the specified registrar endpoint. Otherwise, the function returns an associative array containing the 'id', 'user' and 'display' records for the entry. When an applicant redirects to a registrar, it passes the uniauth session ID via a GET query parameter named 'uniauth'. This allows the registrar to identify the target session that is to be associated with the registration should authentication be successful. Note: a uniauth session is considered authenticated by the standard when there is a valid ID associated with the session (i.e. id >= 1). A call to uniauth() is the minimum that is required for applicants. This call will transparently begin the redirect flow. Registrar Endpoint: When calling a registrar endpoint, one of two things can happen. 1. There is no uniauth session for the registrar: In this case, a session must be created and authenticated. The registrar endpoint calls uniauth_apply() to begin this process. This function takes the query parameter passed from the applicant's call to uniauth() and stores it in a new uniauth session. It must set a cookie (possibly via uniauth_cookie()) or use the PHP session to track the new uniauth session. Now the registrar can present a login form or similar means to collect user credentials. When the credentials have been verified, the uniauth_register() function can be called with the correct information. This updates the registration associated with the registrar session. Once registration is complete, the registrar session is authenticated and ready to transfer. Finally, the uniauth_transfer() function is called to transfer the registrar session into the applicant session. Internally this updates the applicant session to point at the same registration as the registrar session. This function will automatically redirect the user-agent back to the original, applicant endpoint, thus "transferring" back to the original applicant endpoint. 2. There is already an authenticated uniauth session for the registrar: In this case the functionality should skip to calling uniauth_transfer(). The uniauth_check() function is provided for the registrar endpoint so that it can check if an authenticated session exists. This should be done before calling uniauth_apply() in the former case. If 'true' is returned, then the registrar can skip to calling uniauth_transfer() (i.e. case #2 is true). Logging Out: To explictly invalidate a uniauth session, the uniauth_purge() API may be employed. This function clears out the registration associated with the session ID so the user login status is void. Note that this will log out all services (i.e. applicants) that have sessions referencing the registration. The session record is not technically freed until it expires naturally. This means the same session IDs can be reused for future authentications until the user-agent drops the cookie. -------------------------------------------------------------------------------- PHP Userspace Functions Detail Generate notes: Unless a connection error occurs, all functions throw upon error. It is recommended that you wrap all uniauth calls in a try-catch block so as to report errors. Some functions have unusual side effects, such as setting superglobal values or cookies or aborting the script. Make sure you are aware of these. array uniauth([string $url, string $session_id]) This function looks up an authenticated uniauth session. The function returns the session information as a login array if an authenticated session was found. If not, the function's behavior depends on whether an authentication endpoint url was specified: If an authentication endpoint url was specified, the function sends a redirect header pointing at the specified URL for the registrar endpoint. It then aborts the script. Otherwise (if url=null) the function just returns null, indicating that no authenticated session was available. The calling script has no awareness that a redirect occurred. Thus the redirect flow happens transparently. If the second parameter is specified, then the function uses the requested session ID. Otherwise, the current PHP session ID is used unless uniauth_cookie() was previously called. $url - The url of the registrar endpoint handling the authentication. This parameter may be null to avoid a redirect and just query the status of a uniauth session. $session_id - An override uniauth session ID to use in place of the default behavior. Return value: an array with the following keys pulled from the uniauth session: id - user tracking ID as determined by the registrar user - user handle as determined by the registrar display - user display name as determined by the registrar Returns mnull if no session was available and a redirect did not occur. bool uniauth_check([string $session_id]) This function determines if an authenticated session exists. It does not update the session expiration. $session_id - Uniauth session ID to use (optional) The actual session ID used is determined in the same way as in the uniauth() function. Return value: true is returned if the specified session exists and is authenticated. False is returned if the specified session does not exist or exists but is not authenticated. NOTE: This function is largely obsolete in applicant implementations due to changes to the uniauth() function. Prefer calling uniauth(null) over using uniauth_check() when needing to conditionally obtain a session's login array. GOOD: $login = uniauth(null); BAD: if (uniauth_check()) $login = uniauth('http://auth.tld') else $login = null; void uniauth_apply([string $session_id]) This function creates a uniauth session for the registrar endpoint application (if it doesn't exist). The function annotates the new registrar session with the applicant session ID, which is passed in using a 'uniauth' query parameter in the request. This function should only be called in the initial GET request to the registrar endpoint. It must be called before any uniauth_transfer() call would succeed. $session_id - Uniauth session ID to use (optional) The actual session ID used is determined in the same way as in the uniauth() function. The session ID is determined in the same way as in the uniauth() function. void uniauth_register(int $id, string $name, string $display_name[, string $session_id, int $lifetime]) This function is used to register (i.e. authenticate) a uniauth session. It assigns the specified user information into the current/specified uniauth session. After a successful call, the session is now authenticated. $id - Application-defined user ID for the session $name - Application-defined user name for the session $display_name - Application-defined user display name for the session $session_id - Uniauth session ID to use (optional) The actual session ID used is determined in the same way as in the uniauth() function. $lifetime - Defines the session lifetime starting from the current instant (optional) If this value is omitted or a non-positive number, then the uniauth session will have a lifetime equal to the value of the php.ini option "uniauth.lifetime" and the uniauth cookie (if any) is a persistent cookie. The default value for "uniauth.lifetime" is 86400, or 1 day; the value for this setting indicates the number of seconds for the lifetime. Otherwise the uniauth session has the specified lifetime and the uniauth cookie (if any) will be a session cookie. void uniauth_transfer([string $session_id]) This function is used to transfer the information from one session (i.e. the source session) into another (i.e. the destination session). Internally this merely updates the destination session to point at the source session. Practically, the source session is the registrar session and the destination is the applicant session. The destination session ID is pulled from the source session. It was set previously in a call to uniauth_apply(). $session_id - Uniauth session ID to use (optional) The actual session ID used is determined in the same way as in the uniauth() function. This function technically does not return and will bail out to perform the redirect. Otherwise it will throw an exception on failure. bool uniauth_purge([string $session_id]) This functions ends the current uniauth session. $session_id - Uniauth session ID to use (optional) The actual session ID used is determined in the same way as in the uniauth() function. Note: this function merely invalidates the uniauth session. The session lifetime actually persists, which means the backend record can be reused in future authentication attempts within a certain amount of time. Any cookies used to track the session ID should also be preserved so as to avoid having to regenerate the session within a certain amount of time. Returns true if the session was valid and was invalidated, false otherwise. string uniauth_cookie() This is a convenience function used to eliminate boilerplate associated with when you want to use a simple cookie to track the session ID instead of the PHP session. This function will randomly generate a 64-character ID and set it in a cookie with name="uniauth". If such a cookie already exists, it merely continues to use that session ID. Another vital behavior of this function is that it overrides the default behavior of most uniauth functions when determining the default session ID. Instead of using the PHP session by default, the functions' default behavior will be to use the uniauth cookie. For example: // This call will use the PHP session ID. session_start(); uniauth("http://localhost/auth.php"); // This call will use the generated uniauth cookie. uniauth_cookie(); uniauth("http://localhost/auth.php"); Return value: the function returns the session ID. Note that this value can also be grabbed from the $_COOKIE superglobal (without another request) since the function makes sure the cookie's value is set as part of its implementation. NOTE: using uniauth cookies will overwrite any existing cookies! You should always make uniauth calls before any other calls to set cookies!