diff --git a/Controller/Component/OAuthComponent.php b/Controller/Component/OAuthComponent.php index df1fd6e..23f2c94 100644 --- a/Controller/Component/OAuthComponent.php +++ b/Controller/Component/OAuthComponent.php @@ -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. @@ -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 @@ -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) { @@ -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 * @@ -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 * diff --git a/Controller/OAuthController.php b/Controller/OAuthController.php index 5ea5558..beabaa8 100644 --- a/Controller/OAuthController.php +++ b/Controller/OAuthController.php @@ -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'); @@ -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'; @@ -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 @@ -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; @@ -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 * diff --git a/Model/AccessToken.php b/Model/AccessToken.php index 9a313f5..0c7a34b 100644 --- a/Model/AccessToken.php +++ b/Model/AccessToken.php @@ -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'), diff --git a/Model/Client.php b/Model/Client.php index 89b7d28..1ed18f7 100644 --- a/Model/Client.php +++ b/Model/Client.php @@ -113,6 +113,8 @@ 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 @@ -120,7 +122,10 @@ class Client extends OAuthAppModel { 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; @@ -171,4 +176,4 @@ public function afterSave($created, $options = array()) { return true; } -} \ No newline at end of file +} diff --git a/README.markdown b/README.markdown index 335b44c..7e38c03 100644 --- a/README.markdown +++ b/README.markdown @@ -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 @@ -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: @@ -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(); + } +``` + diff --git a/View/OAuth/login.ctp b/View/OAuth/login.ctp index 6d6832a..95eedc3 100644 --- a/View/OAuth/login.ctp +++ b/View/OAuth/login.ctp @@ -13,8 +13,8 @@ Please login 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');