Skip to content
This repository was archived by the owner on Nov 9, 2018. It is now read-only.

client_credential_grant #63

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
49 changes: 35 additions & 14 deletions Controller/Component/OAuthComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
App::import('Vendor', 'oauth2-php/lib/IOAuth2Storage');
App::import('Vendor', 'oauth2-php/lib/IOAuth2RefreshTokens');
App::import('Vendor', 'oauth2-php/lib/IOAuth2GrantUser');
App::import('Vendor', 'oauth2-php/lib/IOAuth2GrantClient');
App::import('Vendor', 'oauth2-php/lib/IOAuth2GrantCode');

class OAuthComponent extends Component implements IOAuth2Storage, IOAuth2RefreshTokens, IOAuth2GrantUser, IOAuth2GrantCode {
class OAuthComponent extends Component implements IOAuth2Storage, IOAuth2RefreshTokens, IOAuth2GrantUser, IOAuth2GrantClient, IOAuth2GrantCode {

/**
* AccessToken object.
Expand Down Expand Up @@ -104,7 +105,7 @@ class OAuthComponent extends Component implements IOAuth2Storage, IOAuth2Refresh
*
* @var array
*/
public $grantTypes = array('authorization_code', 'refresh_token', 'password');
public $grantTypes = array('authorization_code', 'refresh_token', 'password', 'client_credentials');

/**
* OAuth2 Object
Expand Down Expand Up @@ -423,7 +424,7 @@ public function checkClientCredentials($client_id, $client_secret = null) {
public function getClientDetails($client_id) {
$client = $this->Client->find('first', array(
'conditions' => array('client_id' => $client_id),
'fields' => array('client_id', 'redirect_uri'),
'fields' => array('client_id', 'redirect_uri', 'user_id'),
'recursive' => -1
));
if ($client) {
Expand All @@ -432,6 +433,21 @@ public function getClientDetails($client_id) {
return false;
}

public function getUserId(){
$accessToken = $this->getAccessToken($this->getBearerToken());
$client = $this->getClientDetails($accessToken['client_id']);
return $client['user_id'];
}

public function debugToken() {
$accessToken = $this->getAccessToken($this->getBearerToken());
$client = $this->getClientDetails($accessToken['client_id']);
return [
'sub' => $client['user_id'],
'aud' => $$accessToken['client_id'], //TODO change to aud value
];
}

/**
* Retrieve access token
*
Expand Down Expand Up @@ -552,20 +568,25 @@ public function unsetRefreshToken($refresh_token) {
* @param type $username
* @param type $password
*/
public function checkUserCredentials($client_id, $username, $password) {
$user = $this->User->find('first', array(
'conditions' => array(
$this->authenticate['fields']['username'] => $username,
$this->authenticate['fields']['password'] => AuthComponent::password($password)
),
'recursive' => -1
public function checkUserCredentials($client_id, $username, $password) {
$result = $this->User->find('first', array(
'conditions' => array(
$this->authenticate['fields']['username'] => $username,
),
'recursive' => -1
));
if ($user) {
return array('user_id' => $user['User'][$this->User->primaryKey]);

$user = $result['User'];
if (!$user || !BlowfishPasswordHasher::check($password, $user[$this->authenticate['fields']['password']])) {
return false;
}
return false;
return array('user_id' => $user[$this->User->primaryKey]);
}


public function checkClientCredentialsGrant($client_id, $client_secret) {
return [];
}

/**
* Grant type: authorization_code
*
Expand Down
21 changes: 18 additions & 3 deletions Controller/OAuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
class OAuthController extends OAuthAppController {

public $components = array('OAuth.OAuth', 'Auth', 'Session', 'Security');
public $components = array('OAuth.OAuth', 'Auth', 'Session', 'Security'); // if 'Auth' is loaded from app/AppController, reject 'Auth' fron here.

public $uses = array('Users');

Expand All @@ -32,6 +32,8 @@ class OAuthController extends OAuthAppController {
*/
public function beforeFilter() {
parent::beforeFilter();

// for Resource Owner Password Credentials Grant
$this->OAuth->authenticate = array('fields' => array('username' => 'email'));
$this->Auth->allow($this->OAuth->allowedActions);
$this->Security->blackHoleCallback = 'blackHole';
Expand Down Expand Up @@ -121,7 +123,7 @@ public function login () {
* Example Token Endpoint - this is where clients can retrieve an access token
*
* Grant types and parameters:
* 1) authorization_code - exchange code for token
* 1) authorization_code - exchange code for token : use when resource_owner != client
* - code
* - client_id
* - client_secret
Expand All @@ -131,12 +133,16 @@ public function login () {
* - client_id
* - client_secret
*
* 3) password - exchange raw details for token
* 3) password - exchange raw details for token : this is dangerous (when client is bad) -> use client_credentials
* - username
* - password
* - client_id
* - client_secret
*
* 4) client_credentials (connect resource_owner-client at adding client timing) : use when requested from batch && resource_owner == client
* - client_id
* - client_secret
*
*/
public function token() {
$this->autoRender = false;
Expand All @@ -147,6 +153,15 @@ public function token() {
}
}

public function debug_token() {
$this->autoRender = false;
try {
return $this->OAuth->debugToken();
} catch (OAuth2ServerException $e) {
$e->sendHttpResponse();
}
}

/**
* Quick and dirty example implementation for protecetd resource
*
Expand Down
10 changes: 5 additions & 5 deletions Model/AccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ class AccessToken extends OAuthAppModel {
'rule' => array('notempty'),
),
),
'user_id' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
// 'user_id' => array(
// 'notempty' => array(
// 'rule' => array('notempty'),
// ),
// ),
'expires' => array(
'numeric' => array(
'rule' => array('numeric'),
Expand Down
9 changes: 7 additions & 2 deletions Model/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,19 @@ class Client extends OAuthAppModel {
* AddClient
*
* Convinience function for adding client, will create a uuid client_id and random secret
*
* if client credentials grant, connect client-resource_owner at adding client timing.
*
* @param mixed $data Either an array (e.g. $controller->request->data) or string redirect_uri
* @return booleen Success of failure
*/
public function add($data = null) {
$this->data['Client'] = array();

if (is_array($data) && is_array($data['Client']) && array_key_exists('redirect_uri', $data['Client'])) {
if (is_array($data) && is_array($data['Client']) && array_key_exists('redirect_uri', $data['Client']) && array_key_exists('user_id', $data['Client'])) {
$this->data['Client']['redirect_uri'] = $data['Client']['redirect_uri'];
$this->data['Client']['user_id'] = $data['Client']['user_id']; // for client credentials
} elseif (is_array($data) && is_array($data['Client']) && array_key_exists('redirect_uri', $data['Client'])) {
$this->data['Client']['redirect_uri'] = $data['Client']['redirect_uri'];
} elseif (is_string($data)) {
$this->data['Client']['redirect_uri'] = $data;
Expand Down Expand Up @@ -171,4 +176,4 @@ public function afterSave($created, $options = array()) {
return true;
}

}
}
61 changes: 57 additions & 4 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ $ git submodule add git://github.com/thomseddon/cakephp-oauth-server.git Plugin/
### Loading the Plugin
Load the plugin

```PHP
CakePlugin::loadAll(); // Loads all plugins at once
CakePlugin::load('OAuth'); //Just load OAuth
app/Config/bootstrap.php
```
CakePlugin::loadAll(array(
'OAuth' => array('routes' => true)
));
```

### Include component in controller
Expand Down Expand Up @@ -112,7 +114,8 @@ This plugin ships with all required models, including the "Clients" model for ad
You may wish to handle adding clients yourself, see the tables.sql for the schema, or you can use the convenience method included in the model, like so:

```PHP
$client = $this->OAuth->Client->add('http://www.return_url.com')
$userId = 'aaa';
$client = $this->OAuth->Client->add('http://www.return_url.com', $userId)
```
Which will generate then client_id and client_secret and return something like:

Expand Down Expand Up @@ -155,3 +158,53 @@ There is quite a bit of documentation through the code, so dive in, get your han

[1]: https://github.com/quizlet/oauth2-php
[2]: https://github.com/CakeDC/migrations


***
add 'OAuth.OAuth' into app/XxxController's load components

```
public $components = [
'OAuth.OAuth',
];
```

add this function in ApiController (required: Restrict it so that it can be used only for system_user)
```
public function publish_client()
{
if(!isset($this->request->query['redirect_url'])){
$this->_errorLog(__METHOD__, __LINE__, $this->request->query, 'parameter error');
$this->response->statusCode(200);
$this->response->body(json_encode([
'result' => $this->RESULT_400,
'message' => $this->RESULT_400_MSG,
]));
$this->response->send();
$this->_stop();
return;
}
return $this->_rtnJson($this->RESULT_200, $this->OAuth->Client->add($this->request->query['redirect_url']), '');
}


public function delete_access_token(){
try{
$data = $this->request->query;
//必須パラメータチェック
if (!$this->_paramKeyExistsChk($data, ['prime_contractor_id'])) {
$this->_errorLog(__METHOD__, __LINE__, $data, 'Not Parameter error.');
return $this->_rtnJson(false, [], 0, $this->RESULT_400, self::RESULT_400_MSG);
}
return $this->OAuth->invalidateUserTokens($data['prime_contractor_id']) ? $this->_rtnJson(true, 'token was deleted!', 0): $this->_rtnJson(true, 'delete token error', 0, $this->RESULT_500, self::RESULT_500_MSG);
}catch(Exception $e){
$this->_errorLog(__METHOD__, __LINE__, $data, $e->getMessage());
return $this->_rtnJson(false, [], 0, $this->RESULT_500, self::RESULT_500_MSG);
}
}

private function fetchUserId(){
return $this->OAuth->getUserId();
}
```

4 changes: 2 additions & 2 deletions View/OAuth/login.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
Please login

<?php
echo $this->Form->input('email');
echo $this->Form->input('password');
echo $this->Form->input('email'); // if Users.login_id is Auth data, change to 'login_id'
echo $this->Form->input('password'); // if Users.login_pw is Auth data, change to 'login_pw' (hased in database)

echo $this->Form->end('submit');

Expand Down