001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.openid.connect.sdk.federation.entities; 019 020 021import java.util.Date; 022import java.util.LinkedList; 023import java.util.List; 024 025import net.minidev.json.JSONObject; 026 027import com.nimbusds.jose.jwk.JWKSet; 028import com.nimbusds.jwt.JWTClaimsSet; 029import com.nimbusds.oauth2.sdk.ParseException; 030import com.nimbusds.oauth2.sdk.as.AuthorizationServerMetadata; 031import com.nimbusds.oauth2.sdk.client.ClientMetadata; 032import com.nimbusds.oauth2.sdk.id.Identifier; 033import com.nimbusds.oauth2.sdk.id.Issuer; 034import com.nimbusds.oauth2.sdk.id.Subject; 035import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 036import com.nimbusds.oauth2.sdk.util.MapUtils; 037import com.nimbusds.openid.connect.sdk.claims.CommonClaimsSet; 038import com.nimbusds.openid.connect.sdk.federation.policy.MetadataPolicy; 039import com.nimbusds.openid.connect.sdk.federation.policy.language.PolicyViolationException; 040import com.nimbusds.openid.connect.sdk.federation.trust.constraints.TrustChainConstraints; 041import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata; 042import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata; 043 044 045/** 046 * Federation entity statement claims set, serialisable to a JSON object. 047 * 048 * <p>Example claims set: 049 * 050 * <pre> 051 * { 052 * "iss": "https://feide.no", 053 * "sub": "https://ntnu.no", 054 * "iat": 1516239022, 055 * "exp": 1516298022, 056 * "crit": ["jti"], 057 * "jti": "7l2lncFdY6SlhNia", 058 * "policy_language_crit": ["regexp"], 059 * "metadata_policy": { 060 * "openid_provider": { 061 * "issuer": {"value": "https://ntnu.no"}, 062 * "organization_name": {"value": "NTNU"}, 063 * "id_token_signing_alg_values_supported": 064 * {"subset_of": ["RS256", "RS384", "RS512"]}, 065 * "op_policy_uri": { 066 * "regexp": "^https:\/\/[\w-]+\.example\.com\/[\w-]+\.html"} 067 * }, 068 * "openid_relying_party": { 069 * "organization_name": {"value": "NTNU"}, 070 * "grant_types_supported": { 071 * "subset_of": ["authorization_code", "implicit"]}, 072 * "scopes": { 073 * "subset_of": ["openid", "profile", "email", "phone"]} 074 * } 075 * }, 076 * "constraints": { 077 * "max_path_length": 2 078 * } 079 * "jwks": { 080 * "keys": [ 081 * { 082 * "alg": "RS256", 083 * "e": "AQAB", 084 * "ext": true, 085 * "key_ops": ["verify"], 086 * "kid": "key1", 087 * "kty": "RSA", 088 * "n": "pnXBOusEANuug6ewezb9J_...", 089 * "use": "sig" 090 * } 091 * ] 092 * }, 093 * "authority_hints": [ 094 * "https://edugain.org/federation" 095 * ] 096 * } 097 * </pre> 098 * 099 * <p>Related specifications: 100 * 101 * <ul> 102 * <li>OpenID Connect Federation 1.0, section 2.1. 103 * </ul> 104 */ 105public class EntityStatementClaimsSet extends CommonClaimsSet { 106 107 108 /** 109 * The expiration time claim name. 110 */ 111 public static final String EXP_CLAIM_NAME = "exp"; 112 113 114 /** 115 * The JWK set claim name. 116 */ 117 public static final String JWKS_CLAIM_NAME = "jwks"; 118 119 120 /** 121 * The authority hints claim name. 122 */ 123 public static final String AUTHORITY_HINTS_CLAIM_NAME = "authority_hints"; 124 125 126 /** 127 * The metadata claim name. 128 */ 129 public static final String METADATA_CLAIM_NAME = "metadata"; 130 131 132 /** 133 * The metadata policy claim name. 134 */ 135 public static final String METADATA_POLICY_CLAIM_NAME = "metadata_policy"; 136 137 138 /** 139 * The assumed trust anchor in a explicit client registration. Intended 140 * for entity statements issued by an OP for RP performing explicit 141 * client registration only. 142 */ 143 public static final String TRUST_ANCHOR_ID_CLAIM_NAME = "trust_anchor_id"; 144 145 146 /** 147 * The constraints claim name. 148 */ 149 public static final String CONSTRAINTS_CLAIM_NAME = "constraints"; 150 151 152 /** 153 * The critical claim name. 154 */ 155 public static final String CRITICAL_CLAIM_NAME = "crit"; 156 157 158 /** 159 * The policy critical claim name. 160 */ 161 public static final String POLICY_LANGUAGE_CRITICAL_CLAIM_NAME = "policy_language_crit"; 162 163 164 /** 165 * Creates a new federation entity statement claims set with the 166 * minimum required claims. 167 * 168 * @param iss The issuer. Must not be {@code null}. 169 * @param sub The subject. Must not be {@code null}. 170 * @param iat The issue time. Must not be {@code null}. 171 * @param exp The expiration time. Must not be {@code null}. 172 * @param jwks The entity public JWK set, {@code null} if not required. 173 */ 174 public EntityStatementClaimsSet(final Issuer iss, 175 final Subject sub, 176 final Date iat, 177 final Date exp, 178 final JWKSet jwks) { 179 180 this(new EntityID(iss.getValue()), new EntityID(sub.getValue()), iat, exp, jwks); 181 } 182 183 184 /** 185 * Creates a new federation entity statement claims set with the 186 * minimum required claims. 187 * 188 * @param iss The issuer. Must not be {@code null}. 189 * @param sub The subject. Must not be {@code null}. 190 * @param iat The issue time. Must not be {@code null}. 191 * @param exp The expiration time. Must not be {@code null}. 192 * @param jwks The entity public JWK set, {@code null} if not required. 193 */ 194 public EntityStatementClaimsSet(final EntityID iss, 195 final EntityID sub, 196 final Date iat, 197 final Date exp, 198 final JWKSet jwks) { 199 200 setClaim(ISS_CLAIM_NAME, iss.getValue()); 201 setClaim(SUB_CLAIM_NAME, sub.getValue()); 202 setDateClaim(IAT_CLAIM_NAME, iat); 203 setDateClaim(EXP_CLAIM_NAME, exp); 204 if (jwks != null) { 205 setClaim(JWKS_CLAIM_NAME, new JSONObject(jwks.toJSONObject(true))); // public JWKs only 206 } 207 } 208 209 210 /** 211 * Creates a new federation entity statement claims set from the 212 * specified JWT claims set. 213 * 214 * @param jwtClaimsSet The JWT claims set. Must not be {@code null}. 215 * 216 * @throws ParseException If the JWT claims set doesn't represent a 217 * valid federation entity statement claims set. 218 */ 219 public EntityStatementClaimsSet(final JWTClaimsSet jwtClaimsSet) 220 throws ParseException { 221 222 super(JSONObjectUtils.toJSONObject(jwtClaimsSet)); 223 224 validateRequiredClaimsPresence(); 225 } 226 227 228 /** 229 * Validates this claims set for having all minimum required claims for 230 * an entity statement. If a {@link #isSelfStatement() selt-statement} 231 * check for the {@link #hasMetadata() presence of metadata}. If 232 * {@link #getCriticalExtensionClaims() critical extension claims} are 233 * listed their presence is also checked. 234 * 235 * @throws ParseException If the validation failed and a required claim 236 * is missing. 237 */ 238 public void validateRequiredClaimsPresence() 239 throws ParseException { 240 241 if (getIssuer() == null) { 242 throw new ParseException("Missing iss (issuer) claim"); 243 } 244 245 EntityID.parse(getIssuer()); // ensure URI 246 247 if (getSubject() == null) { 248 throw new ParseException("Missing sub (subject) claim"); 249 } 250 251 EntityID.parse(getSubject()); // ensure URI 252 253 if (getIssueTime() == null) { 254 throw new ParseException("Missing iat (issued-at) claim"); 255 } 256 257 if (getExpirationTime() == null) { 258 throw new ParseException("Missing exp (expiration) claim"); 259 } 260 261 // jwks always required for self-statements 262 if (isSelfStatement() && getJWKSet() == null) { 263 throw new ParseException("Missing jwks (JWK set) claim"); 264 } 265 266 if (isSelfStatement() && ! hasMetadata()) { 267 throw new ParseException("Missing required metadata claim for self-statement"); 268 } 269 270 List<String> crit = getCriticalExtensionClaims(); 271 272 if (crit != null) { 273 for (String claimName: crit) { 274 if (getClaim(claimName) == null) { 275 throw new ParseException("Missing critical " + claimName + " claim"); 276 } 277 } 278 } 279 } 280 281 282 /** 283 * Returns {@code true} if this is a self-statement (issuer and subject 284 * match). 285 * 286 * @return {@code true} for a self-statement, {@code false} if not. 287 */ 288 public boolean isSelfStatement() { 289 290 Issuer issuer = getIssuer(); 291 Subject subject = getSubject(); 292 293 return issuer != null && subject != null && issuer.getValue().equals(subject.getValue()); 294 } 295 296 297 /** 298 * Returns the issuer as entity ID. 299 * 300 * @return The issuer as entity ID. 301 */ 302 public EntityID getIssuerEntityID() { 303 304 return new EntityID(getIssuer().getValue()); 305 } 306 307 308 /** 309 * Returns the subject as entity ID. 310 * 311 * @return The subject as entity ID. 312 */ 313 public EntityID getSubjectEntityID() { 314 315 return new EntityID(getSubject().getValue()); 316 } 317 318 319 /** 320 * Gets the entity statement expiration time. Corresponds to the 321 * {@code exp} claim. 322 * 323 * @return The expiration time, {@code null} if not specified or 324 * parsing failed. 325 */ 326 public Date getExpirationTime() { 327 328 return getDateClaim(EXP_CLAIM_NAME); 329 } 330 331 332 /** 333 * Gets the entity JWK set. 334 * 335 * @return The entity JWK set, {@code null} if not specified or parsing 336 * failed. 337 */ 338 public JWKSet getJWKSet() { 339 340 JSONObject jwkSetJSONObject = getJSONObjectClaim(JWKS_CLAIM_NAME); 341 if (jwkSetJSONObject == null) { 342 return null; 343 } 344 try { 345 return JWKSet.parse(jwkSetJSONObject); 346 } catch (java.text.ParseException e) { 347 return null; 348 } 349 } 350 351 352 /** 353 * Gets the entity IDs of the intermediate entities or trust anchors. 354 * 355 * @return The entity IDs, {@code null} or empty list for a trust 356 * anchor, or if parsing failed. 357 */ 358 public List<EntityID> getAuthorityHints() { 359 360 List<String> strings = getStringListClaim(AUTHORITY_HINTS_CLAIM_NAME); 361 362 if (strings == null) { 363 return null; 364 } 365 366 List<EntityID> trustChain = new LinkedList<>(); 367 for (String s: strings) { 368 trustChain.add(new EntityID(s)); 369 } 370 return trustChain; 371 } 372 373 374 /** 375 * Sets the entity IDs of the intermediate entities or trust anchors. 376 * 377 * @param trustChain The entity IDs, {@code null} or empty list for a 378 * trust anchor. 379 */ 380 public void setAuthorityHints(final List<EntityID> trustChain) { 381 382 if (trustChain != null) { 383 setClaim(AUTHORITY_HINTS_CLAIM_NAME, Identifier.toStringList(trustChain)); 384 } else { 385 setClaim(AUTHORITY_HINTS_CLAIM_NAME, null); 386 } 387 } 388 389 390 /** 391 * Returns {@code true} if a metadata field is present. 392 * 393 * @return {@code true} if for a metadata field for an OpenID relying 394 * party, OpenID provider, OAuth authorisation server, OAuth 395 * client, OAuth protected resource or a federation entity is 396 * present. 397 */ 398 public boolean hasMetadata() { 399 400 JSONObject metadataObject = getJSONObjectClaim(METADATA_CLAIM_NAME); 401 402 if (MapUtils.isEmpty(metadataObject)) { 403 return false; 404 } 405 406 if (metadataObject.get(FederationMetadataType.OPENID_RELYING_PARTY.getValue()) != null) return true; 407 if (metadataObject.get(FederationMetadataType.OPENID_PROVIDER.getValue()) != null) return true; 408 if (metadataObject.get(FederationMetadataType.OAUTH_AUTHORIZATION_SERVER.getValue()) != null) return true; 409 if (metadataObject.get(FederationMetadataType.OAUTH_CLIENT.getValue()) != null) return true; 410 if (metadataObject.get(FederationMetadataType.OAUTH_RESOURCE.getValue()) != null) return true; 411 if (metadataObject.get(FederationMetadataType.FEDERATION_ENTITY.getValue()) != null) return true; 412 413 return false; 414 } 415 416 417 /** 418 * Gets the metadata for the specified type. Use a typed getter, such 419 * as {@link #getRPMetadata}, when available. 420 * 421 * @param type The type. Must not be {@code null}. 422 * 423 * @return The metadata, {@code null} if not specified. 424 */ 425 public JSONObject getMetadata(final FederationMetadataType type) { 426 427 JSONObject o = getJSONObjectClaim(METADATA_CLAIM_NAME); 428 429 if (o == null) { 430 return null; 431 } 432 433 try { 434 return JSONObjectUtils.getJSONObject(o, type.getValue(), null); 435 } catch (com.nimbusds.oauth2.sdk.ParseException e) { 436 return null; 437 } 438 } 439 440 441 /** 442 * Sets the metadata for the specified type. Use a typed setter, such 443 * as {@link #setRPMetadata}, when available. 444 * 445 * @param type The type. Must not be {@code null}. 446 * @param metadata The metadata, {@code null} if not specified. 447 */ 448 public void setMetadata(final FederationMetadataType type, final JSONObject metadata) { 449 450 JSONObject o = getJSONObjectClaim(METADATA_CLAIM_NAME); 451 452 if (o == null) { 453 if (metadata == null) { 454 return; // nothing to clear 455 } 456 o = new JSONObject(); 457 } 458 459 o.put(type.getValue(), metadata); 460 461 setClaim(METADATA_CLAIM_NAME, o); 462 } 463 464 465 /** 466 * Gets the OpenID relying party metadata if present for this entity. 467 * 468 * @return The RP metadata, {@code null} if not specified or if parsing 469 * failed. 470 */ 471 public OIDCClientMetadata getRPMetadata() { 472 473 JSONObject o = getMetadata(FederationMetadataType.OPENID_RELYING_PARTY); 474 475 if (o == null) { 476 return null; 477 } 478 479 try { 480 return OIDCClientMetadata.parse(o); 481 } catch (com.nimbusds.oauth2.sdk.ParseException e) { 482 return null; 483 } 484 } 485 486 487 /** 488 * Sets the OpenID relying party metadata if present for this entity. 489 * 490 * @param rpMetadata The RP metadata, {@code null} if not specified. 491 */ 492 public void setRPMetadata(final OIDCClientMetadata rpMetadata) { 493 494 JSONObject o = rpMetadata != null ? rpMetadata.toJSONObject() : null; 495 setMetadata(FederationMetadataType.OPENID_RELYING_PARTY, o); 496 } 497 498 499 /** 500 * Gets the OpenID provider metadata if present for this entity. 501 * 502 * @return The OP metadata, {@code null} if not specified or if parsing 503 * failed. 504 */ 505 public OIDCProviderMetadata getOPMetadata() { 506 507 JSONObject o = getMetadata(FederationMetadataType.OPENID_PROVIDER); 508 509 if (o == null) { 510 return null; 511 } 512 513 try { 514 return OIDCProviderMetadata.parse(o); 515 } catch (com.nimbusds.oauth2.sdk.ParseException e) { 516 return null; 517 } 518 } 519 520 521 /** 522 * Gets the OpenID provider metadata if present for this entity. 523 * 524 * @param opMetadata The OP metadata, {@code null} if not specified. 525 */ 526 public void setOPMetadata(final OIDCProviderMetadata opMetadata) { 527 528 JSONObject o = opMetadata != null ? opMetadata.toJSONObject() : null; 529 setMetadata(FederationMetadataType.OPENID_PROVIDER, o); 530 } 531 532 533 /** 534 * Gets the OAuth 2.0 client metadata if present for this entity. 535 * 536 * @return The client metadata, {@code null} if not specified or if 537 * parsing failed. 538 */ 539 public ClientMetadata getOAuthClientMetadata() { 540 541 JSONObject o = getMetadata(FederationMetadataType.OAUTH_CLIENT); 542 543 if (o == null) { 544 return null; 545 } 546 547 try { 548 return ClientMetadata.parse(o); 549 } catch (com.nimbusds.oauth2.sdk.ParseException e) { 550 return null; 551 } 552 } 553 554 555 /** 556 * Sets the OAuth 2.0 client metadata if present for this entity. 557 * 558 * @param clientMetadata The client metadata, {@code null} if not 559 * specified. 560 */ 561 public void setOAuthClientMetadata(final ClientMetadata clientMetadata) { 562 563 JSONObject o = clientMetadata != null ? clientMetadata.toJSONObject() : null; 564 setMetadata(FederationMetadataType.OAUTH_CLIENT, o); 565 } 566 567 568 /** 569 * Gets the OAuth 2.0 authorisation server metadata if present for this 570 * entity. 571 * 572 * @return The AS metadata, {@code null} if not specified or if parsing 573 * failed. 574 */ 575 public AuthorizationServerMetadata getASMetadata() { 576 577 JSONObject o = getMetadata(FederationMetadataType.OAUTH_AUTHORIZATION_SERVER); 578 579 if (o == null) { 580 return null; 581 } 582 583 try { 584 return AuthorizationServerMetadata.parse(o); 585 } catch (com.nimbusds.oauth2.sdk.ParseException e) { 586 return null; 587 } 588 } 589 590 591 /** 592 * Sets the OAuth 2.0 authorisation server metadata if present for this 593 * entity. 594 * 595 * @param asMetadata The AS metadata, {@code null} if not specified. 596 */ 597 public void setASMetadata(final AuthorizationServerMetadata asMetadata) { 598 599 JSONObject o = asMetadata != null ? asMetadata.toJSONObject() : null; 600 setMetadata(FederationMetadataType.OAUTH_AUTHORIZATION_SERVER, o); 601 } 602 603 604 /** 605 * Gets the federation entity metadata if present for this entity. 606 * 607 * @return The federation entity metadata, {@code null} if not 608 * specified or if parsing failed. 609 */ 610 public FederationEntityMetadata getFederationEntityMetadata() { 611 612 JSONObject o = getMetadata(FederationMetadataType.FEDERATION_ENTITY); 613 614 if (o == null) { 615 return null; 616 } 617 618 try { 619 return FederationEntityMetadata.parse(o); 620 } catch (com.nimbusds.oauth2.sdk.ParseException e) { 621 return null; 622 } 623 } 624 625 626 /** 627 * Sets the federation entity metadata if present for this entity. 628 * 629 * @param entityMetadata The federation entity metadata, {@code null} 630 * if not specified. 631 */ 632 public void setFederationEntityMetadata(final FederationEntityMetadata entityMetadata) { 633 634 JSONObject o = entityMetadata != null ? entityMetadata.toJSONObject() : null; 635 setMetadata(FederationMetadataType.FEDERATION_ENTITY, o); 636 } 637 638 639 /** 640 * Gets the complete metadata policy JSON object. 641 * 642 * @return The metadata policy JSON object, {@code null} if not 643 * specified or if parsing failed. 644 */ 645 public JSONObject getMetadataPolicyJSONObject() { 646 647 return getJSONObjectClaim(METADATA_POLICY_CLAIM_NAME); 648 } 649 650 651 /** 652 * Sets the complete metadata policy JSON object. 653 * 654 * @param metadataPolicy The metadata policy JSON object, {@code null} 655 * if not specified. 656 */ 657 public void setMetadataPolicyJSONObject(final JSONObject metadataPolicy) { 658 659 setClaim(METADATA_POLICY_CLAIM_NAME, metadataPolicy); 660 } 661 662 663 /** 664 * Gets the metadata policy for the specified type. 665 * 666 * @param type The type. Must not be {@code null}. 667 * 668 * @return The metadata policy, {@code null} or if JSON parsing failed. 669 * 670 * @throws PolicyViolationException On a policy violation. 671 */ 672 public MetadataPolicy getMetadataPolicy(final FederationMetadataType type) 673 throws PolicyViolationException { 674 675 JSONObject o = getMetadataPolicyJSONObject(); 676 677 if (o == null) { 678 return null; 679 } 680 681 try { 682 JSONObject policyJSONObject = JSONObjectUtils.getJSONObject(o, type.getValue(), null); 683 if (policyJSONObject == null) { 684 return null; 685 } 686 return MetadataPolicy.parse(policyJSONObject); 687 } catch (ParseException e) { 688 return null; 689 } 690 } 691 692 693 /** 694 * Sets the metadata policy for the specified type. 695 * 696 * @param type The type. Must not be {@code null}. 697 * @param metadataPolicy The metadata policy, {@code null} if not 698 * specified. 699 */ 700 public void setMetadataPolicy(final FederationMetadataType type, final MetadataPolicy metadataPolicy) { 701 702 JSONObject o = getMetadataPolicyJSONObject(); 703 704 if (o == null) { 705 if (metadataPolicy == null) { 706 return; // nothing to clear 707 } 708 o = new JSONObject(); 709 } 710 711 if (metadataPolicy != null) { 712 o.put(type.getValue(), metadataPolicy.toJSONObject()); 713 } else { 714 o.remove(type.getValue()); 715 } 716 717 if (o.isEmpty()) { 718 o = null; 719 } 720 setMetadataPolicyJSONObject(o); 721 } 722 723 724 /** 725 * Gets the used trust anchor in a explicit client registration in 726 * OpenID Connect Federation 1.0. Intended for entity statements issued 727 * by an OpenID provider for a Relying party performing explicit client 728 * registration only.Corresponds to the {@code trust_anchor_id} client 729 * metadata field. 730 * 731 * @return The trust anchor ID, {@code null} if not specified. 732 */ 733 public EntityID getTrustAnchorID() { 734 735 String value = getStringClaim(TRUST_ANCHOR_ID_CLAIM_NAME); 736 737 try { 738 return EntityID.parse(value); 739 } catch (ParseException e) { 740 return null; 741 } 742 } 743 744 745 /** 746 * Sets the used trust anchor in a explicit client registration in 747 * OpenID Connect Federation 1.0. Intended for entity statements issued 748 * by an OpenID provider for a Relying party performing explicit client 749 * registration only.Corresponds to the {@code trust_anchor_id} client 750 * metadata field. 751 * 752 * @param trustAnchorID The trust anchor ID, {@code null} if not 753 * specified. 754 */ 755 public void setTrustAnchorID(final EntityID trustAnchorID) { 756 757 if (trustAnchorID != null) { 758 setClaim(TRUST_ANCHOR_ID_CLAIM_NAME, trustAnchorID.getValue()); 759 } else { 760 setClaim(TRUST_ANCHOR_ID_CLAIM_NAME, null); 761 } 762 } 763 764 765 /** 766 * Gets the trust chain constraints for subordinate entities. 767 * 768 * @return The trust chain constraints, {@code null} if not specified 769 * or if parsing failed. 770 */ 771 public TrustChainConstraints getConstraints() { 772 773 JSONObject o = getJSONObjectClaim(CONSTRAINTS_CLAIM_NAME); 774 775 if (o == null) { 776 return null; 777 } 778 779 try { 780 return TrustChainConstraints.parse(o); 781 } catch (com.nimbusds.oauth2.sdk.ParseException e) { 782 return null; 783 } 784 } 785 786 787 /** 788 * Sets the trust chain constraint for subordinate entities. 789 * 790 * @param constraints The trust chain constraints, {@code null} if not 791 * specified. 792 */ 793 public void setConstraints(final TrustChainConstraints constraints) { 794 795 if (constraints != null) { 796 setClaim(CONSTRAINTS_CLAIM_NAME, constraints.toJSONObject()); 797 } else { 798 setClaim(CONSTRAINTS_CLAIM_NAME, null); 799 } 800 } 801 802 803 /** 804 * Gets the names of the critical extension claims. 805 * 806 * @return The names of the critical extension claims, {@code null} if 807 * not specified or if parsing failed. 808 */ 809 public List<String> getCriticalExtensionClaims() { 810 811 return getStringListClaim(CRITICAL_CLAIM_NAME); 812 } 813 814 815 /** 816 * Sets the names of the critical extension claims. 817 * 818 * @param claimNames The names of the critical extension claims, 819 * {@code null} if not specified. Must not be an 820 * empty list. 821 */ 822 public void setCriticalExtensionClaims(final List<String> claimNames) { 823 824 if (claimNames != null && claimNames.isEmpty()) { 825 throw new IllegalArgumentException("The critical extension claim names must not be empty"); 826 } 827 828 setClaim(CRITICAL_CLAIM_NAME, claimNames); 829 } 830 831 832 /** 833 * Gets the names of the critical policy extensions. 834 * 835 * @return The names of the critical policy extensions or if parsing 836 * failed. 837 */ 838 public List<String> getCriticalPolicyExtensions() { 839 840 return getStringListClaim(POLICY_LANGUAGE_CRITICAL_CLAIM_NAME); 841 } 842 843 844 /** 845 * Sets the names of the critical policy extensions. 846 * 847 * @param extNames The names of the critical policy extensions, 848 * {@code null} if not specified. Must not be an empty 849 * list. 850 */ 851 public void setCriticalPolicyExtensions(final List<String> extNames) { 852 853 if (extNames != null && extNames.isEmpty()) { 854 throw new IllegalArgumentException("The critical policy extension names must not be empty"); 855 } 856 857 setClaim(POLICY_LANGUAGE_CRITICAL_CLAIM_NAME, extNames); 858 } 859}