Skip to content

Commit

Permalink
Merge pull request #757 from rochamarcelo/feature/u2f
Browse files Browse the repository at this point in the history
Feature/u2f
  • Loading branch information
rochamarcelo authored Feb 11, 2019
2 parents 9e94ca3 + 082bf50 commit 0b52456
Show file tree
Hide file tree
Showing 25 changed files with 2,424 additions and 214 deletions.
4 changes: 2 additions & 2 deletions .semver
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
:major: 8
:minor: 0
:patch: 3
:minor: 1
:patch: 0
:special: ''
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ Changelog

Releases for CakePHP 3
-------------
* 8.1
* Added Yubico U2F Authentication

* 8.0.3
* Updated to latest version of Google OAuth
* Added plugin object
Expand Down
29 changes: 29 additions & 0 deletions Docs/Documentation/Yubico-U2F.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
YubicoKey U2F
=============

Installation
------------
To enable this feature you need to

```
composer require yubico/u2flib-server:^1.0
```

Setup
-----

Enable it in your bootstrap.php file:

Config/bootstrap.php
```
Configure::write('U2f.enabled', true);
```

How does it work
----------------
When the user log-in, he is requested to insert and tap his registered yubico key,
if this is the first time he access he need to register the yubico key.

Please check the yubico site for more information about U2F
https://developers.yubico.com/U2F/

1 change: 1 addition & 0 deletions Docs/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Documentation
* [ApiKeyAuthenticate](https://github.com/CakeDC/auth/blob/master/Docs/Documentation/ApiKeyAuthenticate.md)
* [SocialAuthenticate](Documentation/SocialAuthenticate.md)
* [Google Authenticator](Documentation/Google-Two-Factor-Authenticator.md)
* [Yubico U2F](Documentation/Yubico-U2F.md)
* [UserHelper](Documentation/UserHelper.md)
* [Events](Documentation/Events.md)
* [Extending the Plugin](Documentation/Extending-the-Plugin.md)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ It covers the following features:
* Remember me (Cookie) via https://github.com/CakeDC/auth
* Manage user's profile
* Admin management
* Yubico U2F for Two-Factor Authentication
* One-Time Password for Two-Factor Authentication

The plugin is here to provide users related features following 2 approaches:
* Quick drop-in working solution for users login/registration. Get users working in 5 minutes.
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"league/oauth2-linkedin": "@stable",
"luchianenco/oauth2-amazon": "^1.1",
"google/recaptcha": "@stable",
"robthree/twofactorauth": "~1.6.0"
"robthree/twofactorauth": "~1.6.0",
"yubico/u2flib-server": "^1.0"
},
"suggest": {
"league/oauth1-client": "Provides Social Authentication with Twitter",
Expand Down
32 changes: 32 additions & 0 deletions config/Migrations/20190208174112_AddAdditionalDataToUsers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Copyright 2010 - 2019, Cake Development Corporation (https://www.cakedc.com)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2010 - 2019, Cake Development Corporation (https://www.cakedc.com)
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/

use Migrations\AbstractMigration;

class AddAdditionalDataToUsers extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('users');
$table->addColumn('additional_data', 'text', [
'default' => null,
'null' => true,
]);
$table->update();
}
}
10 changes: 10 additions & 0 deletions config/users.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@
'prefix' => false,
],
],
'U2f' => [
'enabled' => false,
'checker' => \CakeDC\Users\Auth\DefaultU2fAuthenticationChecker::class,
'startAction' => [
'plugin' => 'CakeDC/Users',
'controller' => 'Users',
'action' => 'u2f',
'prefix' => false,
]
],
// default configuration used to auto-load the Auth Component, override to change the way Auth works
'Auth' => [
'loginAction' => [
Expand Down
43 changes: 43 additions & 0 deletions src/Auth/DefaultU2fAuthenticationChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Copyright 2010 - 2019, Cake Development Corporation (https://www.cakedc.com)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2010 - 2018, Cake Development Corporation (https://www.cakedc.com)
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace CakeDC\Users\Auth;

use Cake\Core\Configure;

/**
* Default class to check if two factor authentication is enabled and required
*
* @package CakeDC\Users\Auth
*/
class DefaultU2fAuthenticationChecker implements U2fAuthenticationCheckerInterface
{
/**
* Check if two factor authentication is enabled
*
* @return bool
*/
public function isEnabled()
{
return Configure::read('U2f.enabled') !== false;
}

/**
* Check if two factor authentication is required for a user
*
* @param array $user user data
*
* @return bool
*/
public function isRequired(array $user = null)
{
return !empty($user) && $this->isEnabled();
}
}
39 changes: 39 additions & 0 deletions src/Auth/U2fAuthenticationCheckerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Copyright 2010 - 2019, Cake Development Corporation (https://www.cakedc.com)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2010 - 2018, Cake Development Corporation (https://www.cakedc.com)
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace CakeDC\Users\Auth;

use Cake\Core\Configure;
use Cake\Network\Exception\BadRequestException;

/**
* Factory for two authentication checker
*
* @package CakeDC\Users\Auth
*/
class U2fAuthenticationCheckerFactory
{
/**
* Get the two factor authentication checker
*
* @return U2fAuthenticationCheckerInterface
*/
public function build()
{
$className = Configure::read('U2f.checker');
$interfaces = class_implements($className);
$required = U2fAuthenticationCheckerInterface::class;

if (in_array($required, $interfaces)) {
return new $className();
}
throw new \InvalidArgumentException("Invalid config for 'U2f.checker', '$className' does not implement '$required'");
}
}
30 changes: 30 additions & 0 deletions src/Auth/U2fAuthenticationCheckerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
/**
* Copyright 2010 - 2019, Cake Development Corporation (https://www.cakedc.com)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2010 - 2018, Cake Development Corporation (https://www.cakedc.com)
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace CakeDC\Users\Auth;

interface U2fAuthenticationCheckerInterface
{
/**
* Check if two factor authentication is enabled
*
* @return bool
*/
public function isEnabled();

/**
* Check if two factor authentication is required for a user
*
* @param array $user user data
*
* @return bool
*/
public function isRequired(array $user = null);
}
6 changes: 6 additions & 0 deletions src/Controller/Component/UsersAuthComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ protected function _initAuth()
// Social
'endpoint',
'authenticated',

'u2f',
'u2fRegister',
'u2fRegisterFinish',
'u2fAuthenticate',
'u2fAuthenticateFinish',
]);
}
}
Expand Down
18 changes: 16 additions & 2 deletions src/Controller/Traits/LoginTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace CakeDC\Users\Controller\Traits;

use CakeDC\Users\Auth\TwoFactorAuthenticationCheckerFactory;
use CakeDC\Users\Auth\U2fAuthenticationCheckerFactory;
use CakeDC\Users\Controller\Component\UsersAuthComponent;
use CakeDC\Users\Exception\AccountNotActiveException;
use CakeDC\Users\Exception\MissingEmailException;
Expand Down Expand Up @@ -184,7 +185,8 @@ public function login()
return $this->_afterIdentifyUser(
$user,
$socialLogin,
$user && $this->getTwoFactorAuthenticationChecker()->isRequired($user)
$user && $this->getTwoFactorAuthenticationChecker()->isRequired($user),
$user && $this->getU2fAuthenticationChecker()->isRequired($user)
);
}

Expand Down Expand Up @@ -330,11 +332,23 @@ protected function _checkReCaptcha()
* @param array $user user data after identified
* @param bool $socialLogin is social login
* @param bool $googleAuthenticatorLogin googleAuthenticatorLogin
* @param bool $u2fLogin should perform u2f authentication
* @return array
*/
protected function _afterIdentifyUser($user, $socialLogin = false, $googleAuthenticatorLogin = false)
protected function _afterIdentifyUser($user, $socialLogin = false, $googleAuthenticatorLogin = false, $u2fLogin = false)
{
if (!empty($user)) {
if ($u2fLogin) {
// storing user's session in the temporary one
$this->request->getSession()->write('U2f.User', $user);
$url = Configure::read('U2f.startAction');
$url = array_merge($url, [
'?' => $this->request->getQueryParams()
]);

return $this->redirect($url);
}

if ($googleAuthenticatorLogin) {
// storing user's session in the temporary one
// until the GA verification is checked
Expand Down
Loading

0 comments on commit 0b52456

Please sign in to comment.