Yii 2.0: yii2-oauth2

OAuth2 server integration (using bshaffer oauth2 server)
2 followers

This extension allow the developper to use Oauth2 server in Yii2 apps

Requirements

  • Yii 2.0+
  • Redis

Other backends are not yet implemented

Installation

If you use Packagist for installing packages, then you can update your composer.json like this :

{
    "require": {
        "sweelix/yii2-oauth2-server": "~1.0"
    }
}

Howto use it

Add extension to your configuration

return [
    //....
    'bootstrap' => [
        //....
        'oauth2',
        //....
    ],
    'modules' => [
        //....
        'oauth2' => [
            'class' => 'sweelix\oauth2\server\Module',
            'backend' => 'redis',
            'db' => 'redis',
            'identityClass' => 'app\models\User', // only if you don't want to use the user identityClass
            //
            // Parameters
            //
        ],
        //....
    ],
    //....
];

Configure Module

Basic module parameters

  • backend : can only be redis for the moment
  • db : id of the redis component or connection or connection configuration
  • identityClass : user class used to link oauth2 authorization system default to user component identityClass
  • baseEndPoint : base path for token and authorize endpoints default to ''
    • Token endpoint https://host.xxx/token
    • Authorize endpoint https://host.xxx/authorize
  • overrideLayout : override module layout to use another one (ex: @app/views/layouts/oauth2)
  • overrideViewPath : override view path to use specific one (ex: @app/views/oauth2)

Grants management

  • allowImplicit : allow implicit grant (default to false)
  • allowAuthorizationCode : allow authorization code grant (default to true)
  • allowClientCredentials : allow client credentials grant (default to true)
  • allowPassword : allow user credentials / password grant (default to true)
  • allowCredentialsInRequestBody : allow credentials in request body (default to true)
  • allowPublicClients : allow public clients (default to true)
  • alwaysIssueNewRefreshToken : always issue refresh token (default to true)
  • unsetRefreshTokenAfterUse : unset refresh token after use (default to true)

JWT parameters

  • allowJwtAccesToken : enable JWT (default : false)
  • allowAlgorithm : available algorithm for JWT (default : ['RS256', 'RS384', 'RS512'])
  • jwtAudience : default to token endpoint
  • storeEncryptedTokenString : store encrypted token (default : true)

Time To Live

  • idTTL : TTL of ID Token (default to 3600)
  • accessTokenTTL : TTL of access token (default to 3600)
  • refreshTokenTTL : TTL of refresh token (default to 14 * 24 * 3600)

Basic Oauth names

  • realm : Realm value (default to Service)
  • tokenQueryName : name of the access token parameter (default to access_token)
  • tokenBearerName : name of authorization header (default to Bearer)

Enforce parameters

  • enforceState : enforce state parameter (default to true)
  • allowOnlyRedirectUri : need exact redirect URI (default to true)

OpenID

  • allowOpenIdConnect : enable openId connect (default : false) // not implemented yet

User identity and Web user

Configure the user component to link oauth2 system and user / identity management

return [
    //....
    'components' => [
        //....
        'user' => [
            'class' => 'sweelix\oauth2\server\web\User',
            'identityClass' => 'app\models\User', // Identity class must implement UserModelInterface
            //
            // Parameters
            //
        ],
        //....
    ],
    //....
];

IdentityClass must implements sweelix\oauth2\server\interfaces\UserModelInterface. You can use the trait sweelix\oauth2\server\traits\IdentityTrait to automagically implement

  • public function getRestrictedScopes()
  • public function setRestrictedScopes($scopes)
  • public static function findIdentityByAccessToken($token, $type = null)

you will have to implement the remaining methods :

  • public static function findByUsernameAndPassword($username, $password)
  • public static function findByUsername($username)

Creating specific view for OAuth2

In order to use your own views (instead of the builtin ones), you can override * layout : module parameter overrideLayout * viewPath : module parameter overrideViewPath

Overriding layout

You should create a classic layout like :

<?php
/**
 * @app/views/layouts/newLayout.php
 * @var string $content
 */
use yii\helpers\Html;
 
$this->beginPage(); ?>
    <!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title><?php echo Html::encode($this->title); ?></title>
 
        <meta name="viewport" content="width=device-width, initial-scale=1">
 
        <?php $this->head(); ?>
    </head>
    <body>
        <?php $this->beginBody(); ?>
            <?php echo $content;?>
        <?php $this->endBody(); ?>
    </body>
 
</html>
<?php $this->endPage();

and link it to the module

return [
    //....
    'modules' => [
        //....
        'oauth2' => [
            'class' => 'sweelix\oauth2\server\Module',
            'overrideLayout' => '@app/views/layouts/newLayout',
            //
            // Additional Parameters
            //
        ],
        //....
    ],
    //....
];

Overriding views

You should create 3 views to allow oauth2 module to work as expected and link them to the module

return [
    //....
    'modules' => [
        //....
        'oauth2' => [
            'class' => 'sweelix\oauth2\server\Module',
            // use views in folder oauth2
            'overrideViewPath' => '@app/views/oauth2',
            //
            // Additional Parameters
            //
        ],
        //....
    ],
    //....
];

Error view

This view is used to display a page when an error occurs

<?php
/**
 * error.php
 *
 * @var string $type error type
 * @var string $description error description
 */
use yii\helpers\Html;
?>
 
    <h1 class="alert-heading"><?php echo ($type ? : 'Unkown error'); ?></h1>
    <p><?php echo ($description ? : 'Please check your request'); ?></p>

Login view

This view is used to display a login page when needed

<?php
/**
 * login.php
 *
 * @var \sweelix\oauth2\server\forms\User $user
 *
 */
use yii\helpers\Html;
?>
    <?php echo Html::beginForm('', 'post', ['novalidate' => 'novalidate']); ?>
        <label>Username</label>
        <?php echo Html::activeTextInput($user, 'username', [
            'required' => 'required',
        ]); ?>
        <br/>
 
        <label>Password</label>
        <?php echo Html::activePasswordInput($user, 'password', [
            'required' => 'required',
        ]); ?>
        <br/>
        <button type="submit">LOGIN</button>
    <?php echo Html::endForm(); ?>

Authorize view

This view is used to display an authorization page when needed

<?php
/**
 * authorize.php
 *
 * @var \sweelix\oauth2\server\interfaces\ScopeModelInterface[] $requestedScopes
 * @var \sweelix\oauth2\server\interfaces\ClientModelInterface $client
 *
 */
use yii\helpers\Html;
?>
    <h1><?php echo $client->name ?> <span>requests access</span></h1>
 
    <?php echo Html::beginForm(); ?>
        <?php if(empty($requestedScopes) === false) : ?>
        <ul>
            <?php foreach($requestedScopes as $scope): ?>
            <li>
                <h4><?php echo $scope->id; ?></h4>
                <p>
                    <?php echo $scope->definition; ?>
                </p>
            </li>
            <?php endforeach; ?>
        </ul>
        <?php endif; ?>
            <!-- name of decline button **must be** decline -->
            <button type="submit" name="decline">DECLINE</button>
            <!-- name of accept button **must be** accept -->
            <button type="submit" name="accept">AUTHORIZE</button>
    <?php echo Html::endForm(); ?>

Linking RBAC and Scope systems

Using sweelix\oauth2\server\web\User class will automagically link rbac system and oauth2 system.

Permission system will be slightly modified to allow fine grained checks :

  • Yii::$app->user->can('read') will check

    1. if scope read is allowed for current client
    2. if rbac permission read is allowed for current user
  • Yii::$app->user->can('rbac:read') will check only if rbac permission read is allowed for current user

  • Yii::$app->user->can('oauth2:read') will check only if scope read is allowed for current client

CLI System

Several commands are available to manage oauth2 system

  • php protected/yii.php oauth2:client/create
  • php protected/yii.php oauth2:client/update
  • php protected/yii.php oauth2:key/create
  • php protected/yii.php oauth2:scope/create

Running the tests

Before running the tests, you should edit the file tests/config/redis.php and change the config to match your environment.

Resources

Be the first person to leave a comment

Please to leave your comment.

Create extension
Downloads
No downloadable files yet