spomky-labs/oauth2-server-resource-owner-password-credentials-grant-type

Resource Owner Credentials Grant Type for OAuth2 Server


README

Scrutinizer Code Quality Code Coverage

Build Status HHVM Status

SensioLabsInsight

Latest Stable Version Latest Unstable Version Total Downloads License

This library adds a new grant type for OAuth2 Server: Resource Owner Password Credentials Grant Type.

This grant type uses a username and password of the resource owner to directly get an access token. Clients can get a refresh token (if supported by the server) by including the issueRefreshToken=true parameter in the request-body.

Prerequisites

This library needs OAuth2 Server.

Installation

Installation is a quick 3 steps process:

  • Download and install the library
  • Extend with your classes
  • Add the grant type to your OAuth2 Server

Step 1: Install the library

The preferred way to install this library is to rely on Composer:

    composer require "spomky-labs/oauth2-server-resource-owner-password-credentials-grant-type" "~4.0"

Step 2: Create your classes

This grant type needs a Resource Owner and a Resource Owner Manager. You can find abstract class you have to extend.

The Resource Owner

Simple Resource Owner

This library provides an abstract class to ease your work: OAuth2\ResourceOwner\OAuth2ResourceOwner.

You can extend it or create your own class. You just need to define how to store password and a way to check it when requested.

Feel free to add all setters and getters you need.

It the following example, we store a hash (SHA-256) of the password.

<?php

namespace ACME\MyOAuth2Server\ResourceOwner;

use OAuth2\ResourceOwner\OAuth2ResourceOwner;

class MyResourceOwner extends OAuth2ResourceOwner
{
    protected $password;

    public function setPassword($password)
    {
        $this->password = hash('sha256', $password);
        return $this;
    }

    public function getPassword()
    {
        return $this->password;
    }
}
Resource Owner With Refresh Token Extension

With this grant type, the client can ask a refresh token (if the grant type is supported by your server) and get a new access token when expired. The grant type allows the issue of a refresh token by default, but you can restrict the issuance of a refresh token depending on the client:

  • With the configuration of the server (see below)
  • With an extension applied to the resource owner

If you want to use this last feature, your user class just have to implement OAuth2\ResourceOwner\IOAuth2IssueRefreshTokenExtension.

In the following example, only Confidential clients are allowed to get a refresh token:

<?php

namespace ACME\MyOAuth2Server\ResourceOwner;

use ACME\MyOAuth2Server\ResourceOwner\MyResourceOwner;
use OAuth2\ResourceOwner\IOAuth2IssueRefreshTokenExtension;
use OAuth2\Client\IOAuth2ConfidentialClient;

class MyResourceOwnerWithExtension extends MyResourceOwner implements IOAuth2IssueRefreshTokenExtension
{
    public function isRefreshTokenIssueAllowed(IOAuth2Client $client)
    {
        return ($client instanceof IOAuth2ConfidentialClient);
    }
}

In this other example, by default no client are allowed except if they are specifically authorized:

<?php

namespace ACME\MyOAuth2Server\ResourceOwner;

use ACME\MyOAuth2Server\ResourceOwner\MyResourceOwner;
use OAuth2\ResourceOwner\IOAuth2IssueRefreshTokenExtension;

class MyResourceOwnerWithExtension extends MyResourceOwner implements IOAuth2IssueRefreshTokenExtension
{
    protected $allowedClients = array();

    public function setRefreshTokenIssueAllowed(IOAuth2Client $client, $refreshTokenAllowed)
    {
        $this->allowedClients[$client->getPublicId()] = $refreshTokenAllowed;
        return $this;
    }

    public function isRefreshTokenIssueAllowed(IOAuth2Client $client)
    {
        return isset($this->allowedClients[$client->getPublicId()])?$this->allowedClients[$client->getPublicId()]:false;
    }
}

The Resource Owner Manager

The OAuth2 Server library provides an interface: OAuth2\ResourceOwner\IOAuth2ResourceOwnerManager.

You must implement this interface and define how to verify the resource owner password credentials and get a resource owner object.

<?php

namespace ACME\MyOAuth2Server\ResourceOwner;

use OAuth2\ResourceOwner\IOAuth2ResourceOwner;
use OAuth2\ResourceOwner\IOAuth2ResourceOwnerManager;

class MyOAuth2ResourceOwnerManager extends OAuth2ResourceOwnerManager
{
    public function addResourceOwner(IOAuth2ResourceOwner $user)
    {
        return $this->resourceOwners[$user->getUsername()] = $user;
    }

    public function removeResourceOwner(IOAuth2ResourceOwner $user)
    {
        if (isset($this->resourceOwners[$username]))
        {
            unset($this->resourceOwners[$username]);
        }
    }

    public function checkResourceOwnerPasswordCredentials($username, $password)
    {
        $resourceOwner = $this->getResourceOwner($username)
        if (null === $resourceOwner)
        {
            return false;
        }
        return hash('sha256', $password) === $resourceOwner->getPassword();
    }

    public function getResourceOwner($username)
    {
        if (isset($this->resourceOwners[$username]))
        {
            return $this->resourceOwners[$username];
        }
        return null;
    }
}

Step 3: Add the grant type to your OAuth2 Server

To use this grant type, just extend the abstract class provided by this library.

<?php

namespace ACME\MyOAuth2Server

use ACME\MyOAuth2Server\ResourceOwner\MyOAuth2ResourceOwnerManager;
use OAuth2\Grant\OAuth2ResourceOwnerPasswordCredentialsGrantType;

class MyResourceOwnerGrantType extend OAuth2ResourceOwnerPasswordCredentialsGrantType
{
    protected function getExceptionManager()
    {
        //Return the Exception Manager of your server
    }

    protected function getResourceOwnerManager()
    {
        //Return the resource Owner Manager you just have created
    }

    protected function getConfiguration()
    {
        //Return the configuration object of your server
    }
}

Now you can add an instance of MyResourceOwnerGrantType to your access token endpoint.

Configuration

This grant type adds a new configuration option:

  • allow_refresh_token_with_resource_owner_grant_type (boolean, default=true):
    • if true, an refresh token is issued if requested by the client.
    • if false, clients are not allowed to get a refresh token with an access token. Note that this option has no effect if the resource owner implements OAuth2\ResourceOwner\IOAuth2IssueRefreshTokenExtension

Example:

<?php

use OAuth2\Configuration\OAuth2Configuration;

$configuration = new OAuth2Configuration(array(
    'allow_refresh_token_with_resource_owner_grant_type' => false,
));