Skip to content

Commit f041094

Browse files
committed
Merge branch 'master' into wip-vci
2 parents 4c54a79 + 0080cf2 commit f041094

File tree

4 files changed

+61
-53
lines changed

4 files changed

+61
-53
lines changed

README.md

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# simplesamlphp-module-oidc
22
> A SimpleSAMLphp module for OIDC OP support.
33
4-
This module adds support for OpenID Provider role from the OpenID Connect protocol
5-
through a SimpleSAMLphp module installable through Composer. It is based on
6-
[Oauth2 Server from the PHP League](https://oauth2.thephpleague.com/)
4+
This module adds support for the OpenID Provider role from the OpenID Connect protocol
5+
through a SimpleSAMLphp module installable via Composer. It is based on
6+
[OAuth2 Server from the PHP League](https://oauth2.thephpleague.com/).
77

88
Currently supported flows are:
99
* Authorization Code flow, with PKCE support (response_type 'code')
@@ -16,28 +16,28 @@ Currently supported flows are:
1616

1717
![Main screen capture](docs/oidc.png)
1818

19-
### Note on OpenID Federation (OIDF) support
19+
### Note on OpenID Federation (OIDFed) support
2020

2121
OpenID Federation support is in "draft" phase, as is the
22-
[specification](https://openid.net/specs/openid-federation-1_0) itself. This means that you can expect braking changes
23-
in future releases related to OIDF capabilities. You can enable / disable OIDF support at any time in module
22+
[specification](https://openid.net/specs/openid-federation-1_0) itself. This means that you can expect breaking changes
23+
in future releases related to OIDFed capabilities. You can enable / disable OIDFed support at any time in the module
2424
configuration.
2525

26-
Currently, the following OIDF features are supported:
26+
Currently, the following OIDFed features are supported:
2727
* automatic client registration using a Request Object (passing it by value)
2828
* federation participation limiting based on Trust Marks
2929
* endpoint for issuing configuration entity statement (statement about itself)
3030
* fetch endpoint for issuing statements about subordinates (registered clients)
3131
* subordinate listing endpoint
3232

33-
OIDF support is implemented using the underlying [SimpleSAMLphp OpenID library](https://github.com/simplesamlphp/openid).
33+
OIDFed support is implemented using the underlying [SimpleSAMLphp OpenID library](https://github.com/simplesamlphp/openid).
3434

3535
## Version compatibility
3636

37-
Minor versions of SimpleSAMLphp noted below means that the module has been tested with that version of SimpleSAMLphp
38-
during module development. SimpleSAMLphp started following semantic versioning for its API from version 2.0. This means,
39-
for example, that v5.* of the oidc module should work on any v2.* of SimpleSAMLphp. However, do mind that there were
40-
PHP version requirement changes in minor releases for SimpleSAMLphp.
37+
The minor versions of SimpleSAMLphp listed below indicate which versions of SimpleSAMLphp were used for testing
38+
during module development. SimpleSAMLphp has followed semantic versioning for its API since version 2.0. This means,
39+
for example, that v5.* of the OIDC module should work with any v2.* of SimpleSAMLphp. However, please note that
40+
PHP version requirements have changed in minor SimpleSAMLphp releases.
4141

4242
| OIDC module | Tested SimpleSAMLphp | PHP | Note |
4343
|:------------|:---------------------|:------:|-----------------------------|
@@ -53,65 +53,69 @@ If you are upgrading from a previous version, make sure to check the [upgrade gu
5353

5454
## Installation
5555

56-
Installation can be as easy as executing:
56+
Installation is as simple as executing:
5757

5858
composer require simplesamlphp/simplesamlphp-module-oidc
5959

6060
### Configure the module
6161

62-
Copy the module config template file to the SimpleSAMLphp config directory:
62+
Copy the module configuration template file to the SimpleSAMLphp config directory:
6363

6464
cp modules/oidc/config/module_oidc.php.dist config/module_oidc.php
6565

66-
The options are self-explanatory, so make sure to go through the file and edit them as appropriate.
66+
Review all options in the file and edit them as needed for your environment.
6767

6868
### Configure the database
6969

70-
This module uses a default SimpleSAMLphp database feature to store access/refresh tokens, user data, etc.
71-
In order for this to work, edit your `config/config.php` and check 'database' related configuration. Make sure
72-
you have at least the following parameters set:
70+
This module uses SimpleSAMLphp's database feature to store access/refresh tokens, user data, and other information.
71+
To set this up, edit your `config/config.php` and configure the database-related settings. Ensure you have at least
72+
the following parameters configured:
7373

7474
'database.dsn' => 'mysql:host=server;dbname=simplesamlphp;charset=utf8',
7575
'database.username' => 'user',
7676
'database.password' => 'password',
7777

7878
> [!NOTE]
79-
> The module has been tested against and supports the SQLite, PostgreSQL and MySQL databases.
79+
> The module has been tested with and supports SQLite, PostgreSQL, and MySQL databases.
8080
8181
### Create Protocol / Federation RSA key pairs
8282

83-
During the authentication flow, generated ID Token and Access Token will be in a form of signed JSON Web token (JWS).
84-
Because of the signing part, you need to create a public/private RSA key pair. This public/private RSA key pair
85-
is referred to as "OIDC protocol" keys. On the other hand, if you will be using OpenID Federation capabilities,
86-
you should create separate key pair dedicated for OpenID Federation operations, like signing Entity Statement JWS.
87-
Below are sample commands to create key pairs with default file names, both "protocol" and "federation" version.
83+
During the authentication flow, the generated ID Token and Access Token will be in the form of signed JSON Web Tokens (JWS).
84+
For signing these tokens, you need to create a public/private RSA key pair, referred to as "OIDC protocol" keys.
8885

89-
To generate the private key, you can run this command in the terminal:
86+
If you plan to use OpenID Federation capabilities, you should create a separate key pair dedicated to OpenID Federation
87+
operations, such as signing Entity Statement JWS.
88+
89+
Below are sample commands to create key pairs with default file names for both "protocol" and "federation" purposes:
90+
91+
To generate the private keys without a passphrase:
9092

9193
openssl genrsa -out cert/oidc_module.key 3072
9294
openssl genrsa -out cert/oidc_module_federation.key 3072
9395

94-
If you want to provide a passphrase for your private key, run this command instead:
96+
To generate the private keys with a passphrase:
9597

9698
openssl genrsa -passout pass:myPassPhrase -out cert/oidc_module.key 3072
9799
openssl genrsa -passout pass:myPassPhrase -out cert/oidc_module_federation.key 3072
98100

99-
Now you need to extract the public key from the private key:
101+
Next, extract the public key from each private key:
102+
103+
Without passphrase:
100104

101105
openssl rsa -in cert/oidc_module.key -pubout -out cert/oidc_module.crt
102106
openssl rsa -in cert/oidc_module_federation.key -pubout -out cert/oidc_module_federation.crt
103107

104-
or use your passphrase if provided on private key generation:
108+
With passphrase:
105109

106110
openssl rsa -in cert/oidc_module.key -passin pass:myPassPhrase -pubout -out cert/oidc_module.crt
107111
openssl rsa -in cert/oidc_module_federation.key -passin pass:myPassPhrase -pubout -out cert/oidc_module_federation.crt
108112

109-
If you use different files names or a passphrase, make sure to configure it in the `module_oidc.php` config file.
113+
If you use different file names or a passphrase, be sure to update these settings in the `module_oidc.php` configuration file.
110114

111115
### Enabling the module
112116

113-
At this point we can enable the module by adding `'oidc' => true` to the list of enabled modules in the main
114-
SimpleSAMLphp configuration file, `config/config.php`.
117+
To enable the module, add `'oidc' => true` to the list of enabled modules in the main SimpleSAMLphp
118+
configuration file, `config/config.php`:
115119

116120
'module.enable' => [
117121
'exampleauth' => false,
@@ -122,14 +126,17 @@ SimpleSAMLphp configuration file, `config/config.php`.
122126
'oidc' => true,
123127
],
124128

125-
Once the module is enabled, the database migrations must be run.
129+
After enabling the module, you must run the database migrations.
126130

127131
### Run database migrations
128132

129-
The module comes with some default SQL migrations which set up needed tables in the configured database. To run them,
130-
in the SimpleSAMLphp administration area go to `OIDC` > `Database Migrations`, and press the available button.
133+
The module includes default SQL migrations that set up the necessary tables in your configured database.
134+
To run these migrations:
135+
136+
Option 1: Through the web interface - Navigate to the SimpleSAMLphp administration area, go to
137+
`OIDC` > `Database Migrations`, and click the available button.
131138

132-
Alternatively, in case of automatic / scripted deployments, you can run the 'install.php' script from the command line:
139+
Option 2: Through the command line (recommended for automated/scripted deployments):
133140

134141
php modules/oidc/bin/install.php
135142

@@ -326,8 +333,8 @@ The module offers an OpenID Federation configuration endpoint at URL:
326333

327334
### .well-known URLs
328335

329-
You can configure you web server (Apache, Nginx) in a way to serve the mentioned URLs in a '.well-known'
330-
form. Below are some sample configurations for `openid-configuration`, but you can take the same approach for
336+
You can configure your web server (Apache, Nginx) in a way to serve the mentioned URLs in a '.well-known'
337+
format. Below are some sample configurations for `openid-configuration`, but you can take the same approach for
331338
`openid-federation`.
332339

333340
#### nginx

src/Admin/Authorization.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ public function requireAdminOrUserWithPermission(string $permission): void
5656

5757
try {
5858
$this->authContextService->requirePermission($permission);
59-
} catch (Exception $exception) {
60-
throw new AuthorizationException(
61-
Translate::noop('User not authorized.'),
62-
$exception->getCode(),
63-
$exception,
64-
);
59+
} catch (\Exception) {
60+
// TODO mivanci v7 log this exception
6561
}
62+
63+
// If we get here, the user does not have the required permission, or permissions are not enabled.
64+
// Fallback to admin authentication.
65+
$this->requireAdmin(true);
6666
}
6767

6868
public function getUserId(): string

src/Services/AuthContextService.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ public function __construct(
3131
) {
3232
}
3333

34-
public function isSspAdmin(): bool
35-
{
36-
return $this->sspBridge->utils()->auth()->isAdmin();
37-
}
38-
3934
/**
4035
* @throws \SimpleSAML\Error\Exception
4136
* @throws \Exception
@@ -57,8 +52,6 @@ public function getAuthUserId(): string
5752
*/
5853
public function requirePermission(string $neededPermission): void
5954
{
60-
$auth = $this->authenticate();
61-
6255
$permissions = $this->moduleConfig
6356
->config()
6457
->getOptionalConfigItem(ModuleConfig::OPTION_ADMIN_UI_PERMISSIONS, null);
@@ -69,6 +62,9 @@ public function requirePermission(string $neededPermission): void
6962
if (!$permissions->hasValue($neededPermission)) {
7063
throw new RuntimeException('No permission defined for ' . $neededPermission);
7164
}
65+
66+
$auth = $this->authenticate();
67+
7268
$attributeName = $permissions->getString('attribute');
7369
/** @var string[] $entitlements */
7470
$entitlements = $auth->getAttributes()[$attributeName] ?? [];

tests/unit/src/Admin/AuthorizationTest.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ public function testRequireAdminOrUserWithPermissionReturnsIfAdmin(): void
9595

9696
public function testRequireAdminOrUserWithPermissionReturnsIfUser(): void
9797
{
98-
$this->sspBridgeUtilsAuthMock->expects($this->once())->method('isAdmin')->willReturn(false);
98+
$this->sspBridgeUtilsAuthMock->expects($this->atLeastOnce())->method('isAdmin')
99+
->willReturnOnConsecutiveCalls(
100+
false,
101+
true, // After requireAdmin called, isAdmin will return true
102+
);
103+
$this->sspBridgeUtilsAuthMock->expects($this->once())->method('requireAdmin');
99104
$this->authContextServiceMock->expects($this->once())->method('requirePermission');
100105

101106
$this->sut()->requireAdminOrUserWithPermission('permission');
@@ -104,9 +109,9 @@ public function testRequireAdminOrUserWithPermissionReturnsIfUser(): void
104109
public function testRequireUserWithPermissionThrowsIfUserNotAuthorized(): void
105110
{
106111
$this->expectException(AuthorizationException::class);
107-
$this->expectExceptionMessage('not authorized');
112+
$this->expectExceptionMessage('access required');
108113

109-
$this->sspBridgeUtilsAuthMock->expects($this->once())->method('isAdmin')->willReturn(false);
114+
$this->sspBridgeUtilsAuthMock->expects($this->atLeastOnce())->method('isAdmin')->willReturn(false);
110115
$this->authContextServiceMock->expects($this->once())->method('requirePermission')
111116
->willThrowException(new Exception('error'));
112117

0 commit comments

Comments
 (0)