test-oidc-client/public_html/index.php

379 lines
9.5 KiB
PHP
Raw Normal View History

2024-07-24 18:13:46 +02:00
<?php
# vim: shiftwidth=2 tabstop=2 expandtab
require __DIR__ . '/../vendor/autoload.php';
use Jumbojett\OpenIDConnectClient;
use Jumbojett\OpenIDConnectClientException;
/*
************************************
* Configuration *
************************************
*/
// Public app URL
$public_app_url = "https://connection.example.com/test-oidc";
// All valid OIDC servers
$oidc_servers = [
// OIDC server hostname
"connection.example.com" => [
// OIDC server root URL
"url" => "https://connection.example.com",
// Client ID (as provided by your IDP)
"client_id" => "27d65748-0aaa-42d9-90dc-353d94f2840a",
// Client secret (as provided by your IDP)
"client_secret" => "5d86b271-a3b8-4d75-b569-a86d48b75658",
// Requested OIDC scopes
"scopes" => ["profile", "email"],
// Expected attributes (optional, retrieve all proposed attributes otherwise)
/*
"expected_attributes" => [
"preferred_username",
"given_name",
"family_name",
"email",
],
*/
],
];
// FQDN of OIDC server
$default_oidc_server = key($oidc_servers);
/*
************************************
* Main *
************************************
*/
session_start();
$_SESSION["warnings"] = isset($_SESSION["warnings"]) && is_array($_SESSION["warnings"])?$_SESSION["warnings"]:[];
if (isset($_REQUEST['server']) && !isset($oidc_servers[$_REQUEST['server']])) {
$_SESSION["warnings"][] = "Invalid OIDC server choiced";
unset($_REQUEST['server']);
}
if (isset($_REQUEST['server'])) {
$oidc_server = $_REQUEST['server'];
if ($_SESSION['oidc_server'] != $oidc_server) {
$_SESSION = []; // reset session on changing OIDC server
}
}
elseif (isset($_SESSION['oidc_server'])) {
$oidc_server = $_SESSION['oidc_server'];
}
else {
$oidc_server = $default_oidc_server;
$_SESSION = []; // reset session
}
$_SESSION['oidc_server'] = $oidc_server;
function reset_session() {
global $oidc_server;
$_SESSION = [];
if (isset($oidc_server) && $oidc_server)
$_SESSION['oidc_server'] = $oidc_server;
}
$_show_oidc_client_config = false;
function show_oidc_client_config() {
global $_show_oidc_client_config, $oidc_client_config;
if ($_show_oidc_client_config) return true;
$_show_oidc_client_config = true;
echo "<h3>OIDC Client configuration</h3><ul>";
foreach($oidc_client_config as $cfg_name => $cfg_val) {
echo "<li><strong>$cfg_name :</strong> <em>$cfg_val</em></li>";
}
echo "</ul>";
}
function show_warnings() {
if (!empty($_SESSION["warnings"])) {
echo "<h2 style='color: #f00'>Warnings message</h2><ul>";
foreach ($_SESSION["warnings"] as $msg) {
echo "<li>$msg</li>";
}
echo "</ul>";
}
$_SESSION["warnings"] = [];
}
$_SESSION["messages"] = isset($_SESSION["messages"]) && is_array($_SESSION["messages"])?$_SESSION["messages"]:[];
function show_messages() {
if (!empty($_SESSION["messages"])) {
echo "<div class='success'>";
if (count($_SESSION["messages"]) == 1) {
echo $_SESSION["messages"][0];
}
else {
echo "<ul>";
foreach($_SESSION["messages"] as $msg)
echo "<li>$msg</li>";
echo "</ul>";
}
echo "</div>";
}
$_SESSION["messages"] = [];
}
function vardump($value) {
ob_start();
var_dump($value);
$value = ob_get_contents();
ob_end_clean();
return $value;
}
function redirect($url=null) {
global $public_app_url;
$url = $url?$url:$public_app_url;
header("Location: $url");
exit();
}
function show_user_infos() {
echo "<h2>Token ID</h2>";
echo "<pre>".vardump($_SESSION['id_token'])."</pre>";
echo "<h2>Verified claims</h2>";
echo "<pre>".vardump($_SESSION['verified_claims'])."</pre>";
echo "<h2>Attributes</h2>";
echo "<ul>";
foreach($_SESSION['attributes'] as $attr => $value) {
$value = vardump($value);
echo "<li><b>{$attr} :</b><pre>{$value}</pre></li>\n";
}
echo "</ul>";
}
?>
<html>
<head>
<title>Test OIDC</title>
<style>
strong {
font-size: 0.9em;
}
em {
font-size: 0.8em;
}
pre {
margin-left: 1em;
padding: 1em;
border-left: 1px solid;
background-color: #eee;
font-size: 0.9em;
}
div.success, div.error {
padding: 0.2em;
width: 50%;
font-weight: bold;
margin: 1em;
text-align: center;
}
div.success {
color: #0E4700;
border: 1px solid #0E4700;
background-color: #99E774;
}
div.error {
color: #f00;
border: 1px solid #f00;
padding: 1em;
background-color: #C56E6E;
}
h2 {
border-bottom: 1px solid;
}
</style>
<body>
<h1>Test OIDC Application</h1>
<?php
show_warnings();
show_messages();
?>
<h2>OIDC server selection</h2>
<form action='index.php' method='POST'>
<label for='server'>OIDC server</label> :
<select name='server' id='server' onchange="javascript:submit();">
<?php
foreach($oidc_servers as $server => $opts) {
echo "<option value='$server'".($oidc_server == $server?'selected':'').">$server</option>\n";
}
?>
</select>
<input type='submit' value='Change'/>
</form>
<h2>Menu</h2>
<ul>
<li><a href='?do=login'>Login</a></li>
<li><a href='?do=logout'>Logout on OIDC server</a></li>
<li><a href='?do=local_logout'>Logout on local application</a></li>
</ul>
<h2>OIDC Client Initialization ...</h2>
<?php
$oidc_client_config = [
"Public application URL" => $public_app_url,
'OIDC Hostname' => $oidc_server,
'IDP URL' => $oidc_servers[$oidc_server]['url'],
'Client ID' => (
substr($oidc_servers[$oidc_server]['client_id'], 0, 4)."...".
substr($oidc_servers[$oidc_server]['client_id'], -2)
),
'Client secret' => (
substr($oidc_servers[$oidc_server]['client_secret'], 0, 4)."...".
substr($oidc_servers[$oidc_server]['client_secret'], -2)
),
];
$oidc = new OpenIDConnectClient(
$oidc_servers[$oidc_server]['url'],
$oidc_servers[$oidc_server]['client_id'],
$oidc_servers[$oidc_server]['client_secret']
);
$client_redirect_url = $public_app_url."/?do=login";
$oidc_client_config["Client redirect URL"] = $client_redirect_url;
$oidc->setRedirectURL($client_redirect_url);
$client_logout_redirect_url = "$public_app_url/?do=logout_callback";
$oidc_client_config["Client logout redirect URL"] = $client_logout_redirect_url;
$oidc_client_config["Scopes"] = implode(", ", $oidc_servers[$oidc_server]['scopes']);
$oidc->addScope($oidc_servers[$oidc_server]['scopes']);
$oidc_client_config['Expected attributes'] = (
isset($oidc_servers[$oidc_server]['expected_attributes']) // @phpstan-ignore-line
&& is_array($oidc_servers[$oidc_server]['expected_attributes'])
&& ! empty($oidc_servers[$oidc_server]['expected_attributes'])?
implode(", ", $oidc_servers[$oidc_server]['expected_attributes']):
"none (retrieve all provided attributes)"
);
echo "<p><strong>Client successfully initialized</strong></p>";
show_oidc_client_config();
show_warnings();
?>
<h2>Action</h2>
<h3>State before running action</h3>
<?php
if (isset($_SESSION['idToken']) && $_SESSION['idToken']) {
echo "Authenticated";
}
else {
echo "Not authenticated";
}
?>
<h3>Running action...</h3>
<?php
if (isset($_REQUEST['do'])) {
switch($_REQUEST['do']) {
case 'login':
try {
$oidc->authenticate();
}
catch(OpenIDConnectClientException $e) {
$_SESSION["warnings"][] = "Fail to authenticate: ".$e->getMessage();
redirect();
}
$_SESSION["messages"][] = "Successfully authenticated";
$_SESSION['id_token'] = $oidc->getIdToken();
$_SESSION['verified_claims'] = $oidc->getVerifiedClaims();
$_SESSION['attributes'] = [];
if (
isset($oidc_servers[$oidc_server]['expected_attributes']) // @phpstan-ignore-line
&& is_array($oidc_servers[$oidc_server]['expected_attributes'])
&& !empty($oidc_servers[$oidc_server]['expected_attributes'])
) {
foreach($oidc_servers[$oidc_server]['expected_attributes'] as $attr) {
try {
$_SESSION['attributes'][$attr] = $oidc->requestUserInfo($attr);
}
catch(OpenIDConnectClientException $e) {
$_SESSION["warnings"][] = "Fail to retrieve attribute '$attr': ".$e->getMessage();
}
}
}
else {
try {
$_SESSION['attributes'] = get_object_vars($oidc->requestUserInfo());
}
catch(OpenIDConnectClientException $e) {
$_SESSION["warnings"][] = "Fail to retrieve attributes: ".$e->getMessage();
}
}
redirect();
break;
case 'logout':
if (isset($_SESSION['id_token'])) {
$_SESSION["logout_expected"] = true;
$oidc->signOut($_SESSION['id_token'], $client_logout_redirect_url);
}
else {
$_SESSION["warnings"] = "Not yet authenticated, can't logout!";
redirect();
}
break;
case "logout_callback":
if (isset($_SESSION["logout_expected"]) && $_SESSION["logout_expected"]) {
$_SESSION = ["oidc_server" => $oidc_server];
$_SESSION["messages"][] = "Successfully logout from OIDC server and client application.";
unset($_SESSION["logout_expected"]);
}
else {
$_SESSION["warnings"] = "Unexpected logout callback URL call";
}
redirect();
break;
case 'local_logout':
$_SESSION = ["oidc_server" => $oidc_server];
$_SESSION["messages"][] = "Successfully logout from client application only.";
redirect();
break;
default:
$_SESSION["warningsverified_claims"] = "Incorrect requested action";
redirect();
}
}
else {
echo "Nothing to do";
}
if (isset($_SESSION['id_token'])) {
echo "<h2>Authenticated user information</h2>";
show_user_infos();
}
?>
</body>
</html>