PHP Classes

PHP User Auth System: HTTP authentication using PSR-7 interfaces

Recommend this page to a friend!
  Info   View files Example   View files View files (49)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
Not yet rated by the usersTotal: 231 All time: 8,144 This week: 69Up
Version License PHP version Categories
authsystem 1.0.0MIT/X Consortium ...5PHP 5, User Management, PSR
Description 

Author

This package can HTTP authentication using PSR-7 interfaces.

It uses PSR-7 interface implementation for request and response classes that will read the authentication request values and generates the necessary responses.

Separate classes implement the authentication of users from a file based database of user and password records.

It provides classes to check if the user is already logged in an authenticate him in case he isn't.

Innovation Award
PHP Programming Innovation award nominee
August 2017
Number 13
PSR-7 is a PHP standards recommendation for abstracting information sent and received via HTTP requests.

This package implements a user authentication system that abstracts the way HTTP request and response headers are sent and received, so it can work with many different Web server architectures.

Manuel Lemos
Picture of Payam Naderi
  Performance   Level  
Name: Payam Naderi <contact>
Classes: 15 packages by
Country: United States United States
Age: 41
All time rank: 2018285 in United States United States
Week rank: 275 Up28 in United States United States Up
Innovation award
Innovation award
Nominee: 2x

Example

<?php
namespace Poirot\AuthSystem\Authenticate\Identifier\HttpDigest
{
    use
Poirot\Http\Interfaces\iHttpRequest;

   
/**
     * Has Request Contains Authorization Header
     *
     * @param iHttpRequest $request
     * @param bool $isProxy
     *
     * @return bool
     */
   
function hasAuthorizationHeader(iHttpRequest $request, $isProxy = false)
    {
        if (
$isProxy)
           
$headerName = 'Proxy-Authorization';
        else
           
$headerName = 'Authorization';


       
$hValue = false;

       
$headers = $request->headers();
        if (
$headers->has($headerName)) {
           
$h = $headers->get($headerName)->current();
           
$hValue = $h->renderValueLine();
        }

        return
$hValue;
    }

   
/**
     * Parse Authorization Header
     *
     * Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
     *
     * - in case of basic extract given username/password
     *
     * @param string $headerValue
     * @param null|string $clientScheme Basic|Digest, null detect from header
     *
     * @return array
     * @throws \Exception
     */
   
function parseAuthorizationHeader($headerValue, $clientScheme = null)
    {
        if (
$clientScheme === null) {
            list(
$clientScheme) = explode(' ', trim($headerValue));
           
$clientScheme = strtolower($clientScheme);
        }

        if (!
in_array($clientScheme, array('basic', 'digest')))
            throw new \
Exception(sprintf('Client Scheme (%s) Not Supported.', $clientScheme));

        if (
$clientScheme == 'basic')
           
$parsed = parseBasicAuthorizationHeader($headerValue);
        else
           
$parsed = parseDigestAuthorizationHeader($headerValue);

        return
$parsed;
    }

   
/**
     * Parse Basic Authorization Header Value To It's
     * Credential Values
     *
     * Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
     *
     * @param string $headerValue
     *
     * @return array [username=>'', 'password'=>'']
     * @throws \Exception Invalid Header
     */
   
function parseBasicAuthorizationHeader($headerValue)
    {
       
// Decode the Authorization header
       
$auth = substr($headerValue, strlen('Basic '));
       
$auth = base64_decode($auth);
        if (!
$auth)
            throw new \
RuntimeException('Unable to base64_decode Authorization header value');

        if (!
ctype_print($auth))
            throw new \
Exception('Invalid or Empty Authorization Credential.');

       
$creds = array_filter(explode(':', $auth));
        if (
count($creds) != 2)
            throw new \
Exception('Invalid Authorization Credential; Missing username or password.');

       
$credential = array('username' => $creds[0], 'password' => $creds[1], 0=>$creds[0], 1=>$creds[1]);
        return
$credential;
    }

   
/**
     * Parse Digest Authorization header
     *
     * credentials = "Digest" digest-response
     * digest-response = 1#( username | realm | nonce | digest-uri
     * | response | [ algorithm ] | [cnonce] | [opaque]
     * | [message-qop] | [nonce-count] | [auth-param] )
     *
     * @param string $headerValue
     *
     * @return array
     * @throws \Exception Invalid Header
     */
   
function parseDigestAuthorizationHeader($headerValue)
    {
       
preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $headerValue, $matches, PREG_SET_ORDER);
   
       
$data = array();
        foreach (
$matches as $m) {
           
$key = $m[1];
           
$value = ($m[2]) ? $m[2] : $m[3];
   
            switch (
$key) {
                case
'realm':
                case
'username':
                    if (!
ctype_print($value))
                        throw new \
Exception('Invalid "realm" or "username"');
                    break;
                case
'nonce':
                    if (!
ctype_xdigit($value))
                        throw new \
Exception('Invalid "nonce"');
                    break;
               
/*
                * A string of 32 hex digits computed as defined below, which proves
                * that the user knows a password
                */
               
case 'response':
                    if (
32 != strlen($value) || !ctype_xdigit($value))
                        throw new \
Exception('Invalid "response"');
                    break;
               
/*
                 * Indicates what "quality of protection" the client has applied to
                 * the message. If present, its value MUST be one of the alternatives
                 * the server indicated it supports in the WWW-Authenticate header.
                 */
               
case 'qop':
                    break;
               
/*
                 * This MUST be specified if a qop directive is sent (see above), and
                 * MUST NOT be specified if the server did not send a qop directive in
                 * the WWW-Authenticate header field. The nc-value is the hexadecimal
                 * count of the number of requests (including the current request)
                 * that the client has sent with the nonce value in this request. For
                 * example, in the first request sent in response to a given nonce
                 * value, the client sends "nc=00000001". The purpose of this
                 * directive is to allow the server to detect request replays by
                 * maintaining its own copy of this count - if the same nc-value is
                 * seen twice, then the request is a replay.
                 */
               
case 'nc':
                    if (
8 != strlen($value) || !ctype_xdigit($value))
                        throw new \
Exception('Invalid "nc"');
                    break;
            }
   
           
$data[$key] = $value;
        }
   
        return
$data;
   
       
## cnonce -----------------------------------------------------------------
        /*
         * Nonce-count. This a hexadecimal serial number for the request.
         * The client should increase this number by one for every request.
         *
         * This MUST be specified if a qop directive is sent (see above), and
         * MUST NOT be specified if the server did not send a qop directive in
         * the WWW-Authenticate header field. The cnonce-value is an opaque
         * quoted string value provided by the client and used by both client
         * and server to avoid chosen plaintext attacks, to provide mutual
         * authentication, and to provide some message integrity protection.
         */
   
}
}


Details

Poirot\AuthSystem

HTTP authentication using PSR-7 interfaces.

It uses PSR-7 interface implementation for request and response classes that will read the authentication request values and generates the necessary responses.

Separate classes implement the authentication of users from a file based database of user and password records.

It provides classes to check if the user is already logged in an authenticate him in case he isn't.

Overview usage sample

$request  = new HttpRequest(new PhpServerRequestBuilder);
$response = new HttpResponse(new PhpServerResponseBuilder);
$lazyLoad = new LazyFulfillmentIdentity(['fulfillment_by' => 'username', 'data_provider' => new UserData]);
$auth     = new Authenticator\HttpSessionAuth([
    'identity' => $lazyLoad,
    'request'  => $request,
    'response' => $response,
]);
try {
    $credential = null;
    ## check user has authenticated
    login_user:
    $auth->authenticate($credential);
    echo 'Continue ...';
    if (!$auth->isSignIn()) {
        $auth->signIn();
        header('Location: '.$request->getUri()->getPath()->toString());
        die();
    }
} catch (WrongCredentialException $e) {
    throw new \Exception('Invalid Username or Password.');
} catch (UserNotFoundException $e) {
    throw new \Exception('Invalid Username or Password.');
} catch (AuthenticationException $e)
{
    if ($e->getAuthenticator() instanceof Authenticator\HttpSessionAuth)
    {
        ### handle login with satisfy request
        if ($request->plg()->methodType()->isPost()) {
            $credential = new UserPassCredential($request->plg()->phpServer()->getPost());
            goto login_user;
        }
        ### challenge user with login form, redirection or etc.
        $response->setBody('
                <form method="post" action="" enctype="application/x-www-form-urlencoded">
                     <input type="text" name="email">
                     <input type="password" name="password">
                     <input type="submit" value="send">
                </form>
                <p>Please Login ...</p>
            ');
    }
}
## run rest of program
if ($auth->hasAuthenticated()) {
    $response->setBody("<h1>Hello User {$auth->identity()->getEmail()}</h1>");
}
### send response
$response->flush();

TODO

  • Aggregate Authenticator
  • Aggregate Adapter
  • Write Authentication Service Layer On Top Of Adapters For Application Dispatching Control

  Files folder image Files  
File Role Description
Files folder imageAuthenticate (2 files, 7 directories)
Files folder imageAuthorize (1 directory)
Files folder imagedata (1 file)
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file README.md Doc. Documentation
Accessible without login Plain text file _functions.php Example Example script

  Files folder image Files  /  Authenticate  
File Role Description
Files folder imageCredential (2 files)
Files folder imageExceptions (9 files)
Files folder imageIdentifier (9 files)
Files folder imageIdentity (6 files)
Files folder imageIdentityProvider (1 file)
Files folder imageInterfaces (7 files, 1 directory)
Files folder imageRepoIdentityCredential (4 files)
  Plain text file Authenticator.php Class Class source
  Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files  /  Authenticate  /  Credential  
File Role Description
  Plain text file CredentialOpen.php Class Class source
  Plain text file CredentialUserPass.php Class Class source

  Files folder image Files  /  Authenticate  /  Exceptions  
File Role Description
  Plain text file exAccessDenied.php Class Class source
  Plain text file exAuthentication.php Class Class source
  Plain text file exBadRequest.php Class Class source
  Plain text file exLoadUserFailed.php Class Class source
  Plain text file exMissingCredential.php Class Class source
  Plain text file exNotAuthenticated.php Class Class source
  Plain text file exUserNotActivated.php Class Class source
  Plain text file exUserNotFound.php Class Class source
  Plain text file exWrongCredential.php Class Class source

  Files folder image Files  /  Authenticate  /  Identifier  
File Role Description
  Plain text file aIdentifier.php Class Class source
  Plain text file aIdentifierHttp.php Class Class source
  Plain text file IdentifierBasicAuth.php Class Class source
  Plain text file IdentifierHttpBasicAuth.php Class Class source
  Plain text file IdentifierHttpDigestAuth.php Class Class source
  Plain text file IdentifierHttpSession.php Class Class source
  Plain text file IdentifierSession.php Class Class source
  Plain text file IdentifierWrap.php Class Class source
  Plain text file IdentifierWrapIdentityMap.php Class Class source

  Files folder image Files  /  Authenticate  /  Identity  
File Role Description
  Plain text file aIdentity.php Class Class source
  Plain text file IdentityFulfillment.php Class Class source
  Plain text file IdentityFulfillmentLazy.php Class Class source
  Plain text file IdentityHttpDigest.php Class Class source
  Plain text file IdentityOpen.php Class Class source
  Plain text file IdentityUsername.php Class Class source

  Files folder image Files  /  Authenticate  /  IdentityProvider  
File Role Description
  Plain text file ProviderNothing.php Class Class source

  Files folder image Files  /  Authenticate  /  Interfaces  
File Role Description
Files folder imageHttpMessageAware (2 files)
  Plain text file iAuthenticator.php Class Class source
  Plain text file iCredential.php Class Class source
  Plain text file iCredentialHttpAware.php Class Class source
  Plain text file iIdentifier.php Class Class source
  Plain text file iIdentity.php Class Class source
  Plain text file iIdentityCredentialRepo.php Class Class source
  Plain text file iProviderIdentityData.php Class Class source

  Files folder image Files  /  Authenticate  /  Interfaces  /  HttpMessageAware  
File Role Description
  Plain text file iAuthenticator.php Class Class source
  Plain text file iIdentifier.php Class Class source

  Files folder image Files  /  Authenticate  /  RepoIdentityCredential  
File Role Description
  Plain text file aIdentityCredentialAdapter.php Class Class source
  Plain text file IdentityCredentialDigestFile.php Class Class source
  Plain text file IdentityCredentialWrap.php Class Class source
  Plain text file IdentityCredentialWrapIdentityMap.php Class Class source

  Files folder image Files  /  Authorize  
File Role Description
Files folder imageInterfaces (2 files)

  Files folder image Files  /  Authorize  /  Interfaces  
File Role Description
  Plain text file iAuthorize.php Class Class source
  Plain text file iResourceAuthorize.php Class Class source

  Files folder image Files  /  data  
File Role Description
  Accessible without login Plain text file users.pws Data Auxiliary data

 Version Control Unique User Downloads Download Rankings  
 100%
Total:231
This week:0
All time:8,144
This week:69Up