Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e621c3a
Start rewrite
samuelwei May 8, 2025
93d105f
Add support for ImplicitFlow, support signed UserInfo responses
samuelwei Jun 18, 2025
3080938
Add support for additionalJwks
samuelwei Jun 18, 2025
766a809
Keep support for PHP 8.1
samuelwei Jun 18, 2025
081b4f9
Fix code style
samuelwei Jun 18, 2025
3269b16
Add support for elliptic curve
samuelwei Jun 18, 2025
d5b8b16
Add support for verifyLogoutTokenClaims and verifyLogoutToken
samuelwei Jun 18, 2025
f64dd57
Code cleanup
samuelwei Jun 20, 2025
8de45e3
Require jti claim on logout token
samuelwei Jun 20, 2025
c0042da
Add support for EdDSA (only Ed25519)
samuelwei Jun 20, 2025
943de88
Remove old php version from github actions
samuelwei Jun 24, 2025
7294cbc
Update phpunit config format
samuelwei Jun 26, 2025
69bd300
Check auth code flow token endpoint response has token_type and acces…
samuelwei Jun 26, 2025
ba5968a
Refactor fetchURL return type to custom Response class
samuelwei Jun 26, 2025
1be11b7
Add integration tests for authenticate and userInfo
samuelwei Jun 26, 2025
b843e12
Code cleanup
samuelwei Jun 30, 2025
8e22a51
Fix wrong TestCase class
samuelwei Jun 30, 2025
af7136a
Require jti on back-channel logout, add jti getter
samuelwei Jun 30, 2025
2f2d28a
Adjust tests
samuelwei Jun 30, 2025
af42873
Remove test
samuelwei Jun 30, 2025
9867b90
Expose addAdditionalJwk function
samuelwei Jun 30, 2025
06febbd
Catch no jwk found to check signiture against
samuelwei Jun 30, 2025
490a9aa
Add tests for all supported alg in VerifyJWS
samuelwei Jun 30, 2025
fa1729f
Remove unused validateIssuer method
samuelwei Jun 30, 2025
40cf00f
Add support for handleJweResponse
samuelwei Jul 1, 2025
38e98f0
Add tests for RequestUserInfo with JWE
samuelwei Jul 1, 2025
499dad9
Add tests for authenticate with JWE
samuelwei Jul 1, 2025
c456cda
Check state earlier
samuelwei Jul 1, 2025
3272242
Add state checks to authenticate
samuelwei Jul 1, 2025
3a0c8db
Restructure code for better readability
samuelwei Jul 1, 2025
01ad3c5
Add VerifyLogoutToken tests
samuelwei Jul 1, 2025
e423bd0
Update changelog
samuelwei Jul 1, 2025
30343b7
Add redirect tests, fix test issues, refactor code
samuelwei Jul 2, 2025
173c45e
Update changelog
samuelwei Jul 2, 2025
477e9bf
Add script, update gitignore
samuelwei Jul 2, 2025
43e5db3
Refactor error handling for token endpoint
samuelwei Jul 2, 2025
cb2ac43
Add more auth error tests, improve test performance
samuelwei Jul 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
php: ['8.1', '8.2', '8.3', '8.4']

steps:
- name: Checkout
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/.idea
/vendor
/composer.lock
/coverage
.phpunit.result.cache
.php-cs-fixer.cache
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added
- Support to change the `leeway` time for JWT verification using `setLeeway` #483
- Support for elliptic curves (ES256, ES384 & ES512) #488
- Support for EdDSA (only Ed25519) #488
- `getJtiFromBackChannel()` to retrieve the JTI after back-channel logout request #488
- `getJWSClaims` to retrieve the claims from a JWS #488
- `verifyJWSHeader` to verify the JWS header #488

### Changed
- Stop adding ?schema=openid to userinfo endpoint URL. #449
- Min. PHP version to 8.1 #488
- `fetchURL` response type to `Response` class #488
- `Nonce` claim must be present, Partially reverts #280
- `verifySignatures` method signature, accepting `JWS` object instead of string #488

### Fixed
- Check existence of subject when verifying JWT #474
- Check existence of `sub` claim when verifying JWT #474
- exp verification when verifying Logout Token claims #482
- Missing `iat` claim verification #488
- Exception is thrown when `iss` claim is missing #488
- Missing check of `events` claim when verifying Logout Token claims #488
- Missing check of `jti` claim when verifying Logout Token claims #488
- Missing check of `sub` claim for unsigned UserInfo Responses #488

### Removed
- `getResponseCode()`, replaced with new response method `getStatus()` #488
- `getResponseContentType()`, replaced with new response method `getContentType()` #488
- `verifyJWTClaims()`, replaced with individual checks #488
- `validateIssuer()`, replaced with `IssuerChecker` #488
- `verifyJWTSignature()`, replaced with `verifyJWSSignature()` #488

## [1.0.1] - 2024-09-13

Expand Down
15 changes: 12 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
"description": "Bare-bones OpenID Connect client",
"license": "Apache-2.0",
"require": {
"php": ">=7.1",
"php": ">=8.1",
"ext-json": "*",
"ext-curl": "*",
"phpseclib/phpseclib": "^3.0.7"
"phpseclib/phpseclib": "^3.0.7",
"web-token/jwt-library": "^3.0",
"symfony/clock": "^6.4"
},
"require-dev": {
"phpunit/phpunit": "<10",
"roave/security-advisories": "dev-latest",
"yoast/phpunit-polyfills": "^2.0"
"yoast/phpunit-polyfills": "^2.0",
"friendsofphp/php-cs-fixer": "^3.75",
"fakerphp/faker": "^1.24"
},
"archive" : {
"exclude" : [
Expand All @@ -20,5 +24,10 @@
},
"autoload" : {
"classmap": [ "src/"]
},
"scripts": {
"test": "phpunit",
"test:coverage": "XDEBUG_MODE=coverage phpunit --coverage-html coverage/",
"fix-cs": "php-cs-fixer fix ."
}
}
41 changes: 15 additions & 26 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="./vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
verbose="true"
stopOnFailure="false"
processIsolation="false"
backupGlobals="false"
syntaxCheck="true"
>
<testsuites>
<testsuite name="Tests">
<directory>./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
<exclude>
<directory>./vendor</directory>
<directory>./tests</directory>
</exclude>
</whitelist>
</filter>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="./vendor/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" verbose="true" stopOnFailure="false" processIsolation="false" backupGlobals="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage includeUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
<exclude>
<directory>./vendor</directory>
<directory>./tests</directory>
</exclude>
</coverage>
<testsuites>
<testsuite name="Tests">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
36 changes: 36 additions & 0 deletions src/AccessTokenHashChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Jumbojett;

use Jose\Component\Checker\ClaimChecker;
use Jose\Component\Checker\InvalidClaimException;

final class AccessTokenHashChecker implements ClaimChecker
{
public function __construct(private OpenIDConnectClient $openIDConnectClient)
{

}

public function checkClaim($value): void
{
$alg = $this->openIDConnectClient->getIdTokenHeader()->alg;

$bit = match ($alg) {
'EdDSA' => '512',
default => substr($alg, 2, 3),
};

$len = ((int)$bit) / 16;
$expected_at_hash = $this->openIDConnectClient->urlEncode(substr(hash('sha'.$bit, $this->openIDConnectClient->getAccessToken(), true), 0, $len));

if ($value !== $expected_at_hash) {
throw new InvalidClaimException('The claim "at_hash" does not match the Access Token hash value.', 'at_hash', $value);
}
}

public function supportedClaim(): string
{
return 'at_hash';
}
}
30 changes: 30 additions & 0 deletions src/EventsChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Jumbojett;

use Jose\Component\Checker\ClaimChecker;
use Jose\Component\Checker\InvalidClaimException;

final class EventsChecker implements ClaimChecker
{
public function __construct(protected string $event)
{

}

public function checkClaim($value): void
{

$events = (array) $value;
if (!isset($events['http://schemas.openid.net/event/backchannel-logout']) ||
!is_object($events['http://schemas.openid.net/event/backchannel-logout'])) {
throw new InvalidClaimException('The claim "events" does not contain the expected value.', 'events', $events);
}

}

public function supportedClaim(): string
{
return 'events';
}
}
34 changes: 34 additions & 0 deletions src/IssuerChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Jumbojett;

use Jose\Component\Checker\ClaimChecker;
use Jose\Component\Checker\InvalidClaimException;

final class IssuerChecker implements ClaimChecker
{
public function __construct(private OpenIDConnectClient $openIDConnectClient)
{

}

public function checkClaim($value): void
{
$issuerValidator = $this->openIDConnectClient->getIssuerValidator();

if ($issuerValidator !== null) {
$isValid = $issuerValidator->__invoke($value);
} else {
$isValid = ($value === $this->openIDConnectClient->getIssuer() || $value === $this->openIDConnectClient->getWellKnownIssuer() || $value === $this->openIDConnectClient->getWellKnownIssuer(true));
}

if (!$isValid) {
throw new InvalidClaimException('The claim "iss" does not match the expected value.', 'iss', $value);
}
}

public function supportedClaim(): string
{
return 'iss';
}
}
Loading