Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Library can be installed by using Composer:
composer require simplesamlphp/openid
```

## OpenID Federation (draft 42)
## OpenID Federation (draft 43)

The initial functionality of the library revolves around the OpenID Federation specification. To use it, create an
instance of the class `\SimpleSAML\OpenID\Federation`
Expand Down Expand Up @@ -207,8 +207,8 @@ Federation tools expose Trust Mark Fetcher which you can use to dynamically fetc

/** @var \SimpleSAML\OpenID\Federation $federationTools */

// Trust Mark ID that you want to fetch.
$trustMarkId = 'https://example.com/trust-mark/member';
// Trust Mark Type that you want to fetch.
$trustMarkType = 'https://example.com/trust-mark/member';
// ID of Subject for which to fetch the Trust Mark.
$subjectId = 'https://leaf-entity.org'
// ID of the Trust Mark Issuer from which to fetch the Trust Mark.
Expand All @@ -222,7 +222,7 @@ try {

// Fetch the Trust Mark from Issuer.
$trustMarkEntity = $federationTools->trustMarkFetcher()->fromCacheOrFederationTrustMarkEndpoint(
$trustMarkId,
$trustMarkType,
$subjectId,
$trustMarkIssuerConfigurationStatement
);
Expand All @@ -237,7 +237,7 @@ try {
### Validating Trust Marks

Federation tools expose Trust Mark Validator with several methods for validating Trust Marks, with the most common
one being the one to validate Trust Mark for some entity simply based on the Trust Mark ID.
one being the one to validate Trust Mark for some entity simply based on the Trust Mark Type.

If cache is utilized, Trust Mark validation will be cached with cache TTL being the minimum expiration
time of Trust Mark, Leaf Entity Statement or `maxCacheDuration`, whatever is smaller.
Expand All @@ -249,25 +249,25 @@ time of Trust Mark, Leaf Entity Statement or `maxCacheDuration`, whatever is sma
/** @var \SimpleSAML\OpenID\Federation\TrustChain $trustChain */


// Trust Mark ID that you want to validate.
$trustMarkId = 'https://example.com/trust-mark/member';
// Trust Mark Type that you want to validate.
$trustMarkType = 'https://example.com/trust-mark/member';
// Leaf for which you want to validate the Trust Mark with ID above.
$leafEntityConfigurationStatement = $trustChain->getResolvedLeaf();
// Trust Anchor under which you want to validate Trust Mark.
$trustAnchorConfigurationStatement = $trustChain->getResolvedTrustAnchor();

try {
// Example which queries cache for previously validated Trust Mark, and does formal validation if not cached.
$federationTools->trustMarkValidator()->fromCacheOrDoForTrustMarkId(
$trustMarkId,
$federationTools->trustMarkValidator()->fromCacheOrDoForTrustMarkType(
$trustMarkType,
$leafEntityConfigurationStatement,
$trustAnchorConfigurationStatement,
$expectedJwtType = \SimpleSAML\OpenID\Codebooks\JwtTypesEnum::TrustMarkJwt,
);

// Example which always does formal validation (does not use cache).
$federationTools->trustMarkValidator()->doForTrustMarkId(
$trustMarkId,
$federationTools->trustMarkValidator()->doForTrustMarkType(
$trustMarkType,
$leafEntityConfigurationStatement,
$trustAnchorConfigurationStatement,
$expectedJwtType = \SimpleSAML\OpenID\Codebooks\JwtTypesEnum::TrustMarkJwt,
Expand Down
6 changes: 5 additions & 1 deletion src/Codebooks/ClaimsEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ enum ClaimsEnum: string
case Delegation = 'delegation';
case Description = 'description';
case Display = 'display';
case DisplayName = 'display_name';
case EndSessionEndpoint = 'end_session_endpoint';
// ExpirationTime
case Exp = 'exp';
Expand All @@ -65,6 +66,7 @@ enum ClaimsEnum: string
// Identifier
case Id = 'id';
case IdTokenSigningAlgValuesSupported = 'id_token_signing_alg_values_supported';
case InformationUri = 'information_uri';
case IntrospectionEndpoint = 'introspection_endpoint';
case IntrospectionEndpointAuthMethodsSupported = 'introspection_endpoint_auth_methods_supported';
case IntrospectionEndpointAuthSigningAlgValuesSupported =
Expand All @@ -77,6 +79,7 @@ enum ClaimsEnum: string
// JsonWebKeySet
case Jwks = 'jwks';
case JwksUri = 'jwks_uri';
case Keywords = 'keywords';
// KeyId
case Kid = 'kid';
case KeyAttestationsRequired = 'key_attestations_required';
Expand All @@ -98,6 +101,7 @@ enum ClaimsEnum: string
// OpenIDProviderTermsOfServiceUri
case OpTosUri = 'op_tos_uri';
case OrganizationName = 'organization_name';
case OrganizationUri = 'organization_uri';
case Path = 'path';
case PolicyUri = 'policy_uri';
case PostLogoutRedirectUris = 'post_logout_redirect_uris';
Expand Down Expand Up @@ -139,8 +143,8 @@ enum ClaimsEnum: string
case Type = 'type';
case TrustChain = 'trust_chain';
case TrustMark = 'trust_mark';
case TrustMarkId = 'trust_mark_id';
case TrustMarkOwners = 'trust_mark_owners';
case TrustMarkType = 'trust_mark_type';
case TrustMarks = 'trust_marks';
// UserInterfaceLocalesSupported
case UiLocalesSupported = 'ui_locales_supported';
Expand Down
2 changes: 1 addition & 1 deletion src/Codebooks/ParamsEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ enum ParamsEnum: string
case Scope = 'scope';
case State = 'state';
case TrustMarked = 'trust_marked';
case TrustMarkId = 'trust_mark_id';
case TrustMarkType = 'trust_mark_type';
case UiLocales = 'ui_locales';
}
10 changes: 5 additions & 5 deletions src/Federation/Claims/TrustMarkOwnersClaimBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ public function __construct(TrustMarkOwnersClaimValue ...$trustMarkOwnersClaimVa
public function add(TrustMarkOwnersClaimValue ...$trustMarkOwnersClaimValues): void
{
foreach ($trustMarkOwnersClaimValues as $trustMarkOwnersClaimValue) {
$this->trustMarkOwnersClaimValues[$trustMarkOwnersClaimValue->getTrustMarkId()] =
$this->trustMarkOwnersClaimValues[$trustMarkOwnersClaimValue->getTrustMarkType()] =
$trustMarkOwnersClaimValue;
}
}

public function has(string $trustMarkId): bool
public function has(string $trustMarkType): bool
{
return isset($this->trustMarkOwnersClaimValues[$trustMarkId]);
return isset($this->trustMarkOwnersClaimValues[$trustMarkType]);
}

public function get(string $trustMarkId): ?TrustMarkOwnersClaimValue
public function get(string $trustMarkType): ?TrustMarkOwnersClaimValue
{
return $this->trustMarkOwnersClaimValues[$trustMarkId] ?? null;
return $this->trustMarkOwnersClaimValues[$trustMarkType] ?? null;
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/Federation/Claims/TrustMarkOwnersClaimValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
class TrustMarkOwnersClaimValue implements JsonSerializable
{
/**
* @param non-empty-string $trustMarkId
* @param non-empty-string $trustMarkType
* @param non-empty-string $subject
* @param array<non-empty-string,mixed> $otherClaims
*/
public function __construct(
protected readonly string $trustMarkId,
protected readonly string $trustMarkType,
protected readonly string $subject,
protected readonly JwksClaim $jwks,
protected readonly array $otherClaims = [],
Expand All @@ -26,9 +26,9 @@ public function __construct(
/**
* @return non-empty-string
*/
public function getTrustMarkId(): string
public function getTrustMarkType(): string
{
return $this->trustMarkId;
return $this->trustMarkType;
}

/**
Expand Down Expand Up @@ -59,7 +59,7 @@ public function jsonSerialize(): array
{
return array_merge(
[
ClaimsEnum::TrustMarkId->value => $this->trustMarkId,
ClaimsEnum::TrustMarkType->value => $this->trustMarkType,
ClaimsEnum::Sub->value => $this->subject,
ClaimsEnum::Jwks->value => $this->jwks->getValue(),
],
Expand Down
10 changes: 5 additions & 5 deletions src/Federation/Claims/TrustMarksClaimBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@ public function getAll(): array
}

/**
* @param non-empty-string $trustMarkId
* @param non-empty-string $trustMarkType
* @return \SimpleSAML\OpenID\Federation\Claims\TrustMarksClaimValue[]
*/
public function getAllFor(string $trustMarkId): array
public function getAllFor(string $trustMarkType): array
{
return array_values(array_filter(
$this->trustMarksClaimValues,
fn(TrustMarksClaimValue $trustMarkClaim): bool => $trustMarkClaim->getTrustMarkId() === $trustMarkId,
fn(TrustMarksClaimValue $trustMarkClaim): bool => $trustMarkClaim->getTrustMarkType() === $trustMarkType,
));
}

public function getFirstFor(string $trustMarkId): ?TrustMarksClaimValue
public function getFirstFor(string $trustMarkType): ?TrustMarksClaimValue
{
foreach ($this->trustMarksClaimValues as $trustMarkClaim) {
if ($trustMarkClaim->getTrustMarkId() === $trustMarkId) {
if ($trustMarkClaim->getTrustMarkType() === $trustMarkType) {
return $trustMarkClaim;
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/Federation/Claims/TrustMarksClaimValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
class TrustMarksClaimValue implements JsonSerializable
{
/**
* @param non-empty-string $trustMarkId
* @param non-empty-string $trustMarkType
* @param non-empty-string $trustMark
* @param array<non-empty-string,mixed> $otherClaims
*/
public function __construct(
protected readonly string $trustMarkId,
protected readonly string $trustMarkType,
protected readonly string $trustMark,
protected readonly array $otherClaims = [],
) {
Expand All @@ -28,9 +28,9 @@ public function __construct(
/**
* @return non-empty-string
*/
public function getTrustMarkId(): string
public function getTrustMarkType(): string
{
return $this->trustMarkId;
return $this->trustMarkType;
}

/**
Expand All @@ -56,7 +56,7 @@ public function jsonSerialize(): array
{
return array_merge(
[
ClaimsEnum::TrustMarkId->value => $this->trustMarkId,
ClaimsEnum::TrustMarkType->value => $this->trustMarkType,
ClaimsEnum::TrustMark->value => $this->trustMark,
],
$this->otherClaims,
Expand Down
4 changes: 2 additions & 2 deletions src/Federation/EntityStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ public function getTrustMarks(): ?TrustMarksClaimBag
public function getTrustMarkOwners(): ?TrustMarkOwnersClaimBag
{
// trust_mark_owners
// OPTIONAL. It is a JSON object with member names that are Trust Mark identifiers and each
// corresponding value being a JSON object with members: sub, jwks and optionally other members.
// OPTIONAL. It is a JSON object with member names that are Trust Mark Type identifiers, and each
// corresponding value is a JSON object with members: sub, jwks and optionally other members.

$claimKey = ClaimsEnum::TrustMarkOwners->value;
$trustMarkOwnersClaimData = $this->getPayloadClaim($claimKey);
Expand Down
32 changes: 16 additions & 16 deletions src/Federation/Factories/FederationClaimFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ public function __construct(
* @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
*/
public function buildTrustMarksClaimValue(
mixed $trustMarkId,
mixed $trustMarkType,
mixed $trustMark,
mixed $otherClaims = [],
): TrustMarksClaimValue {
$trustMarkId = $this->helpers->type()->ensureNonEmptyString($trustMarkId);
$trustMarkType = $this->helpers->type()->ensureNonEmptyString($trustMarkType);
$trustMark = $this->helpers->type()->ensureNonEmptyString($trustMark);
$otherClaims = $this->helpers->type()->ensureArrayWithKeysAsNonEmptyStrings($otherClaims);

return new TrustMarksClaimValue($trustMarkId, $trustMark, $otherClaims);
return new TrustMarksClaimValue($trustMarkType, $trustMark, $otherClaims);
}

/**
Expand All @@ -47,12 +47,12 @@ public function buildTrustMarksClaimValueFrom(mixed $trustMarksClaimData): Trust
$trustMarksClaimData = $this->helpers->type()->ensureArray($trustMarksClaimData);

// Each JSON object MUST contain the following two claims and MAY contain other claims.
// trust_mark_id
// The Trust Mark identifier. It MUST be the same value as the id claim contained in the Trust Mark JWT.
// trust_mark_type
// The Trust Mark Type identifier. It MUST be the same value as the id claim contained in the Trust Mark JWT.
// trust_mark
// A signed JSON Web Token that represents a Trust Mark.
$trustMarkId = $trustMarksClaimData[ClaimsEnum::TrustMarkId->value] ?? throw new TrustMarkException(
'No ID present in Trust Mark claim.',
$trustMarkType = $trustMarksClaimData[ClaimsEnum::TrustMarkType->value] ?? throw new TrustMarkException(
'No type present in Trust Mark claim.',
);

$trustMark = $trustMarksClaimData[ClaimsEnum::TrustMark->value] ?? throw new TrustMarkException(
Expand All @@ -61,11 +61,11 @@ public function buildTrustMarksClaimValueFrom(mixed $trustMarksClaimData): Trust

$otherClaims = array_diff_key(
$trustMarksClaimData,
[ClaimsEnum::TrustMarkId->value => true, ClaimsEnum::TrustMark->value => true],
[ClaimsEnum::TrustMarkType->value => true, ClaimsEnum::TrustMark->value => true],
);

return $this->buildTrustMarksClaimValue(
$trustMarkId,
$trustMarkType,
$trustMark,
$otherClaims,
);
Expand All @@ -77,18 +77,18 @@ public function buildTrustMarksClaimBag(TrustMarksClaimValue ...$trustMarksClaim
}

public function buildTrustMarkOwnersClaimValue(
mixed $trustMarkId,
mixed $trustMarkType,
mixed $subject,
mixed $jwks,
mixed $otherClaims = [],
): TrustMarkOwnersClaimValue {
$trustMarkId = $this->helpers->type()->ensureNonEmptyString($trustMarkId);
$trustMarkType = $this->helpers->type()->ensureNonEmptyString($trustMarkType);
$subject = $this->helpers->type()->ensureNonEmptyString($subject);
$jwksClaim = $this->claimFactory->buildJwks($jwks);
$otherClaims = $this->helpers->type()->ensureArrayWithKeysAsNonEmptyStrings($otherClaims);

return new TrustMarkOwnersClaimValue(
$trustMarkId,
$trustMarkType,
$subject,
$jwksClaim,
$otherClaims,
Expand All @@ -105,7 +105,7 @@ public function buildTrustMarkOwnersClaimBagFrom(mixed $trustMarkOwnersClaimData

$trustMarkOwnersClaimValues = [];

// It is a JSON object with member names that are Trust Mark identifiers and each corresponding value
// It is a JSON object with member names that are Trust Mark Type identifiers and each corresponding value
// being a JSON object with these members:
// sub
// REQUIRED Identifier of the Trust Mark Owner.
Expand All @@ -114,7 +114,7 @@ public function buildTrustMarkOwnersClaimBagFrom(mixed $trustMarkOwnersClaimData
// for signing.
// Other members MAY also be defined and used.

foreach ($trustMarkOwnersClaimData as $trustMarkId => $trustMarkOwnersClaim) {
foreach ($trustMarkOwnersClaimData as $trustMarkType => $trustMarkOwnersClaim) {
$trustMarkOwnersClaim = $this->helpers->type()->ensureArray($trustMarkOwnersClaim);


Expand All @@ -127,11 +127,11 @@ public function buildTrustMarkOwnersClaimBagFrom(mixed $trustMarkOwnersClaimData

$otherClaims = array_diff_key(
$trustMarkOwnersClaim,
[ClaimsEnum::TrustMarkId->value => true, ClaimsEnum::TrustMark->value => true],
[ClaimsEnum::TrustMarkType->value => true, ClaimsEnum::TrustMark->value => true],
);

$trustMarkOwnersClaimValues[] = $this->buildTrustMarkOwnersClaimValue(
$trustMarkId,
$trustMarkType,
$subject,
$jwks,
$otherClaims,
Expand Down
12 changes: 6 additions & 6 deletions src/Federation/TrustMark.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ public function getSubject(): string
* @return non-empty-string
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
*/
public function getTrustMarkId(): string
public function getTrustMarkType(): string
{
$claimKey = ClaimsEnum::TrustMarkId->value;
$claimKey = ClaimsEnum::TrustMarkType->value;

$trustMarkId = $this->getPayloadClaim($claimKey) ?? throw new TrustMarkException(
'No Trust Mark ID claim found.',
$trustMarkType = $this->getPayloadClaim($claimKey) ?? throw new TrustMarkException(
'No Trust Mark Type claim found.',
);

return $this->helpers->type()->ensureNonEmptyString($trustMarkId);
return $this->helpers->type()->ensureNonEmptyString($trustMarkType);
}

/**
Expand Down Expand Up @@ -164,7 +164,7 @@ protected function validate(): void
$this->validateByCallbacks(
$this->getIssuer(...),
$this->getSubject(...),
$this->getTrustMarkId(...),
$this->getTrustMarkType(...),
$this->getIssuedAt(...),
$this->getLogoUri(...),
$this->getExpirationTime(...),
Expand Down
Loading