diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/ajax-broker/api.php | 38 | ||||
-rw-r--r-- | examples/ajax-broker/app.js | 107 | ||||
-rw-r--r-- | examples/ajax-broker/index.html | 56 | ||||
-rw-r--r-- | examples/broker/error.php | 25 | ||||
-rw-r--r-- | examples/broker/index.php | 39 | ||||
-rw-r--r-- | examples/broker/login.php | 56 | ||||
-rw-r--r-- | examples/server/.htaccess | 6 | ||||
-rw-r--r-- | examples/server/MySSOServer.php | 90 | ||||
-rw-r--r-- | examples/server/index.php | 18 |
9 files changed, 435 insertions, 0 deletions
diff --git a/examples/ajax-broker/api.php b/examples/ajax-broker/api.php new file mode 100644 index 0000000..996b813 --- /dev/null +++ b/examples/ajax-broker/api.php @@ -0,0 +1,38 @@ +<?php + +require_once __DIR__ . '/../../vendor/autoload.php'; + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); + +if (empty($_REQUEST['command']) || !method_exists($broker, $_REQUEST['command'])) { + header("Content-Type: application/json"); + header("HTTP/1.1 400 Bad Request"); + echo json_encode(['error' => 'Command not specified']); + exit(); +} + +try { + $result = $broker->{$_REQUEST['command']}(); +} catch (Exception $e) { + $status = $e->getCode() ?: 500; + $result = ['error' => $e->getMessage()]; +} + +// JSONP +if (!empty($_GET['callback'])) { + if (!isset($result)) $result = null; + if (!isset($status)) $status = isset($result) ? 200 : 204; + + header('Content-Type: application/javascript'); + echo $_GET['callback'] . '(' . json_encode($result) . ', ' . $status . ')'; + return; +} + +// REST +if (!$result) { + http_response_code(204); +} else { + http_response_code(isset($status) ? $status : 200); + header("Content-Type: application/json"); + echo json_encode($result); +} diff --git a/examples/ajax-broker/app.js b/examples/ajax-broker/app.js new file mode 100644 index 0000000..7a627c9 --- /dev/null +++ b/examples/ajax-broker/app.js @@ -0,0 +1,107 @@ ++function($) { + // Init + attach(); + + /** + * Attach session. + * Will redirect to SSO server. + */ + function attach() { + var req = $.ajax({ + url: 'api.php?command=attach', + crossDomain: true, + dataType: 'jsonp' + }); + + req.done(function(data, code) { + if (code && code >= 400) { // jsonp failure + showError(data.error); + return; + } + + loadUserInfo(); + }); + + req.fail(function(jqxhr) { + showError(jqxhr.responseJSON || jqxhr.textResponse) + }); + } + + /** + * Do an AJAX request to the API + * + * @param command API command + * @param params POST data + * @param callback Callback function + */ + function doApiRequest(command, params, callback) { + var req = $.ajax({ + url: 'api.php?command=' + command, + method: params ? 'POST' : 'GET', + data: params, + dataType: 'json' + }); + + req.done(callback); + + req.fail(function(jqxhr) { + showError(jqxhr.responseJSON || jqxhr.textResponse); + }); + } + + /** + * Display the error message + * + * @param data + */ + function showError(data) { + var message = typeof data === 'object' && data.error ? data.error : 'Unexpected error'; + $('#error').text(message).show(); + } + + /** + * Load and display user info + */ + function loadUserInfo() { + doApiRequest('getUserinfo', null, showUserInfo); + } + + /** + * Display user info + * + * @param info + */ + function showUserInfo(info) { + $('body').removeClass('anonymous authenticated'); + $('#user-info').html(''); + + if (info) { + for (var key in info) { + $('#user-info').append($('<dt>').text(key)); + $('#user-info').append($('<dd>').text(info[key])); + } + } + + $('body').addClass(info ? 'authenticated' : 'anonymous'); + } + + /** + * Submit login form through AJAX + */ + $('#login-form').on('submit', function(e) { + e.preventDefault(); + + $('#error').text('').hide(); + + var data = { + username: this.username.value, + password: this.password.value + }; + + doApiRequest('login', data, showUserInfo); + }); + + $('#logout').on('click', function() { + doApiRequest('logout', {}, function() { showUserInfo(null); }); + }) +}(jQuery); diff --git a/examples/ajax-broker/index.html b/examples/ajax-broker/index.html new file mode 100644 index 0000000..8b8a98b --- /dev/null +++ b/examples/ajax-broker/index.html @@ -0,0 +1,56 @@ +<!doctype html> +<html> + <head> + <title>Single Sign-On Ajax demo</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + + <style> + .state { + display: none; + } + body.anonymous .state.anonymous, + body.authenticated .state.authenticated { + display: initial; + } + </style> + </head> + <body> + <div class="container"> + <h1>Single Sign-On Ajax demo</h1> + + <div id="error" class="alert alert-danger" style="display: none;"></div> + + <form id="login-form" class="form-horizontal state anonymous"> + <div class="form-group"> + <label for="inputUsername" class="col-sm-2 control-label">Username</label> + <div class="col-sm-10"> + <input type="text" name="username" class="form-control" id="inputUsername"> + </div> + </div> + <div class="form-group"> + <label for="inputPassword" class="col-sm-2 control-label">Password</label> + <div class="col-sm-10"> + <input type="password" name="password" class="form-control" id="inputPassword"> + </div> + </div> + + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10"> + <button type="submit" class="btn btn-default">Login</button> + </div> + </div> + </form> + + <div class="state authenticated"> + <h3>Logged in</h3> + <dl id="user-info" class="dl-horizontal"></dl> + + <a id="logout" class="btn btn-default">Logout</a> + </div> + </div> + + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> + <script src="app.js"></script> + </body> +</html> + diff --git a/examples/broker/error.php b/examples/broker/error.php new file mode 100644 index 0000000..52c7a53 --- /dev/null +++ b/examples/broker/error.php @@ -0,0 +1,25 @@ +<?php +require_once __DIR__ . '/../../vendor/autoload.php'; + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); +$error = $_GET['sso_error']; + +?> +<!doctype html> +<html> + <head> + <title>Single Sign-On demo (<?= $broker->broker ?>)</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + </head> + <body> + <div class="container"> + <h1>Single Sign-On demo <small>(<?= $broker->broker ?>)</small></h1> + + <div class="alert alert-danger"> + <?= $error ?> + </div> + + <a href="/">Try again</a> + </div> + </body> +</html> diff --git a/examples/broker/index.php b/examples/broker/index.php new file mode 100644 index 0000000..2a5f12d --- /dev/null +++ b/examples/broker/index.php @@ -0,0 +1,39 @@ +<?php +require_once __DIR__ . '/../../vendor/autoload.php'; + +if (isset($_GET['sso_error'])) { + header("Location: error.php?sso_error=" . $_GET['sso_error'], true, 307); + exit; +} + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); +$broker->attach(true); + +$user = $broker->getUserInfo(); + +if (!$user) { + header("Location: login.php", true, 307); + exit; +} +?> +<!doctype html> +<html> + <head> + <title><?= $broker->broker ?> (Single Sign-On demo)</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + </head> + <body> + <div class="container"> + <h1><?= $broker->broker ?> <small>(Single Sign-On demo)</small></h1> + <h3>Logged in</h3> + + <dl class="dl-horizontal"> + <?php foreach ($user as $key => $value) : ?> + <dt><?= $key ?></dt><dd><?= $value ?></dd> + <?php endforeach; ?> + </dl> + + <a id="logout" class="btn btn-default" href="login.php?logout=1">Logout</a> + </div> + </body> +</html> diff --git a/examples/broker/login.php b/examples/broker/login.php new file mode 100644 index 0000000..e51fe39 --- /dev/null +++ b/examples/broker/login.php @@ -0,0 +1,56 @@ +<?php +require_once __DIR__ . '/../../vendor/autoload.php'; + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); +$broker->attach(); + +if (!empty($_GET['logout'])) { + $broker->logout(); +} elseif ($broker->getUserInfo() || ($_SERVER['REQUEST_METHOD'] == 'POST' && $broker->login($_POST['username'], $_POST['password']))) { + header("Location: index.php", true, 303); + exit; +} + +if ($_SERVER['REQUEST_METHOD'] == 'POST') $errmsg = "Login failed"; +?> +<!doctype html> +<html> + <head> + <title><?= $broker->broker ?> | Login (Single Sign-On demo)</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + + <style> + h1 { + margin-bottom: 30px; + } + </style> + </head> + <body> + <div class="container"> + <h1><?= $broker->broker ?> <small>(Single Sign-On demo)</small></h1> + + <?php if (isset($errmsg)): ?><div class="alert alert-danger"><?= $errmsg ?></div><?php endif; ?> + + <form class="form-horizontal" action="login.php" method="post"> + <div class="form-group"> + <label for="inputUsername" class="col-sm-2 control-label">Username</label> + <div class="col-sm-10"> + <input type="text" name="username" class="form-control" id="inputUsername"> + </div> + </div> + <div class="form-group"> + <label for="inputPassword" class="col-sm-2 control-label">Password</label> + <div class="col-sm-10"> + <input type="password" name="password" class="form-control" id="inputPassword"> + </div> + </div> + + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10"> + <button type="submit" class="btn btn-default">Login</button> + </div> + </div> + </form> + </div> + </body> +</html> diff --git a/examples/server/.htaccess b/examples/server/.htaccess new file mode 100644 index 0000000..7bb4b5b --- /dev/null +++ b/examples/server/.htaccess @@ -0,0 +1,6 @@ +RewriteEngine On + +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule (.+) index.php?command=$1 [L] + diff --git a/examples/server/MySSOServer.php b/examples/server/MySSOServer.php new file mode 100644 index 0000000..ca523b0 --- /dev/null +++ b/examples/server/MySSOServer.php @@ -0,0 +1,90 @@ +<?php + +use Jasny\ValidationResult; +use Jasny\SSO; + +/** + * Example SSO server. + * + * Normally you'd fetch the broker info and user info from a database, rather then declaring them in the code. + */ +class MySSOServer extends SSO\Server +{ + /** + * Registered brokers + * @var array + */ + private static $brokers = [ + 'Alice' => ['secret'=>'8iwzik1bwd'], + 'Greg' => ['secret'=>'7pypoox2pc'], + 'Julias' => ['secret'=>'ceda63kmhp'] + ]; + + /** + * System users + * @var array + */ + private static $users = array ( + 'jackie' => [ + 'fullname' => 'Jackie Black', + 'email' => 'jackie.black@example.com', + 'password' => '$2y$10$lVUeiphXLAm4pz6l7lF9i.6IelAqRxV4gCBu8GBGhCpaRb6o0qzUO' // jackie123 + ], + 'john' => [ + 'fullname' => 'John Doe', + 'email' => 'john.doe@example.com', + 'password' => '$2y$10$RU85KDMhbh8pDhpvzL6C5.kD3qWpzXARZBzJ5oJ2mFoW7Ren.apC2' // john123 + ], + ); + + /** + * Get the API secret of a broker and other info + * + * @param string $brokerId + * @return array + */ + protected function getBrokerInfo($brokerId) + { + return isset(self::$brokers[$brokerId]) ? self::$brokers[$brokerId] : null; + } + + /** + * Authenticate using user credentials + * + * @param string $username + * @param string $password + * @return ValidationResult + */ + protected function authenticate($username, $password) + { + if (!isset($username)) { + return ValidationResult::error("username isn't set"); + } + + if (!isset($password)) { + return ValidationResult::error("password isn't set"); + } + + if (!isset(self::$users[$username]) || !password_verify($password, self::$users[$username]['password'])) { + return ValidationResult::error("Invalid credentials"); + } + + return ValidationResult::success(); + } + + + /** + * Get the user information + * + * @return array + */ + protected function getUserInfo($username) + { + if (!isset(self::$users[$username])) return null; + + $user = compact('username') + self::$users[$username]; + unset($user['password']); + + return $user; + } +} diff --git a/examples/server/index.php b/examples/server/index.php new file mode 100644 index 0000000..5416eb9 --- /dev/null +++ b/examples/server/index.php @@ -0,0 +1,18 @@ +<?php + +require_once __DIR__ . '/../../vendor/autoload.php'; +require_once 'MySSOServer.php'; + +$ssoServer = new MySSOServer(); +$command = isset($_REQUEST['command']) ? $_REQUEST['command'] : null; + +if (!$command || !method_exists($ssoServer, $command)) { + header("HTTP/1.1 404 Not Found"); + header('Content-type: application/json; charset=UTF-8'); + + echo json_encode(['error' => 'Unknown command']); + exit(); +} + +$result = $ssoServer->$command(); + |