Skip to content

Commit a5e9861

Browse files
Guido Gröönmrts
authored andcommitted
WE2-689 Updated README
WE2-689 Added example project WE2-683 Added method withSecureRandom() to ChallengeNonceGeneratorBuilder
1 parent e7d7814 commit a5e9861

File tree

15 files changed

+670
-7
lines changed

15 files changed

+670
-7
lines changed

README.md

Lines changed: 316 additions & 2 deletions
Large diffs are not rendered by default.

examples/composer.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "demo/webeid-php",
3+
"description": "Web eID PHP demo",
4+
"license": "MIT",
5+
"type": "library",
6+
"authors": [
7+
{
8+
"name": "Guido Gröön",
9+
"role" : "developer"
10+
}
11+
],
12+
"require": {
13+
"php": ">=7.4",
14+
"web_eid/web_eid_authtoken_validation_php": "dev-main",
15+
"web_eid/ocsp_php": "dev-main",
16+
"altorouter/altorouter": "1.1.0"
17+
},
18+
"autoload": {
19+
"classmap": ["src"]
20+
},
21+
"repositories": [
22+
{
23+
"type": "vcs",
24+
"url": "https://github.com/web-eid/web-eid-authtoken-validation-php.git"
25+
},
26+
{
27+
"type": "vcs",
28+
"url": "https://github.com/web-eid/ocsp-php.git"
29+
}
30+
]
31+
}

examples/index.php

Lines changed: 0 additions & 3 deletions
This file was deleted.

examples/public/.htaccess

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
RewriteEngine on
2+
RewriteCond %{REQUEST_FILENAME} !-f
3+
RewriteCond %{REQUEST_FILENAME}/ !-f
4+
RewriteRule . index.php [L]

examples/public/index.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
header('Content-type: text/html; charset=UTF-8');
4+
5+
session_start();
6+
7+
// Define the log location
8+
define("LOGFILE", dirname(__FILE__) . "/../log/web-eid-authtoken-validation-php.log");
9+
10+
require __DIR__ . '/../vendor/autoload.php';
11+
12+
$router = new Router();
13+
$router->init();

examples/src/Auth.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
use web_eid\web_eid_authtoken_validation_php\authtoken\WebEidAuthToken;
4+
use web_eid\web_eid_authtoken_validation_php\certificate\CertificateData;
5+
use web_eid\web_eid_authtoken_validation_php\certificate\CertificateLoader;
6+
use web_eid\web_eid_authtoken_validation_php\challenge\ChallengeNonceGenerator;
7+
use web_eid\web_eid_authtoken_validation_php\challenge\ChallengeNonceGeneratorBuilder;
8+
use web_eid\web_eid_authtoken_validation_php\challenge\ChallengeNonceStore;
9+
use web_eid\web_eid_authtoken_validation_php\exceptions\ChallengeNonceExpiredException;
10+
use web_eid\web_eid_authtoken_validation_php\util\Uri;
11+
use web_eid\web_eid_authtoken_validation_php\validator\AuthTokenValidator;
12+
use web_eid\web_eid_authtoken_validation_php\validator\AuthTokenValidatorBuilder;
13+
14+
class Auth
15+
{
16+
17+
public function trustedIntermediateCACertificates(): array
18+
{
19+
return CertificateLoader::loadCertificatesFromResources(
20+
__DIR__ . "/../certificates/esteid2018.der.crt", __DIR__ . "/../certificates/ESTEID-SK_2015.der.crt"
21+
);
22+
}
23+
24+
public function generator(): ChallengeNonceGenerator
25+
{
26+
return (new ChallengeNonceGeneratorBuilder())
27+
->withNonceTtl(300)
28+
->build();
29+
}
30+
31+
public function tokenValidator(): AuthTokenValidator
32+
{
33+
return (new AuthTokenValidatorBuilder())
34+
->withSiteOrigin(new Uri('https://localhost:8443'))
35+
->withTrustedCertificateAuthorities(...self::trustedIntermediateCACertificates())
36+
->build();
37+
}
38+
39+
/**
40+
* Get challenge nonce
41+
*
42+
* @return string
43+
*/
44+
public function getNonce()
45+
{
46+
try {
47+
header('Content-Type: application/json; charset=utf-8');
48+
$generator = $this->generator();
49+
$challengeNonce = $generator->generateAndStoreNonce();
50+
$responseArr = [];
51+
$responseArr["nonce"] = $challengeNonce->getBase64EncodedNonce();
52+
echo json_encode($responseArr);
53+
} catch (Exception $e) {
54+
header("HTTP/1.0 400 Bad Request");
55+
echo $e->getMessage();
56+
}
57+
}
58+
59+
/**
60+
* Authenticate
61+
*
62+
* @return string
63+
*/
64+
public function validate()
65+
{
66+
$authToken = file_get_contents('php://input');
67+
68+
try {
69+
70+
/* Get and remove nonce from store */
71+
$challengeNonce = (new ChallengeNonceStore())->getAndRemove();
72+
73+
try {
74+
75+
// Build token validator
76+
$tokenValidator = $this->tokenValidator();
77+
78+
// Validate token
79+
$cert = $tokenValidator->validate(new WebEidAuthToken($authToken), $challengeNonce->getBase64EncodedNonce());
80+
81+
session_regenerate_id();
82+
83+
$subjectName = CertificateData::getSubjectGivenName($cert) . " " . CertificateData::getSubjectSurname($cert);
84+
$result = [
85+
'sub' => $subjectName
86+
];
87+
88+
$_SESSION["auth-user"] = $subjectName;
89+
90+
echo json_encode($result);
91+
92+
} catch (Exception $e) {
93+
header("HTTP/1.0 400 Bad Request");
94+
echo $e->getMessage();
95+
}
96+
97+
} catch (ChallengeNonceExpiredException $e) {
98+
header("HTTP/1.0 400 Bad Request");
99+
echo $e->getMessage();
100+
}
101+
}
102+
103+
/**
104+
* Logout
105+
*
106+
*/
107+
public function logout()
108+
{
109+
unset($_SESSION["auth-user"]);
110+
session_regenerate_id();
111+
// Redirect to login
112+
header("location:/");
113+
}
114+
115+
}

examples/src/Pages.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
class Pages
4+
{
5+
var $template;
6+
var $data = [];
7+
8+
public function __construct()
9+
{
10+
$this->template = new Template();
11+
}
12+
13+
public function login()
14+
{
15+
$this->data['content'] = $this->template->getHtml(__DIR__ . '/../tpl/login.phtml');
16+
}
17+
18+
public function welcome()
19+
{
20+
if (!isset($_SESSION["auth-user"])) {
21+
// Redirect to login
22+
header("location:/");
23+
return;
24+
}
25+
26+
$data = [];
27+
$data["auth_user"] = $_SESSION["auth-user"];
28+
$this->data['content'] = $this->template->getHtml(__DIR__ . '/../tpl/welcome.phtml', $data);
29+
}
30+
31+
public function __destruct()
32+
{
33+
echo $this->template->getHtml(__DIR__ . '/../tpl/site.phtml', $this->data);
34+
}
35+
36+
}

examples/src/Router.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/* App router */
3+
4+
class Router
5+
{
6+
public function init()
7+
{
8+
9+
$router = new AltoRouter();
10+
$router->setBasePath('');
11+
12+
// Page routes
13+
$router->map('GET', '', ['controller' => 'Pages', 'method' => 'login']);
14+
$router->map('GET', '/', ['controller' => 'Pages', 'method' => 'login']);
15+
$router->map('GET', '/logout', ['controller' => 'Auth', 'method' => 'logout']);
16+
17+
// Allow route onlu for authenticated users
18+
if (isset($_SESSION["auth-user"])) {
19+
$router->map('GET', '/welcome', ['controller' => 'Pages', 'method' => 'welcome']);
20+
}
21+
22+
// Web eID routes
23+
$router->map('GET', '/nonce', ['controller' => 'Auth', 'method' => 'getNonce']);
24+
$router->map('POST', '/validate', ['controller' => 'Auth', 'method' => 'validate']);
25+
26+
$match = $router->match();
27+
28+
if (!$match) {
29+
// Redirect to login
30+
header("location:/");
31+
return;
32+
}
33+
34+
35+
$controller = new $match['target']['controller'];
36+
$method = $match['target']['method'];
37+
38+
call_user_func([$controller, $method], $match['params'], []);
39+
40+
}
41+
}

0 commit comments

Comments
 (0)