Skip to content

Commit b2282ff

Browse files
committed
WIP
1 parent 0598490 commit b2282ff

File tree

8 files changed

+176
-6
lines changed

8 files changed

+176
-6
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ The module offers an OpenID Federation configuration endpoint at URL:
367367

368368
You can configure your web server (Apache, Nginx) in a way to serve the mentioned URLs in a '.well-known'
369369
format. Below are some sample configurations for `openid-configuration`, but you can take the same approach for
370-
`openid-federation`.
370+
`openid-federation`, `jwt-vc-issuer`, or any other.
371371

372372
#### nginx
373373
location = /.well-known/openid-configuration {
@@ -382,9 +382,9 @@ format. Below are some sample configurations for `openid-configuration`, but you
382382

383383
## Using Docker
384384

385-
### With current git branch.
385+
### With the current git branch.
386386

387-
To explore the module using docker run the below command. This will run an SSP image, with the current oidc module
387+
To explore the module using docker, run the below command. This will run an SSP image, with the current oidc module
388388
mounted in the container, along with some configuration files. Any code changes you make to your git checkout are
389389
"live" in the container, allowing you to test and iterate different things.
390390

config/module_oidc.php.dist

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ $config = [
514514
// https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#credential-issuer-parameters.
515515
// Check the example below on how this can be used.
516516
ModuleConfig::OPTION_CREDENTIAL_CONFIGURATIONS_SUPPORTED => [
517+
// Sample for 'jwt_vc_json' format with notes about required and optional fields.
517518
'ResearchAndScholarshipCredentialJwtVcJson' => [
518519
// REQUIRED
519520
ClaimsEnum::Format->value => CredentialFormatIdentifiersEnum::JwtVcJson->value,
@@ -529,6 +530,9 @@ $config = [
529530
// OPTIONAL
530531
// proof_types_supported
531532

533+
// OPTIONAL
534+
// cryptographic_binding_methods_supported
535+
532536
ClaimsEnum::Display->value => [
533537
[
534538
ClaimsEnum::Name->value => 'ResearchAndScholarshipCredentialJwtVcJson',
@@ -588,8 +592,7 @@ $config = [
588592
*/
589593
[
590594
// REQUIRED
591-
ClaimsEnum::Path->value => [ClaimsEnum::Credential_Subject->value, 'eduPersonPrincipalName']
592-
],
595+
ClaimsEnum::Path->value => [ClaimsEnum::Credential_Subject->value, 'eduPersonPrincipalName'],
593596
// OPTIONAL
594597
ClaimsEnum::Mandatory->value => true,
595598
// OPTIONAL
@@ -668,6 +671,92 @@ $config = [
668671
'ResearchAndScholarshipCredentialJwtVcJson',
669672
],
670673
],
674+
],
675+
676+
// Sample for 'dc+sd-jwt' format without notes about required and optional fields.
677+
'ResearchAndScholarshipCredentialDcSdJwt' => [
678+
ClaimsEnum::Format->value => CredentialFormatIdentifiersEnum::JwtVcJson->value,
679+
ClaimsEnum::Scope->value => 'ResearchAndScholarshipCredentialDcSdJwt',
680+
ClaimsEnum::Display->value => [
681+
[
682+
ClaimsEnum::Name->value => 'ResearchAndScholarshipCredentialDcSdJwt',
683+
ClaimsEnum::Locale->value => 'en-US',
684+
ClaimsEnum::Description->value => 'Research and Scholarship Credential',
685+
],
686+
],
687+
ClaimsEnum::Claims->value => [
688+
[
689+
ClaimsEnum::Path->value => ['eduPersonPrincipalName'],
690+
ClaimsEnum::Mandatory->value => true,
691+
ClaimsEnum::Display->value => [
692+
[
693+
ClaimsEnum::Name->value => 'Principal Name',
694+
ClaimsEnum::Locale->value => LanguageTagsEnum::EnUs->value,
695+
],
696+
],
697+
],
698+
[
699+
ClaimsEnum::Path->value => ['eduPersonTargetedID'],
700+
ClaimsEnum::Mandatory->value => false,
701+
ClaimsEnum::Display->value => [
702+
[
703+
ClaimsEnum::Name->value => 'Targeted ID',
704+
ClaimsEnum::Locale->value => LanguageTagsEnum::EnUs->value,
705+
],
706+
],
707+
],
708+
[
709+
ClaimsEnum::Path->value => ['displayName'],
710+
ClaimsEnum::Mandatory->value => false,
711+
ClaimsEnum::Display->value => [
712+
[
713+
ClaimsEnum::Name->value => 'Display Name',
714+
ClaimsEnum::Locale->value => LanguageTagsEnum::EnUs->value,
715+
],
716+
],
717+
],
718+
[
719+
ClaimsEnum::Path->value => ['givenName'],
720+
ClaimsEnum::Mandatory->value => false,
721+
ClaimsEnum::Display->value => [
722+
[
723+
ClaimsEnum::Name->value => 'Given Name',
724+
ClaimsEnum::Locale->value => LanguageTagsEnum::EnUs->value,
725+
],
726+
],
727+
],
728+
[
729+
ClaimsEnum::Path->value => ['sn'],
730+
ClaimsEnum::Display->value => [
731+
[
732+
ClaimsEnum::Name->value => 'Last Name',
733+
ClaimsEnum::Locale->value => LanguageTagsEnum::EnUs->value,
734+
],
735+
],
736+
],
737+
[
738+
ClaimsEnum::Path->value => ['mail'],
739+
ClaimsEnum::Display->value => [
740+
[
741+
ClaimsEnum::Name->value => 'Email Address',
742+
ClaimsEnum::Locale->value => LanguageTagsEnum::EnUs->value,
743+
],
744+
],
745+
],
746+
[
747+
ClaimsEnum::Path->value => ['eduPersonScopedAffiliation'],
748+
ClaimsEnum::Display->value => [
749+
[
750+
ClaimsEnum::Name->value => 'Scoped Affiliation',
751+
ClaimsEnum::Locale->value => LanguageTagsEnum::EnUs->value,
752+
],
753+
],
754+
],
755+
],
756+
757+
// REQUIRED
758+
ClaimsEnum::Vct->value => 'ResearchAndScholarshipCredentialDcSdJwt',
759+
],
671760
],
672761

673762
// Mapping of user attributes to a credential claim path, per credential configuration ID.
@@ -689,5 +778,8 @@ $config = [
689778
['mail' => [ClaimsEnum::Credential_Subject->value, 'mail']],
690779
['eduPersonScopedAffiliation' => [ClaimsEnum::Credential_Subject->value, 'eduPersonScopedAffiliation']],
691780
],
781+
'ResearchAndScholarshipCredentialDcSdJwt' => [
782+
783+
],
692784
],
693785
];

docker/apache-override.cf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
RewriteEngine On
22
RewriteRule ^/.well-known/openid-configuration(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-configuration$1 [PT]
33
RewriteRule ^/.well-known/openid-federation(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-federation$1 [PT]
4+
RewriteRule ^/.well-known/openid-credential-issuer(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-credential-issuer$1 [PT]
5+
RewriteRule ^/.well-known/oauth-authorization-server(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/oauth-authorization-server$1 [PT]
6+
RewriteRule ^/.well-known/jwt-vc-issuer(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/jwt-vc-issuer$1 [PT]
47

58
# Leave Authorization header with Bearer tokens available in requests.
69
# Solution 1:

routing/routes/routes.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use SimpleSAML\Module\oidc\Controllers\UserInfoController;
2323
use SimpleSAML\Module\oidc\Controllers\VerifiableCredentials\CredentialIssuerConfigurationController;
2424
use SimpleSAML\Module\oidc\Controllers\VerifiableCredentials\CredentialIssuerCredentialController;
25+
use SimpleSAML\Module\oidc\Controllers\VerifiableCredentials\JwtVcIssuerConfigurationController;
2526
use SimpleSAML\OpenID\Codebooks\HttpMethodsEnum;
2627
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
2728

@@ -131,4 +132,12 @@
131132
$routes->add(RoutesEnum::CredentialIssuerCredential->name, RoutesEnum::CredentialIssuerCredential->value)
132133
->controller([CredentialIssuerCredentialController::class, 'credential'])
133134
->methods([HttpMethodsEnum::GET->value, HttpMethodsEnum::POST->value]);
135+
136+
/*****************************************************************************************************************
137+
* SD-JWT-based Verifiable Credentials (SD-JWT VC)
138+
****************************************************************************************************************/
139+
140+
$routes->add(RoutesEnum::JwtVcIssuerConfiguration->name, RoutesEnum::JwtVcIssuerConfiguration->value)
141+
->controller([JwtVcIssuerConfigurationController::class, 'configuration'])
142+
->methods([HttpMethodsEnum::GET->value]);
134143
};

src/Codebooks/RoutesEnum.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,10 @@ enum RoutesEnum: string
6363

6464
case CredentialIssuerConfiguration = '.well-known/openid-credential-issuer';
6565
case CredentialIssuerCredential = 'credential-issuer/credential';
66+
67+
/*****************************************************************************************************************
68+
* SD-JWT-based Verifiable Credentials (SD-JWT VC)
69+
****************************************************************************************************************/
70+
71+
case JwtVcIssuerConfiguration = '.well-known/jwt-vc-issuer';
6672
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* |
7+
* \ ___ / _________
8+
* _ / \ _ GÉANT | * * | Co-Funded by
9+
* | ~ | Trust & Identity | * * | the European
10+
* \_/ Incubator |__*_*__| Union
11+
* =
12+
*/
13+
14+
namespace SimpleSAML\Module\oidc\Controllers\VerifiableCredentials;
15+
16+
use SimpleSAML\Module\oidc\Codebooks\RoutesEnum;
17+
use SimpleSAML\Module\oidc\ModuleConfig;
18+
use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException;
19+
use SimpleSAML\Module\oidc\Utils\Routes;
20+
use SimpleSAML\OpenID\Codebooks\ClaimsEnum;
21+
use Symfony\Component\HttpFoundation\Response;
22+
23+
class JwtVcIssuerConfigurationController
24+
{
25+
/**
26+
* @throws \SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException
27+
*/
28+
public function __construct(
29+
protected readonly ModuleConfig $moduleConfig,
30+
protected readonly Routes $routes,
31+
) {
32+
if (!$this->moduleConfig->getVerifiableCredentialEnabled()) {
33+
throw OidcServerException::forbidden('Verifiable Credential capabilities not enabled');
34+
}
35+
}
36+
37+
public function configuration(): Response
38+
{
39+
$configuration = [
40+
ClaimsEnum::Issuer->value => $this->moduleConfig->getIssuer(),
41+
ClaimsEnum::JwksUri->value => $this->moduleConfig->getModuleUrl(RoutesEnum::Jwks->value),
42+
];
43+
44+
return $this->routes->newJsonResponse($configuration);
45+
}
46+
}

src/Utils/Routes.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,4 +226,14 @@ public function urlCredentialIssuerCredential(array $parameters = []): string
226226
{
227227
return $this->getModuleUrl(RoutesEnum::CredentialIssuerCredential->value, $parameters);
228228
}
229+
230+
/*****************************************************************************************************************
231+
* SD-JWT-based Verifiable Credentials (SD-JWT VC)
232+
****************************************************************************************************************/
233+
234+
public function urlJwtVcIssuerConfiguration(array $parameters = []): string
235+
{
236+
return $this->getModuleUrl(RoutesEnum::JwtVcIssuerConfiguration->value, $parameters);
237+
}
238+
229239
}

templates/config/verifiable-credential.twig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010

1111
<h4>{{ 'Entity'|trans }}</h4>
1212
<p>
13-
{{ 'Configuration URL'|trans }}:
13+
{{ 'Credential Issuer Configuration URL'|trans }}:
1414
<a href="{{ routes.urlCredentialIssuerConfiguration }}" target="_blank">{{ routes.urlCredentialIssuerConfiguration }}</a>
1515
</p>
16+
<p>
17+
{{ 'JWT VC Issuer Configuration URL'|trans }}:
18+
<a href="{{ routes.urlJwtVcIssuerConfiguration }}" target="_blank">{{ routes.urlJwtVcIssuerConfiguration }}</a>
19+
</p>
1620
<p>
1721
{{ 'Issuer'|trans }}: {{ moduleConfig.getIssuer }}
1822
</p>

0 commit comments

Comments
 (0)