Giter Site home page Giter Site logo

yii2-oauth2's Introduction

Oauth2 Yii2 integration

This extension allow the developper to use Oauth2 server.

Latest Stable Version Build Status Scrutinizer Code Quality Code Coverage License

Latest Development Version Build Status Scrutinizer Code Quality Code Coverage composer.lock

Installation

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

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

How to use it

Add extension to your configuration :

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

You also need to enable PrettyUrl:

'components' => [
    //....
    'urlManager' => [
        'enablePrettyUrl' => true,
        'rules' => [
            // your rules go here
        ],
        // ....
    ]
    // ....
]

Migrations (MySql only)

All the migrations needed can be found inside src/migrations. Be sure to configure the database connection before applying them.

Grant types

You can find examples and explanations about every grant types here and here.

For the Jwt Bearer Grant, you will need to create a Jwt entry in your database for the given client and subject.

Configure Module

Basic module parameters

  • backend : can be redis or mysql
  • db : id of the component or connection or connection configuration
  • identityClass : user class used to link oauth2 authorization system default to user component identityClass
  • webUserParamId : allow separation between main app user (session) and module app user, (default to __oauth2)
  • identityCookieName : allow separation between main app user (cookie) and module app user, (default to oauth2)
  • webUser : allow full management of module web user, (default to [])
  • baseEndPoint : base path for token and authorize endpoints default to ''
  • 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 (:warning: Not sure about the implementation. Use at your own risk !)

  • useJwtAccessToken : send access tokens as 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

Authorization Code parameters

  • enforceRedirect : enforce redirect parameter (default to false)
  • authorizationCodeTTL : TTL of authorization code (default to 30)

CORS

  • cors : enable CORS on the token endpoint (default : false) the CORS part can be defined using an array as described in Yii documentation
 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
             //
             // Cors parameters example :
             //
             'cors' => [
                'Origin' => ['https://www.myowndomain.com'],
             ]
         ],
         //....
     ],
     //....
 ];

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(); ?>

Exposed Models overview

The Oauth2 Yii2 extension expose severall models which can be used in your application. All models can be overloaded using Yii2 DI.

For example, if you want to overload the Client model, you have to inject your own model in the DI using:

Yii::$container->set('sweelix\oauth2\server\interfaces\ClientModelInterface', [
    'class' => YourClientModel::className(),
]);

Client / ClientModelInterface

  • Client::findOne($id) - Find client by ID
  • Client::findAllByUserId($id) - Find all clients accepted by user (userId)
  • Client::findAll() - Find all existing clients
  • $client->save() - Save client
  • $client->delete() - Delete client
  • $client->hasUser($userId) - Check if user (userId) has accepted the client
  • $client->addUser($userId) - Attach the user (userId) to the client
  • $client->removeUser($userId) - Dettach the user (userId) from the client

AccessToken / AccessTokenModelInterface

  • AccessToken::findOne($id) - Find accessToken by ID
  • AccessToken::findAllByUserId($id) - Find all accessTokens for user (userId)
  • AccessToken::findAllByClientId($id) - Find all accessTokens for client (clientId)
  • AccessToken::deleteAllByUserId($id) - Delete all accessTokens for user (userId)
  • AccessToken::deleteAllByClientId($id) - Delete all accessTokens for client (clientId)
  • AccessToken::findAll() - Find all existing accessTokens
  • AccessToken::deleteAllExpired() - Delete all expired accessTokens
  • $accessToken->save() - Save accessToken
  • $accessToken->delete() - Delete accessToken

RefreshToken / RefreshTokenModelInterface

  • RefreshToken::findOne($id) - Find accessToken by ID
  • RefreshToken::findAllByUserId($id) - Find all refreshTokens for user (userId)
  • RefreshToken::findAllByClientId($id) - Find all refreshTokens for client (clientId)
  • RefreshToken::deleteAllByUserId($id) - Delete all refreshTokens for user (userId)
  • RefreshToken::deleteAllByClientId($id) - Delete all refreshTokens for client (clientId)
  • RefreshToken::findAll() - Find all existing refreshTokens
  • RefreshToken::deleteAllExpired() - Delete all expired refreshTokens
  • $refreshToken->save() - Save refreshToken
  • $refreshToken->delete() - Delete refreshToken

AuthCode / AuthCodeModelInterface

  • AuthCode::findOne($id) - Find authCode by ID
  • $authCode->save() - Save authCode
  • $authCode->delete() - Delete authCode

Scope / ScopeModelInterface

  • Scope::findOne($id) - Find scope by ID
  • Scope::findAvailableScopeIds() - Find all scopes IDs
  • Scope::findDefaultScopeIds() - Find default scopes IDs
  • $scope->save() - Save scope
  • $scope->delete() - Delete scope

CypherKey / CypherKeyModelInterface

  • CypherKey::findOne($id) - Find cypherKey by ID
  • $cypherKey->save() - Save cypherKey
  • $cypherKey->delete() - Delete cypherKey
  • $cypherKey->generateKeys() - Generate random keys for current cypherKey

Jti / JtiModelInterface (:warning: Not sure about the implementation. Use at your own risk !)

  • Jti::findOne($id) - Find jti by ID
  • Jti::findAllBySubject($id) - Find all jtis for user (userId)
  • Jti::findAllByClientId($id) - Find all jtis for client (clientId)
  • Jti::deleteAllBySubject($id) - Delete all jtis for user (userId)
  • Jti::deleteAllByClientId($id) - Delete all jtis for client (clientId)
  • Jti::findAll() - Find all existing jtis
  • Jti::deleteAllExpired() - Delete all expired jtis
  • Jti::getFingerprint($clientId, $subject, $audience, $expires, $jti) - Get a jti fingerprint for given params
  • $jti->save() - Save jti
  • $jti->delete() - Delete jti

Jwt / JwtModelInterface (:warning: Not sure about the implementation. Use at your own risk !)

  • Jwt::findOne($id) - Find jwt by ID
  • Jwt::getFingerprint($clientId, $subject) - Get jwt fingerprint for given clientId and subject
  • $jwt->save() - Save jwt
  • $jwt->delete() - Delete jwt

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

Running the tests

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

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:client/delete
  • php protected/yii.php oauth2:jwt/create
  • php protected/yii.php oauth2:jwt/update
  • php protected/yii.php oauth2:jwt/delete
  • php protected/yii.php oauth2:key/create
  • php protected/yii.php oauth2:key/update
  • php protected/yii.php oauth2:key/delete
  • php protected/yii.php oauth2:scope/create
  • php protected/yii.php oauth2:scope/update
  • php protected/yii.php oauth2:scope/delete
  • php protected/yii.php oauth2:cronjob/remove-expired - Run this one with your cron manager
  • php protected/yii.php oauth2:migrate-redis/migrate - Migration command for redis

yii2-oauth2's People

Contributors

asamats avatar dixonsatit avatar pgaultier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yii2-oauth2's Issues

Mysql version

Hi pgaultier,

I am looking for a mysql version of the same is it in development?

Regards,
Wenceslaus Dsilva

can't access token by query parameter(yii\filters\auth\QueryParamAuth)

Hi, i can't access query parameter. you can remove this line for support query parameter.

https://github.com/pgaultier/yii2-oauth2/blob/devel/src/traits/IdentityTrait.php#L68
eg.
http://app-sso.dev/api/v1/user/info?access-token=fbc0a36d1aa50c5ef32c0a7a86700e3cf7b2c1ba

this config

'authenticator' => [
                'class' => CompositeAuth::className(),
                'authMethods' => [
                    ['class' => HttpBearerAuth::className()],
                    ['class' => QueryParamAuth::className()],
                ]
            ],

Thank you.

When click on authorize button then error "Authorization code doesn't exist or is invalid for the client"

create client user

./yii oauth2:client/create --name=doh --userId=1 --redirectUri=http://app-frontend.dev:9090/site/auth?authclient=doh

create auth client

<?php

namespace frontend\components;

use yii\authclient\OAuth2;
use dektrium\user\clients\ClientInterface;

class DohClient extends OAuth2
{
    public $authUrl = 'https://sso.sathit.me/oauth2/authorize';

    public $tokenUrl = 'https://sso.sathit.me/oauth2/token';

    public $apiBaseUrl = 'https://sso.sathit.me/api/v1';

    protected function defaultName()
    {
        return 'doh';
    }

    protected function defaultTitle()
    {
        return 'DOH';
    }

    protected function defaultViewOptions()
    {
        return [
            'popupWidth' => 800,
            'popupHeight' => 500,
        ];
    }

    protected function initUserAttributes()
    {
        return $this->api('user/info', 'GET');
    }

        /** @inheritdoc */
    public function getEmail()
    {
        return isset($this->getUserAttributes()['email'])
            ? $this->getUserAttributes()['email']
            : null;
    }
    /** @inheritdoc */
    public function getUsername()
    {
        return;
    }
}

Use widget AuthChoice.

        <ul>
            <?php $authAuthChoice = AuthChoice::begin([
            //'baseAuthUrl' => ['/user/security/auth'],
            'baseAuthUrl' => ['/site/auth'],
            'popupMode' => true,
            ]); ?>
                <?php foreach ($authAuthChoice->getClients() as $key => $client): ?>
                    <li><?= $authAuthChoice->clientLink($client,ucfirst($key)) ?></li>
                <?php endforeach; ?>
            <?php AuthChoice::end(); ?>
         </ul>

when login & click authorize button then error?

screen shot 2016-12-14 at 22 47 16

screen shot 2016-12-14 at 21 19 20

Command:

First, redirect the user to the following URL

https://sso.sathit.me/oauth2/authorize/index?response_type=code&client_id=f0124396cad6668186643f55deee9f8a6bfc6169&redirect_uri=http://app-frontend.dev:9090

response authorization code in the URL

http://app-frontend.dev:9090/?code=fc5427d1fac73e967097d21748fd97702376ccf5

requested using the authorization code.

curl -u f0124396cad6668186643f55deee9f8a6bfc6169:43298539b024e5b8c73c60601e7c2b1d06c7aca7  https://sso.sathit.me/oauth2/token -d 'grant_type=authorization_code&code=fc5427d1fac73e967097d21748fd97702376ccf5'

result

{"error":"invalid_grant","error_description":"Authorization code doesn't exist or is invalid for the client"}

How to config a console command?

i want to config a console comnad in oauth2. i try this config. don't work.

return [
    'id' => 'app-console',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'controllerNamespace' => 'console\controllers',
    'modules' => [
        'oauth2' => [
            'class' => 'sweelix\oauth2\server\Module'
        ],
    ]
...
]

or ?

   'controllerMap'       => [
         'client' => 'sweelix\oauth2\server\commands\ClientController',
         'key' => 'sweelix\oauth2\server\commands\KeyController',
         'scope' => 'sweelix\oauth2\server\commands\ScopeController'
     ],

error.

./yii client/create --userId=1
Exception 'yii\di\NotInstantiableException' with message 'Can not instantiate sweelix\oauth2\server\interfaces\ClientModelInterface.'

in /var/www/html/vendor/yiisoft/yii2/di/Container.php:370

Stack trace:
#0 /var/www/html/vendor/yiisoft/yii2/di/Container.php(154): yii\di\Container->build('sweelix\\oauth2\\...', Array, Array)
#1 /var/www/html/vendor/yiisoft/yii2/BaseYii.php(340): yii\di\Container->get('sweelix\\oauth2\\...', Array)
#2 /var/www/html/vendor/sweelix/yii2-oauth2-server/src/commands/ClientController.php(66): yii\BaseYii::createObject('sweelix\\oauth2\\...')
#3 [internal function]: sweelix\oauth2\server\commands\ClientController->actionCreate()
#4 /var/www/html/vendor/yiisoft/yii2/base/InlineAction.php(55): call_user_func_array(Array, Array)
#5 /var/www/html/vendor/yiisoft/yii2/base/Controller.php(154): yii\base\InlineAction->runWithParams(Array)
#6 /var/www/html/vendor/yiisoft/yii2/console/Controller.php(128): yii\base\Controller->runAction('create', Array)
#7 /var/www/html/vendor/yiisoft/yii2/base/Module.php(454): yii\console\Controller->runAction('create', Array)
#8 /var/www/html/vendor/yiisoft/yii2/console/Application.php(180): yii\base\Module->runAction('client/create', Array)
#9 /var/www/html/vendor/yiisoft/yii2/console/Application.php(147): yii\console\Application->runAction('client/create', Array)
#10 /var/www/html/vendor/yiisoft/yii2/base/Application.php(375): yii\console\Application->handleRequest(Object(yii\console\Request))
#11 /var/www/html/yii(30): yii\base\Application->run()
#12 {main}

thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.