Skip to content

Commit 1810b36

Browse files
committed
Enable TrustMarks listing in entity configuration
1 parent 8d8849a commit 1810b36

File tree

4 files changed

+64
-24
lines changed

4 files changed

+64
-24
lines changed

config-templates/module_oidc.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@
355355
//'https://intermediate.example.org/',
356356
],
357357

358+
// (optional) Federation Trust Mark tokens. An array of tokens (signed JWTs), each representing a Trust Mark
359+
// issued to this entity.
360+
ModuleConfig::OPTION_FEDERATION_TRUST_MARK_TOKENS => [
361+
// 'eyJ...GHg',
362+
],
363+
358364
// (optional) Dedicated federation cache adapter, used to cache federation artifacts like trust chains, entity
359365
// statements, etc. It will also be used for token reuse check in federation context. Setting this option is
360366
// recommended in production environments. If set to null, no caching will be used. Can be set to any

src/Controller/Federation/EntityStatementController.php

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use SimpleSAML\OpenID\Codebooks\ErrorsEnum;
2121
use SimpleSAML\OpenID\Codebooks\HttpHeadersEnum;
2222
use SimpleSAML\OpenID\Codebooks\JwtTypesEnum;
23+
use SimpleSAML\OpenID\Federation;
2324
use Symfony\Component\HttpFoundation\JsonResponse;
2425
use Symfony\Component\HttpFoundation\Request;
2526
use Symfony\Component\HttpFoundation\Response;
@@ -39,6 +40,7 @@ public function __construct(
3940
private readonly OpMetadataService $opMetadataService,
4041
private readonly ClientRepository $clientRepository,
4142
private readonly Helpers $helpers,
43+
private readonly Federation $federation,
4244
private readonly ?FederationCache $federationCache,
4345
) {
4446
if (!$this->moduleConfig->getFederationEnabled()) {
@@ -52,6 +54,8 @@ public function __construct(
5254
* @return \Symfony\Component\HttpFoundation\Response
5355
* @throws \SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException
5456
* @throws \ReflectionException
57+
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
58+
* @throws \Psr\SimpleCache\InvalidArgumentException
5559
*/
5660
public function configuration(): Response
5761
{
@@ -121,14 +125,32 @@ public function configuration(): Response
121125
$builder = $builder->withClaim(ClaimsEnum::AuthorityHints->value, $authorityHints);
122126
}
123127

128+
if (
129+
is_array($trustMarkTokens = $this->moduleConfig->getFederationTrustMarkTokens()) &&
130+
(!empty($trustMarkTokens))
131+
) {
132+
$trustMarks = array_map(function (string $token): array {
133+
$trustMarkEntity = $this->federation->trustMarkFactory()->fromToken($token);
134+
135+
if ($trustMarkEntity->getSubject() !== $this->moduleConfig->getIssuer()) {
136+
throw OidcServerException::serverError(sprintf(
137+
'Trust Mark %s is not intended for this entity.',
138+
$trustMarkEntity->getIdentifier(),
139+
));
140+
}
141+
142+
return [
143+
ClaimsEnum::Id->value => $trustMarkEntity->getIdentifier(),
144+
ClaimsEnum::TrustMark->value => $token,
145+
];
146+
}, $trustMarkTokens);
147+
148+
$builder = $builder->withClaim(ClaimsEnum::TrustMarks->value, $trustMarks);
149+
}
150+
151+
// TODO mivanci Continue
124152
// Remaining claims, add if / when ready.
125153
// * crit
126-
// * trust_marks
127-
// * trust_mark_issuers
128-
// * source_endpoint
129-
130-
// Note: claims which should only be present in Trust Anchors
131-
// * trust_mark_owners
132154

133155
$jws = $this->jsonWebTokenBuilderService->getSignedFederationJwt($builder);
134156

@@ -219,6 +241,7 @@ public function fetch(Request $request): Response
219241
],
220242
);
221243

244+
// TODO mivanci Continue
222245
// Note: claims which can be present in subordinate statements:
223246
// * metadata_policy
224247
// * constraints

src/Controller/Federation/Test.php

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,31 +68,31 @@ public function __invoke(): Response
6868
$trustChain = $this->federation
6969
->trustChainResolver()
7070
->for(
71-
// 'https://08-dap.localhost.markoivancic.from.hr/openid/entities/ALeaf/',
71+
'https://08-dap.localhost.markoivancic.from.hr/openid/entities/ALeaf/',
7272
// 'https://trust-anchor.testbed.oidcfed.incubator.geant.org/oidc/rp/',
7373
// 'https://relying-party-php.testbed.oidcfed.incubator.geant.org/',
74-
'https://gorp.testbed.oidcfed.incubator.geant.org',
74+
// 'https://gorp.testbed.oidcfed.incubator.geant.org',
7575
// 'https://maiv1.incubator.geant.org',
7676
[
77-
'https://trust-anchor.testbed.oidcfed.incubator.geant.org/',
78-
// 'https://08-dap.localhost.markoivancic.from.hr/openid/entities/ABTrustAnchor/',
77+
// 'https://trust-anchor.testbed.oidcfed.incubator.geant.org/',
78+
'https://08-dap.localhost.markoivancic.from.hr/openid/entities/ABTrustAnchor/',
7979
// 'https://08-dap.localhost.markoivancic.from.hr/openid/entities/CTrustAnchor/',
8080
],
8181
);
8282

8383
$leaf = $trustChain->getResolvedLeaf();
84-
dd($leaf);
85-
// $leafFederationJwks = $leaf->getJwks();
84+
// dd($leaf);
85+
$leafFederationJwks = $leaf->getJwks();
8686
// dd($leafFederationJwks);
87-
/** @psalm-suppress PossiblyNullArgument */
88-
// $resolvedMetadata = $trustChain->getResolvedMetadata(EntityTypesEnum::OpenIdRelyingParty);
89-
// $clientEntity = $this->clientEntityFactory->fromRegistrationData(
90-
// $resolvedMetadata,
91-
// RegistrationTypeEnum::FederatedAutomatic,
92-
// );
87+
// /** @psalm-suppress PossiblyNullArgument */
88+
$resolvedMetadata = $trustChain->getResolvedMetadata(EntityTypesEnum::OpenIdRelyingParty);
89+
$clientEntity = $this->clientEntityFactory->fromRegistrationData(
90+
$resolvedMetadata,
91+
RegistrationTypeEnum::FederatedAutomatic,
92+
);
9393
// dd($resolvedMetadata, $clientEntity);
94-
// $jwksUri = $resolvedMetadata['jwks_uri'] ?? null;
95-
// $signedJwksUri = $resolvedMetadata['signed_jwks_uri'] ?? null;
94+
$jwksUri = $resolvedMetadata['jwks_uri'] ?? null;
95+
$signedJwksUri = $resolvedMetadata['signed_jwks_uri'] ?? null;
9696
// dd($leaf, $leafFederationJwks, $resolvedMetadata, $jwksUri, $signedJwksUri);
9797
// $cachedJwks = $jwksUri ? $this->jwks->jwksFetcher()->fromCache($jwksUri) : null;
9898
// $jwks = $jwksUri ? $this->jwks->jwksFetcher()->fromJwksUri($jwksUri) : null;
@@ -112,10 +112,10 @@ public function __invoke(): Response
112112
// ],
113113
//];
114114
// $signedJwksUri = 'https://08-dap.localhost.markoivancic.from.hr/openid/entities/ALeaf/signed-jwks';
115-
// $signedJwks = $signedJwksUri ? $this->jwks->jwksFetcher()
116-
// ->fromSignedJwksUri($signedJwksUri, $leafFederationJwks) : null;
117-
// $cachedSignedJwks = $signedJwksUri ? $this->jwks->jwksFetcher()->fromCache($signedJwksUri) : null;
118-
// dd($signedJwksUri, $cachedSignedJwks, $signedJwks);
115+
$signedJwks = $signedJwksUri ? $this->jwks->jwksFetcher()
116+
->fromSignedJwksUri($signedJwksUri, $leafFederationJwks) : null;
117+
$cachedSignedJwks = $signedJwksUri ? $this->jwks->jwksFetcher()->fromCache($signedJwksUri) : null;
118+
dd($signedJwksUri, $cachedSignedJwks, $signedJwks);
119119
// dd(
120120
// $signedJwksUri,
121121
// $cachedSignedJwks,

src/ModuleConfig.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class ModuleConfig
7676
final public const OPTION_FEDERATION_CACHE_ADAPTER_ARGUMENTS = 'federation_cache_adapter_arguments';
7777
final public const OPTION_FEDERATION_CACHE_MAX_DURATION = 'federation_cache_max_duration';
7878
final public const OPTION_FEDERATION_TRUST_ANCHORS = 'federation_trust_anchors';
79+
final public const OPTION_FEDERATION_TRUST_MARK_TOKENS = 'federation_trust_mark_tokens';
7980
final public const OPTION_FEDERATION_ENTITY_STATEMENT_CACHE_DURATION = 'federation_entity_statement_cache_duration';
8081
final public const OPTION_PROTOCOL_CACHE_ADAPTER = 'protocol_cache_adapter';
8182
final public const OPTION_PROTOCOL_CACHE_ADAPTER_ARGUMENTS = 'protocol_cache_adapter_arguments';
@@ -478,6 +479,16 @@ public function getFederationAuthorityHints(): ?array
478479
return empty($authorityHints) ? null : $authorityHints;
479480
}
480481

482+
public function getFederationTrustMarkTokens(): ?array
483+
{
484+
$trustMarks = $this->config()->getOptionalArray(
485+
self::OPTION_FEDERATION_TRUST_MARK_TOKENS,
486+
null,
487+
);
488+
489+
return empty($trustMarks) ? null : $trustMarks;
490+
}
491+
481492
public function getOrganizationName(): ?string
482493
{
483494
return $this->config()->getOptionalString(

0 commit comments

Comments
 (0)