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.oauth2.sdk.client; 019 020 021import java.net.URI; 022import java.net.URISyntaxException; 023import java.util.*; 024 025import net.minidev.json.JSONArray; 026import net.minidev.json.JSONObject; 027 028import com.nimbusds.jose.EncryptionMethod; 029import com.nimbusds.jose.JWEAlgorithm; 030import com.nimbusds.jose.JWSAlgorithm; 031import com.nimbusds.jose.jwk.JWKSet; 032import com.nimbusds.langtag.LangTag; 033import com.nimbusds.langtag.LangTagUtils; 034import com.nimbusds.oauth2.sdk.GrantType; 035import com.nimbusds.oauth2.sdk.ParseException; 036import com.nimbusds.oauth2.sdk.ResponseType; 037import com.nimbusds.oauth2.sdk.Scope; 038import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod; 039import com.nimbusds.oauth2.sdk.id.Identifier; 040import com.nimbusds.oauth2.sdk.id.SoftwareID; 041import com.nimbusds.oauth2.sdk.id.SoftwareVersion; 042import com.nimbusds.oauth2.sdk.util.CollectionUtils; 043import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 044import com.nimbusds.openid.connect.sdk.federation.FederationType; 045import com.nimbusds.openid.connect.sdk.federation.entities.EntityID; 046 047 048/** 049 * Client metadata. 050 * 051 * <p>Example client metadata, serialised to a JSON object: 052 * 053 * <pre> 054 * { 055 * "redirect_uris" : ["https://client.example.org/callback", 056 * "https://client.example.org/callback2"], 057 * "client_name" : "My Example Client", 058 * "client_name#ja-Jpan-JP" : "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D", 059 * "token_endpoint_auth_method" : "client_secret_basic", 060 * "scope" : "read write dolphin", 061 * "logo_uri" : "https://client.example.org/logo.png", 062 * "jwks_uri" : "https://client.example.org/my_public_keys.jwks" 063 * } 064 * </pre> 065 * 066 * <p>Related specifications: 067 * 068 * <ul> 069 * <li>OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591), section 070 * 2. 071 * <li>OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound 072 * Access Tokens (RFC 8705), sections 2.1.2 and 3.4. 073 * <li>Financial-grade API: JWT Secured Authorization Response Mode for 074 * OAuth 2.0 (JARM). 075 * <li>OpenID Connect Federation 1.0 (draft 11) 076 * </ul> 077 */ 078public class ClientMetadata { 079 080 081 /** 082 * The registered parameter names. 083 */ 084 private static final Set<String> REGISTERED_PARAMETER_NAMES; 085 086 087 static { 088 Set<String> p = new HashSet<>(); 089 090 p.add("redirect_uris"); 091 p.add("scope"); 092 p.add("response_types"); 093 p.add("grant_types"); 094 p.add("contacts"); 095 p.add("client_name"); 096 p.add("logo_uri"); 097 p.add("client_uri"); 098 p.add("policy_uri"); 099 p.add("tos_uri"); 100 p.add("token_endpoint_auth_method"); 101 p.add("token_endpoint_auth_signing_alg"); 102 p.add("jwks_uri"); 103 p.add("jwks"); 104 p.add("request_uris"); 105 p.add("request_object_signing_alg"); 106 p.add("request_object_encryption_alg"); 107 p.add("request_object_encryption_enc"); 108 p.add("software_id"); 109 p.add("software_version"); 110 p.add("tls_client_certificate_bound_access_tokens"); 111 p.add("tls_client_auth_subject_dn"); 112 p.add("tls_client_auth_san_dns"); 113 p.add("tls_client_auth_san_uri"); 114 p.add("tls_client_auth_san_ip"); 115 p.add("tls_client_auth_san_email"); 116 p.add("authorization_signed_response_alg"); 117 p.add("authorization_encrypted_response_alg"); 118 p.add("authorization_encrypted_response_enc"); 119 120 // OIDC federation 121 p.add("federation_type"); 122 p.add("organization_name"); 123 p.add("trust_anchor_id"); 124 125 REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p); 126 } 127 128 129 /** 130 * Redirect URIs. 131 */ 132 private Set<URI> redirectURIs; 133 134 135 /** 136 * The client OAuth 2.0 scope. 137 */ 138 private Scope scope; 139 140 141 /** 142 * The expected OAuth 2.0 response types. 143 */ 144 private Set<ResponseType> responseTypes; 145 146 147 /** 148 * The expected OAuth 2.0 grant types. 149 */ 150 private Set<GrantType> grantTypes; 151 152 153 /** 154 * Administrator email contacts for the client. 155 */ 156 private List<String> contacts; 157 158 159 /** 160 * The client name. 161 */ 162 private final Map<LangTag,String> nameEntries; 163 164 165 /** 166 * The client application logo. 167 */ 168 private final Map<LangTag,URI> logoURIEntries; 169 170 171 /** 172 * The client URI entries. 173 */ 174 private final Map<LangTag,URI> uriEntries; 175 176 177 /** 178 * The client policy for use of end-user data. 179 */ 180 private Map<LangTag,URI> policyURIEntries; 181 182 183 /** 184 * The client terms of service. 185 */ 186 private final Map<LangTag,URI> tosURIEntries; 187 188 189 /** 190 * Token endpoint authentication method. 191 */ 192 private ClientAuthenticationMethod authMethod; 193 194 195 /** 196 * The JSON Web Signature (JWS) algorithm required for 197 * {@code private_key_jwt} and {@code client_secret_jwt} 198 * authentication at the Token endpoint. 199 */ 200 private JWSAlgorithm authJWSAlg; 201 202 203 /** 204 * URI for this client's JSON Web Key (JWK) set containing key(s) that 205 * are used in signing requests to the server and key(s) for encrypting 206 * responses. 207 */ 208 private URI jwkSetURI; 209 210 211 /** 212 * Client's JSON Web Key (JWK) set containing key(s) that are used in 213 * signing requests to the server and key(s) for encrypting responses. 214 * Intended as an alternative to {@link #jwkSetURI} for native clients. 215 */ 216 private JWKSet jwkSet; 217 218 219 /** 220 * Pre-registered request object URIs. 221 */ 222 private Set<URI> requestObjectURIs; 223 224 225 /** 226 * The JSON Web Signature (JWS) algorithm required for request objects 227 * sent by this client. 228 */ 229 private JWSAlgorithm requestObjectJWSAlg; 230 231 232 /** 233 * The JSON Web Encryption (JWE) algorithm required for request objects 234 * sent by this client. 235 */ 236 private JWEAlgorithm requestObjectJWEAlg; 237 238 239 /** 240 * The JSON Web Encryption (JWE) method required for request objects 241 * sent by this client. 242 */ 243 private EncryptionMethod requestObjectJWEEnc; 244 245 246 /** 247 * Identifier for the OAuth 2.0 client software. 248 */ 249 private SoftwareID softwareID; 250 251 252 /** 253 * Version identifier for the OAuth 2.0 client software. 254 */ 255 private SoftwareVersion softwareVersion; 256 257 258 /** 259 * Preference for TLS client certificate bound access tokens. 260 */ 261 private boolean tlsClientCertificateBoundAccessTokens = false; 262 263 264 /** 265 * The expected subject distinguished name (DN) of the client X.509 266 * certificate the in mutual TLS authentication. 267 */ 268 private String tlsClientAuthSubjectDN = null; 269 270 271 /** 272 * The expected dNSName SAN entry in the X.509 certificate, which 273 * the OAuth client will use in mutual TLS authentication. 274 */ 275 private String tlsClientAuthSanDNS = null; 276 277 278 /** 279 * The expected uniformResourceIdentifier SAN entry in the X.509 280 * certificate, which the OAuth client will use in mutual TLS 281 * authentication. 282 */ 283 private String tlsClientAuthSanURI = null; 284 285 286 /** 287 * The expected iPAddress SAN entry in the X.509 certificate, which 288 * the OAuth client will use in mutual TLS authentication. 289 */ 290 private String tlsClientAuthSanIP = null; 291 292 293 /** 294 * The expected rfc822Name SAN entry in the X.509 certificate, which 295 * the OAuth client will use in mutual TLS authentication. 296 */ 297 private String tlsClientAuthSanEmail = null; 298 299 300 /** 301 * The JWS algorithm for JWT-encoded authorisation responses. 302 */ 303 private JWSAlgorithm authzJWSAlg; 304 305 306 /** 307 * The JWE algorithm for JWT-encoded authorisation responses. 308 */ 309 private JWEAlgorithm authzJWEAlg; 310 311 312 /** 313 * The encryption method for JWT-encoded authorisation responses. 314 */ 315 private EncryptionMethod authzJWEEnc; 316 317 318 /** 319 * The supported OpenID Connect Federation 1.0 types. 320 */ 321 private List<FederationType> federationTypes; 322 323 324 /** 325 * The organisation name in OpenID Connect Federation 1.0. 326 */ 327 private String organizationName; 328 329 330 /** 331 * The used trust anchor in a explicit client registration in OpenID 332 * Connect Federation 1.0. 333 */ 334 private EntityID trustAnchorID; 335 336 337 /** 338 * The custom metadata fields. 339 */ 340 private JSONObject customFields; 341 342 343 /** 344 * Creates a new OAuth 2.0 client metadata instance. 345 */ 346 public ClientMetadata() { 347 348 nameEntries = new HashMap<>(); 349 logoURIEntries = new HashMap<>(); 350 uriEntries = new HashMap<>(); 351 policyURIEntries = new HashMap<>(); 352 policyURIEntries = new HashMap<>(); 353 tosURIEntries = new HashMap<>(); 354 customFields = new JSONObject(); 355 } 356 357 358 /** 359 * Creates a shallow copy of the specified OAuth 2.0 client metadata 360 * instance. 361 * 362 * @param metadata The client metadata to copy. Must not be 363 * {@code null}. 364 */ 365 public ClientMetadata(final ClientMetadata metadata) { 366 367 redirectURIs = metadata.redirectURIs; 368 scope = metadata.scope; 369 responseTypes = metadata.responseTypes; 370 grantTypes = metadata.grantTypes; 371 contacts = metadata.contacts; 372 nameEntries = metadata.nameEntries; 373 logoURIEntries = metadata.logoURIEntries; 374 uriEntries = metadata.uriEntries; 375 policyURIEntries = metadata.policyURIEntries; 376 tosURIEntries = metadata.tosURIEntries; 377 authMethod = metadata.authMethod; 378 authJWSAlg = metadata.authJWSAlg; 379 jwkSetURI = metadata.jwkSetURI; 380 jwkSet = metadata.getJWKSet(); 381 requestObjectURIs = metadata.requestObjectURIs; 382 requestObjectJWSAlg = metadata.requestObjectJWSAlg; 383 requestObjectJWEAlg = metadata.requestObjectJWEAlg; 384 requestObjectJWEEnc = metadata.requestObjectJWEEnc; 385 softwareID = metadata.softwareID; 386 softwareVersion = metadata.softwareVersion; 387 tlsClientCertificateBoundAccessTokens = metadata.tlsClientCertificateBoundAccessTokens; 388 tlsClientAuthSubjectDN = metadata.tlsClientAuthSubjectDN; 389 tlsClientAuthSanDNS = metadata.tlsClientAuthSanDNS; 390 tlsClientAuthSanURI = metadata.tlsClientAuthSanURI; 391 tlsClientAuthSanIP = metadata.tlsClientAuthSanIP; 392 tlsClientAuthSanEmail = metadata.tlsClientAuthSanEmail; 393 authzJWSAlg = metadata.authzJWSAlg; 394 authzJWEAlg = metadata.authzJWEAlg; 395 authzJWEEnc = metadata.authzJWEEnc; 396 federationTypes = metadata.federationTypes; 397 organizationName = metadata.organizationName; 398 trustAnchorID = metadata.trustAnchorID; 399 customFields = metadata.customFields; 400 } 401 402 403 /** 404 * Gets the registered (standard) OAuth 2.0 client metadata parameter 405 * names. 406 * 407 * @return The registered parameter names, as an unmodifiable set. 408 */ 409 public static Set<String> getRegisteredParameterNames() { 410 411 return REGISTERED_PARAMETER_NAMES; 412 } 413 414 415 /** 416 * Gets the redirection URIs for this client. Corresponds to the 417 * {@code redirect_uris} client metadata field. 418 * 419 * @return The redirection URIs, {@code null} if not specified. 420 */ 421 public Set<URI> getRedirectionURIs() { 422 423 return redirectURIs; 424 } 425 426 427 /** 428 * Gets one of the redirection URIs for this client. Corresponds to the 429 * {@code redirect_uris} client metadata field. 430 * 431 * @return The redirection URI, {@code null} if not specified. 432 */ 433 public URI getRedirectionURI() { 434 435 if (redirectURIs != null && ! redirectURIs.isEmpty()) { 436 return redirectURIs.iterator().next(); 437 } else { 438 return null; 439 } 440 } 441 442 443 /** 444 * Gets the redirection URIs for this client as strings. Corresponds to 445 * the {@code redirect_uris} client metadata field. 446 * 447 * <p>This short-hand method is intended to enable string-based URI 448 * comparison. 449 * 450 * @return The redirection URIs as strings, {@code null} if not 451 * specified. 452 */ 453 public Set<String> getRedirectionURIStrings() { 454 455 if (redirectURIs == null) 456 return null; 457 458 Set<String> uriStrings = new HashSet<>(); 459 460 for (URI uri: redirectURIs) 461 uriStrings.add(uri.toString()); 462 463 return uriStrings; 464 } 465 466 467 /** 468 * Sets the redirection URIs for this client. Corresponds to the 469 * {@code redirect_uris} client metadata field. 470 * 471 * @param redirectURIs The redirection URIs, {@code null} if not 472 * specified. Valid redirection URIs must not 473 * contain a fragment. 474 */ 475 public void setRedirectionURIs(final Set<URI> redirectURIs) { 476 477 if (redirectURIs != null) { 478 // check URIs 479 for (URI uri: redirectURIs) { 480 if (uri == null) { 481 throw new IllegalArgumentException("The redirect_uri must not be null"); 482 } 483 if (uri.getFragment() != null) { 484 throw new IllegalArgumentException("The redirect_uri must not contain fragment"); 485 } 486 } 487 this.redirectURIs = redirectURIs; 488 } else { 489 this.redirectURIs = null; 490 } 491 } 492 493 494 /** 495 * Sets a single redirection URI for this client. Corresponds to the 496 * {@code redirect_uris} client metadata field. 497 * 498 * @param redirectURI The redirection URIs, {@code null} if not 499 * specified. A valid redirection URI must not 500 * contain a fragment. 501 */ 502 public void setRedirectionURI(final URI redirectURI) { 503 504 setRedirectionURIs(redirectURI != null ? Collections.singleton(redirectURI) : null); 505 } 506 507 508 /** 509 * Gets the scope values that the client can use when requesting access 510 * tokens. Corresponds to the {@code scope} client metadata field. 511 * 512 * @return The scope, {@code null} if not specified. 513 */ 514 public Scope getScope() { 515 516 return scope; 517 } 518 519 520 /** 521 * Checks if the scope matadata field is set and contains the specified 522 * scope value. 523 * 524 * @param scopeValue The scope value. Must not be {@code null}. 525 * 526 * @return {@code true} if the scope value is contained, else 527 * {@code false}. 528 */ 529 public boolean hasScopeValue(final Scope.Value scopeValue) { 530 531 return scope != null && scope.contains(scopeValue); 532 } 533 534 535 /** 536 * Sets the scope values that the client can use when requesting access 537 * tokens. Corresponds to the {@code scope} client metadata field. 538 * 539 * @param scope The scope, {@code null} if not specified. 540 */ 541 public void setScope(final Scope scope) { 542 543 this.scope = scope; 544 } 545 546 547 /** 548 * Gets the expected OAuth 2.0 response types. Corresponds to the 549 * {@code response_types} client metadata field. 550 * 551 * @return The response types, {@code null} if not specified. 552 */ 553 public Set<ResponseType> getResponseTypes() { 554 555 return responseTypes; 556 } 557 558 559 /** 560 * Sets the expected OAuth 2.0 response types. Corresponds to the 561 * {@code response_types} client metadata field. 562 * 563 * @param responseTypes The response types, {@code null} if not 564 * specified. 565 */ 566 public void setResponseTypes(final Set<ResponseType> responseTypes) { 567 568 this.responseTypes = responseTypes; 569 } 570 571 572 /** 573 * Gets the expected OAuth 2.0 grant types. Corresponds to the 574 * {@code grant_types} client metadata field. 575 * 576 * @return The grant types, {@code null} if not specified. 577 */ 578 public Set<GrantType> getGrantTypes() { 579 580 return grantTypes; 581 } 582 583 584 /** 585 * Sets the expected OAuth 2.0 grant types. Corresponds to the 586 * {@code grant_types} client metadata field. 587 * 588 * @param grantTypes The grant types, {@code null} if not specified. 589 */ 590 public void setGrantTypes(final Set<GrantType> grantTypes) { 591 592 this.grantTypes = grantTypes; 593 } 594 595 596 /** 597 * Gets the administrator email contacts for the client. Corresponds to 598 * the {@code contacts} client metadata field. 599 * 600 * @return The administrator email contacts, {@code null} if not 601 * specified. 602 */ 603 public List<String> getEmailContacts() { 604 605 return contacts; 606 } 607 608 609 /** 610 * Sets the administrator email contacts for the client. Corresponds to 611 * the {@code contacts} client metadata field. 612 * 613 * @param contacts The administrator email contacts, {@code null} if 614 * not specified. 615 */ 616 public void setEmailContacts(final List<String> contacts) { 617 618 this.contacts = contacts; 619 } 620 621 622 /** 623 * Gets the client name. Corresponds to the {@code client_name} client 624 * metadata field, with no language tag. 625 * 626 * @return The client name, {@code null} if not specified. 627 */ 628 public String getName() { 629 630 return getName(null); 631 } 632 633 634 /** 635 * Gets the client name. Corresponds to the {@code client_name} client 636 * metadata field, with an optional language tag. 637 * 638 * @param langTag The language tag of the entry, {@code null} to get 639 * the non-tagged entry. 640 * 641 * @return The client name, {@code null} if not specified. 642 */ 643 public String getName(final LangTag langTag) { 644 645 return nameEntries.get(langTag); 646 } 647 648 649 /** 650 * Gets the client name entries. Corresponds to the {@code client_name} 651 * client metadata field. 652 * 653 * @return The client name entries, empty map if none. 654 */ 655 public Map<LangTag,String> getNameEntries() { 656 657 return nameEntries; 658 } 659 660 661 /** 662 * Sets the client name. Corresponds to the {@code client_name} client 663 * metadata field, with no language tag. 664 * 665 * @param name The client name, {@code null} if not specified. 666 */ 667 public void setName(final String name) { 668 669 nameEntries.put(null, name); 670 } 671 672 673 /** 674 * Sets the client name. Corresponds to the {@code client_name} client 675 * metadata field, with an optional language tag. 676 * 677 * @param name The client name. Must not be {@code null}. 678 * @param langTag The language tag, {@code null} if not specified. 679 */ 680 public void setName(final String name, final LangTag langTag) { 681 682 nameEntries.put(langTag, name); 683 } 684 685 686 /** 687 * Gets the client application logo. Corresponds to the 688 * {@code logo_uri} client metadata field, with no language 689 * tag. 690 * 691 * @return The logo URI, {@code null} if not specified. 692 */ 693 public URI getLogoURI() { 694 695 return getLogoURI(null); 696 } 697 698 699 /** 700 * Gets the client application logo. Corresponds to the 701 * {@code logo_uri} client metadata field, with an optional 702 * language tag. 703 * 704 * @param langTag The language tag, {@code null} if not specified. 705 * 706 * @return The logo URI, {@code null} if not specified. 707 */ 708 public URI getLogoURI(final LangTag langTag) { 709 710 return logoURIEntries.get(langTag); 711 } 712 713 714 /** 715 * Gets the client application logo entries. Corresponds to the 716 * {@code logo_uri} client metadata field. 717 * 718 * @return The logo URI entries, empty map if none. 719 */ 720 public Map<LangTag,URI> getLogoURIEntries() { 721 722 return logoURIEntries; 723 } 724 725 726 /** 727 * Sets the client application logo. Corresponds to the 728 * {@code logo_uri} client metadata field, with no language 729 * tag. 730 * 731 * @param logoURI The logo URI, {@code null} if not specified. 732 */ 733 public void setLogoURI(final URI logoURI) { 734 735 logoURIEntries.put(null, logoURI); 736 } 737 738 739 /** 740 * Sets the client application logo. Corresponds to the 741 * {@code logo_uri} client metadata field, with an optional 742 * language tag. 743 * 744 * @param logoURI The logo URI. Must not be {@code null}. 745 * @param langTag The language tag, {@code null} if not specified. 746 */ 747 public void setLogoURI(final URI logoURI, final LangTag langTag) { 748 749 logoURIEntries.put(langTag, logoURI); 750 } 751 752 753 /** 754 * Gets the client home page. Corresponds to the {@code client_uri} 755 * client metadata field, with no language tag. 756 * 757 * @return The client URI, {@code null} if not specified. 758 */ 759 public URI getURI() { 760 761 return getURI(null); 762 } 763 764 765 /** 766 * Gets the client home page. Corresponds to the {@code client_uri} 767 * client metadata field, with an optional language tag. 768 * 769 * @param langTag The language tag, {@code null} if not specified. 770 * 771 * @return The client URI, {@code null} if not specified. 772 */ 773 public URI getURI(final LangTag langTag) { 774 775 return uriEntries.get(langTag); 776 } 777 778 779 /** 780 * Gets the client home page entries. Corresponds to the 781 * {@code client_uri} client metadata field. 782 * 783 * @return The client URI entries, empty map if none. 784 */ 785 public Map<LangTag,URI> getURIEntries() { 786 787 return uriEntries; 788 } 789 790 791 /** 792 * Sets the client home page. Corresponds to the {@code client_uri} 793 * client metadata field, with no language tag. 794 * 795 * @param uri The client URI, {@code null} if not specified. 796 */ 797 public void setURI(final URI uri) { 798 799 uriEntries.put(null, uri); 800 } 801 802 803 /** 804 * Sets the client home page. Corresponds to the {@code client_uri} 805 * client metadata field, with an optional language tag. 806 * 807 * @param uri The URI. Must not be {@code null}. 808 * @param langTag The language tag, {@code null} if not specified. 809 */ 810 public void setURI(final URI uri, final LangTag langTag) { 811 812 uriEntries.put(langTag, uri); 813 } 814 815 816 /** 817 * Gets the client policy for use of end-user data. Corresponds to the 818 * {@code policy_uri} client metadata field, with no language 819 * tag. 820 * 821 * @return The policy URI, {@code null} if not specified. 822 */ 823 public URI getPolicyURI() { 824 825 return getPolicyURI(null); 826 } 827 828 829 /** 830 * Gets the client policy for use of end-user data. Corresponds to the 831 * {@code policy_uri} client metadata field, with an optional 832 * language tag. 833 * 834 * @param langTag The language tag, {@code null} if not specified. 835 * 836 * @return The policy URI, {@code null} if not specified. 837 */ 838 public URI getPolicyURI(final LangTag langTag) { 839 840 return policyURIEntries.get(langTag); 841 } 842 843 844 /** 845 * Gets the client policy entries for use of end-user data. 846 * Corresponds to the {@code policy_uri} client metadata field. 847 * 848 * @return The policy URI entries, empty map if none. 849 */ 850 public Map<LangTag,URI> getPolicyURIEntries() { 851 852 return policyURIEntries; 853 } 854 855 856 /** 857 * Sets the client policy for use of end-user data. Corresponds to the 858 * {@code policy_uri} client metadata field, with no language 859 * tag. 860 * 861 * @param policyURI The policy URI, {@code null} if not specified. 862 */ 863 public void setPolicyURI(final URI policyURI) { 864 865 policyURIEntries.put(null, policyURI); 866 } 867 868 869 /** 870 * Sets the client policy for use of end-user data. Corresponds to the 871 * {@code policy_uri} client metadata field, with an optional 872 * language tag. 873 * 874 * @param policyURI The policy URI. Must not be {@code null}. 875 * @param langTag The language tag, {@code null} if not specified. 876 */ 877 public void setPolicyURI(final URI policyURI, final LangTag langTag) { 878 879 policyURIEntries.put(langTag, policyURI); 880 } 881 882 883 /** 884 * Gets the client's terms of service. Corresponds to the 885 * {@code tos_uri} client metadata field, with no language 886 * tag. 887 * 888 * @return The terms of service URI, {@code null} if not specified. 889 */ 890 public URI getTermsOfServiceURI() { 891 892 return getTermsOfServiceURI(null); 893 } 894 895 896 /** 897 * Gets the client's terms of service. Corresponds to the 898 * {@code tos_uri} client metadata field, with an optional 899 * language tag. 900 * 901 * @param langTag The language tag, {@code null} if not specified. 902 * 903 * @return The terms of service URI, {@code null} if not specified. 904 */ 905 public URI getTermsOfServiceURI(final LangTag langTag) { 906 907 return tosURIEntries.get(langTag); 908 } 909 910 911 /** 912 * Gets the client's terms of service entries. Corresponds to the 913 * {@code tos_uri} client metadata field. 914 * 915 * @return The terms of service URI entries, empty map if none. 916 */ 917 public Map<LangTag,URI> getTermsOfServiceURIEntries() { 918 919 return tosURIEntries; 920 } 921 922 923 /** 924 * Sets the client's terms of service. Corresponds to the 925 * {@code tos_uri} client metadata field, with no language 926 * tag. 927 * 928 * @param tosURI The terms of service URI, {@code null} if not 929 * specified. 930 */ 931 public void setTermsOfServiceURI(final URI tosURI) { 932 933 tosURIEntries.put(null, tosURI); 934 } 935 936 937 /** 938 * Sets the client's terms of service. Corresponds to the 939 * {@code tos_uri} client metadata field, with an optional 940 * language tag. 941 * 942 * @param tosURI The terms of service URI. Must not be {@code null}. 943 * @param langTag The language tag, {@code null} if not specified. 944 */ 945 public void setTermsOfServiceURI(final URI tosURI, final LangTag langTag) { 946 947 tosURIEntries.put(langTag, tosURI); 948 } 949 950 951 /** 952 * Gets the Token endpoint authentication method. Corresponds to the 953 * {@code token_endpoint_auth_method} client metadata field. 954 * 955 * @return The Token endpoint authentication method, {@code null} if 956 * not specified. 957 */ 958 public ClientAuthenticationMethod getTokenEndpointAuthMethod() { 959 960 return authMethod; 961 } 962 963 964 /** 965 * Sets the Token endpoint authentication method. Corresponds to the 966 * {@code token_endpoint_auth_method} client metadata field. 967 * 968 * @param authMethod The Token endpoint authentication method, 969 * {@code null} if not specified. 970 */ 971 public void setTokenEndpointAuthMethod(final ClientAuthenticationMethod authMethod) { 972 973 this.authMethod = authMethod; 974 } 975 976 977 /** 978 * Gets the JSON Web Signature (JWS) algorithm required for 979 * {@code private_key_jwt} and {@code client_secret_jwt} 980 * authentication at the Token endpoint. Corresponds to the 981 * {@code token_endpoint_auth_signing_alg} client metadata field. 982 * 983 * @return The JWS algorithm, {@code null} if not specified. 984 */ 985 public JWSAlgorithm getTokenEndpointAuthJWSAlg() { 986 987 return authJWSAlg; 988 } 989 990 991 /** 992 * Sets the JSON Web Signature (JWS) algorithm required for 993 * {@code private_key_jwt} and {@code client_secret_jwt} 994 * authentication at the Token endpoint. Corresponds to the 995 * {@code token_endpoint_auth_signing_alg} client metadata field. 996 * 997 * @param authJWSAlg The JWS algorithm, {@code null} if not specified. 998 */ 999 public void setTokenEndpointAuthJWSAlg(final JWSAlgorithm authJWSAlg) { 1000 1001 this.authJWSAlg = authJWSAlg; 1002 } 1003 1004 1005 /** 1006 * Gets the URI for this client's JSON Web Key (JWK) set containing 1007 * key(s) that are used in signing requests to the server and key(s) 1008 * for encrypting responses. Corresponds to the {@code jwks_uri} client 1009 * metadata field. 1010 * 1011 * @return The JWK set URI, {@code null} if not specified. 1012 */ 1013 public URI getJWKSetURI() { 1014 1015 return jwkSetURI; 1016 } 1017 1018 1019 /** 1020 * Sets the URI for this client's JSON Web Key (JWK) set containing 1021 * key(s) that are used in signing requests to the server and key(s) 1022 * for encrypting responses. Corresponds to the {@code jwks_uri} client 1023 * metadata field. 1024 * 1025 * @param jwkSetURI The JWK set URI, {@code null} if not specified. 1026 */ 1027 public void setJWKSetURI(final URI jwkSetURI) { 1028 1029 this.jwkSetURI = jwkSetURI; 1030 } 1031 1032 1033 /** 1034 * Gets this client's JSON Web Key (JWK) set containing key(s) that are 1035 * used in signing requests to the server and key(s) for encrypting 1036 * responses. Intended as an alternative to {@link #getJWKSetURI} for 1037 * native clients. Corresponds to the {@code jwks} client metadata 1038 * field. 1039 * 1040 * @return The JWK set, {@code null} if not specified. 1041 */ 1042 public JWKSet getJWKSet() { 1043 1044 return jwkSet; 1045 } 1046 1047 1048 /** 1049 * Sets this client's JSON Web Key (JWK) set containing key(s) that are 1050 * used in signing requests to the server and key(s) for encrypting 1051 * responses. Intended as an alternative to {@link #getJWKSetURI} for 1052 * native clients. Corresponds to the {@code jwks} client metadata 1053 * field. 1054 * 1055 * @param jwkSet The JWK set, {@code null} if not specified. 1056 */ 1057 public void setJWKSet(final JWKSet jwkSet) { 1058 1059 this.jwkSet = jwkSet; 1060 } 1061 1062 1063 /** 1064 * Gets the pre-registered request object URIs. Corresponds to the 1065 * {@code request_uris} client metadata field. 1066 * 1067 * @return The request object URIs, {@code null} if not specified. 1068 */ 1069 public Set<URI> getRequestObjectURIs() { 1070 1071 return requestObjectURIs; 1072 } 1073 1074 1075 /** 1076 * Sets the pre-registered request object URIs. Corresponds to the 1077 * {@code request_uris} client metadata field. 1078 * 1079 * @param requestObjectURIs The request object URIs, {@code null} if 1080 * not specified. 1081 */ 1082 public void setRequestObjectURIs(final Set<URI> requestObjectURIs) { 1083 1084 this.requestObjectURIs = requestObjectURIs; 1085 } 1086 1087 1088 /** 1089 * Gets the JSON Web Signature (JWS) algorithm required for request 1090 * objects sent by this client. Corresponds to the 1091 * {@code request_object_signing_alg} client metadata field. 1092 * 1093 * @return The JWS algorithm, {@code null} if not specified. 1094 */ 1095 public JWSAlgorithm getRequestObjectJWSAlg() { 1096 1097 return requestObjectJWSAlg; 1098 } 1099 1100 1101 /** 1102 * Sets the JSON Web Signature (JWS) algorithm required for request 1103 * objects sent by this client. Corresponds to the 1104 * {@code request_object_signing_alg} client metadata field. 1105 * 1106 * @param requestObjectJWSAlg The JWS algorithm, {@code null} if not 1107 * specified. 1108 */ 1109 public void setRequestObjectJWSAlg(final JWSAlgorithm requestObjectJWSAlg) { 1110 1111 this.requestObjectJWSAlg = requestObjectJWSAlg; 1112 } 1113 1114 1115 /** 1116 * Gets the JSON Web Encryption (JWE) algorithm required for request 1117 * objects sent by this client. Corresponds to the 1118 * {@code request_object_encryption_alg} client metadata field. 1119 * 1120 * @return The JWE algorithm, {@code null} if not specified. 1121 */ 1122 public JWEAlgorithm getRequestObjectJWEAlg() { 1123 1124 return requestObjectJWEAlg; 1125 } 1126 1127 1128 /** 1129 * Sets the JSON Web Encryption (JWE) algorithm required for request 1130 * objects sent by this client. Corresponds to the 1131 * {@code request_object_encryption_alg} client metadata field. 1132 * 1133 * @param requestObjectJWEAlg The JWE algorithm, {@code null} if not 1134 * specified. 1135 */ 1136 public void setRequestObjectJWEAlg(final JWEAlgorithm requestObjectJWEAlg) { 1137 1138 this.requestObjectJWEAlg = requestObjectJWEAlg; 1139 } 1140 1141 1142 /** 1143 * Gets the JSON Web Encryption (JWE) method required for request 1144 * objects sent by this client. Corresponds to the 1145 * {@code request_object_encryption_enc} client metadata field. 1146 * 1147 * @return The JWE method, {@code null} if not specified. 1148 */ 1149 public EncryptionMethod getRequestObjectJWEEnc() { 1150 1151 return requestObjectJWEEnc; 1152 } 1153 1154 1155 /** 1156 * Sets the JSON Web Encryption (JWE) method required for request 1157 * objects sent by this client. Corresponds to the 1158 * {@code request_object_encryption_enc} client metadata field. 1159 * 1160 * @param requestObjectJWEEnc The JWE method, {@code null} if not 1161 * specified. 1162 */ 1163 public void setRequestObjectJWEEnc(final EncryptionMethod requestObjectJWEEnc) { 1164 1165 this.requestObjectJWEEnc = requestObjectJWEEnc; 1166 } 1167 1168 1169 /** 1170 * Gets the identifier for the OAuth 2.0 client software. Corresponds 1171 * to the {@code software_id} client metadata field. 1172 * 1173 * @return The software identifier, {@code null} if not specified. 1174 */ 1175 public SoftwareID getSoftwareID() { 1176 1177 return softwareID; 1178 } 1179 1180 1181 /** 1182 * Sets the identifier for the OAuth 2.0 client software. Corresponds 1183 * to the {@code software_id} client metadata field. 1184 * 1185 * @param softwareID The software identifier, {@code null} if not 1186 * specified. 1187 */ 1188 public void setSoftwareID(final SoftwareID softwareID) { 1189 1190 this.softwareID = softwareID; 1191 } 1192 1193 1194 /** 1195 * Gets the version identifier for the OAuth 2.0 client software. 1196 * Corresponds to the {@code software_version} client metadata field. 1197 * 1198 * @return The version identifier, {@code null} if not specified. 1199 */ 1200 public SoftwareVersion getSoftwareVersion() { 1201 1202 return softwareVersion; 1203 } 1204 1205 1206 /** 1207 * Sets the version identifier for the OAuth 2.0 client software. 1208 * Corresponds to the {@code software_version} client metadata field. 1209 * 1210 * @param softwareVersion The version identifier, {@code null} if not 1211 * specified. 1212 */ 1213 public void setSoftwareVersion(final SoftwareVersion softwareVersion) { 1214 1215 this.softwareVersion = softwareVersion; 1216 } 1217 1218 1219 /** 1220 * Sets the preference for TLS client certificate bound access tokens. 1221 * Corresponds to the 1222 * {@code tls_client_certificate_bound_access_tokens} client metadata 1223 * field. 1224 * 1225 * @return {@code true} indicates a preference for TLS client 1226 * certificate bound access tokens, {@code false} if none. 1227 */ 1228 public boolean getTLSClientCertificateBoundAccessTokens() { 1229 1230 return tlsClientCertificateBoundAccessTokens; 1231 } 1232 1233 1234 /** 1235 * Gets the preference for TLS client certificate bound access tokens. 1236 * Corresponds to the 1237 * {@code tls_client_certificate_bound_access_tokens} client metadata 1238 * field. 1239 * 1240 * @param tlsClientCertBoundTokens {@code true} indicates a preference 1241 * for TLS client certificate bound 1242 * access tokens, {@code false} if 1243 * none. 1244 */ 1245 public void setTLSClientCertificateBoundAccessTokens(final boolean tlsClientCertBoundTokens) { 1246 1247 tlsClientCertificateBoundAccessTokens = tlsClientCertBoundTokens; 1248 } 1249 1250 1251 /** 1252 * Sets the preference for TLS client certificate bound access tokens. 1253 * Corresponds to the 1254 * {@code tls_client_certificate_bound_access_tokens} client metadata 1255 * field. 1256 * 1257 * @return {@code true} indicates a preference for TLS client 1258 * certificate bound access tokens, {@code false} if none. 1259 */ 1260 @Deprecated 1261 public boolean getMutualTLSSenderConstrainedAccessTokens() { 1262 1263 return tlsClientCertificateBoundAccessTokens; 1264 } 1265 1266 1267 /** 1268 * Gets the preference for TLS client certificate bound access tokens. 1269 * Corresponds to the 1270 * {@code tls_client_certificate_bound_access_tokens} client metadata 1271 * field. 1272 * 1273 * @param tlsSenderAccessTokens {@code true} indicates a preference for 1274 * TLS client certificate bound access 1275 * tokens, {@code false} if none. 1276 */ 1277 @Deprecated 1278 public void setMutualTLSSenderConstrainedAccessTokens(final boolean tlsSenderAccessTokens) { 1279 1280 tlsClientCertificateBoundAccessTokens = tlsSenderAccessTokens; 1281 } 1282 1283 1284 /** 1285 * Gets the expected subject distinguished name (DN) of the client 1286 * X.509 certificate in mutual TLS authentication. Corresponds to the 1287 * {@code tls_client_auth_subject_dn} client metadata field. 1288 * 1289 * @return The expected subject distinguished name (DN) of the client 1290 * X.509 certificate, {@code null} if not specified. 1291 */ 1292 public String getTLSClientAuthSubjectDN() { 1293 1294 return tlsClientAuthSubjectDN; 1295 } 1296 1297 1298 /** 1299 * Sets the expected subject distinguished name (DN) of the client 1300 * X.509 certificate in mutual TLS authentication. Corresponds to the 1301 * {@code tls_client_auth_subject_dn} client metadata field. 1302 * 1303 * @param subjectDN The expected subject distinguished name (DN) of the 1304 * client X.509 certificate, {@code null} if not 1305 * specified. 1306 */ 1307 public void setTLSClientAuthSubjectDN(final String subjectDN) { 1308 1309 this.tlsClientAuthSubjectDN = subjectDN; 1310 } 1311 1312 1313 /** 1314 * Gets the expected dNSName SAN entry in the X.509 certificate, which 1315 * the OAuth client will use in mutual TLS authentication. Corresponds 1316 * to the {@code tls_client_auth_san_dns} client metadata field. 1317 * 1318 * @return The expected dNSName SAN entry in the X.509 certificate, 1319 * {@code null} if not specified. 1320 */ 1321 public String getTLSClientAuthSanDNS() { 1322 1323 return tlsClientAuthSanDNS; 1324 } 1325 1326 1327 /** 1328 * Sets the expected dNSName SAN entry in the X.509 certificate, which 1329 * the OAuth client will use in mutual TLS authentication. Corresponds 1330 * to the {@code tls_client_auth_san_dns} client metadata field. 1331 * 1332 * @param dns The expected dNSName SAN entry in the X.509 certificate, 1333 * {@code null} if not specified. 1334 */ 1335 public void setTLSClientAuthSanDNS(final String dns) { 1336 1337 this.tlsClientAuthSanDNS = dns; 1338 } 1339 1340 1341 /** 1342 * Gets the expected uniformResourceIdentifier SAN entry in the X.509 1343 * certificate, which the OAuth client will use in mutual TLS 1344 * authentication. Corresponds to the {@code tls_client_auth_san_uri} 1345 * client metadata field. 1346 * 1347 * @return The expected uniformResourceIdentifier SAN entry in the X.509 1348 * certificate, {@code null} if not specified. 1349 */ 1350 public String getTLSClientAuthSanURI() { 1351 1352 return tlsClientAuthSanURI; 1353 } 1354 1355 1356 /** 1357 * Sets the expected uniformResourceIdentifier SAN entry in the X.509 1358 * certificate, which the OAuth client will use in mutual TLS 1359 * authentication. Corresponds to the {@code tls_client_auth_san_uri} 1360 * client metadata field. 1361 * 1362 * @param uri The expected uniformResourceIdentifier SAN entry in the X.509 1363 * certificate, {@code null} if not specified. 1364 */ 1365 public void setTLSClientAuthSanURI(final String uri) { 1366 1367 this.tlsClientAuthSanURI = uri; 1368 } 1369 1370 1371 /** 1372 * Gets the expected iPAddress SAN entry in the X.509 certificate, which 1373 * the OAuth client will use in mutual TLS authentication. Corresponds 1374 * to the {@code tls_client_auth_san_ip} client metadata field. 1375 * 1376 * @return The expected iPAddress SAN entry in the X.509 certificate, 1377 * {@code null} if not specified. 1378 */ 1379 public String getTLSClientAuthSanIP() { 1380 1381 return tlsClientAuthSanIP; 1382 } 1383 1384 1385 /** 1386 * Sets the expected iPAddress SAN entry in the X.509 certificate, which 1387 * the OAuth client will use in mutual TLS authentication. Corresponds 1388 * to the {@code tls_client_auth_san_ip} client metadata field. 1389 * 1390 * @param ip The expected iPAddress SAN entry in the X.509 1391 * certificate, {@code null} if not specified. 1392 */ 1393 public void setTLSClientAuthSanIP(final String ip) { 1394 1395 this.tlsClientAuthSanIP = ip; 1396 } 1397 1398 1399 /** 1400 * Gets the expected rfc822Name SAN entry in the X.509 certificate, which 1401 * the OAuth client will use in mutual TLS authentication. Corresponds 1402 * to the {@code tls_client_auth_san_email} client metadata field. 1403 * 1404 * @return The expected rfc822Name SAN entry in the X.509 certificate, 1405 * {@code null} if not specified. 1406 */ 1407 public String getTLSClientAuthSanEmail() { 1408 1409 return tlsClientAuthSanEmail; 1410 } 1411 1412 1413 /** 1414 * Sets the expected rfc822Name SAN entry in the X.509 certificate, which 1415 * the OAuth client will use in mutual TLS authentication. Corresponds 1416 * to the {@code tls_client_auth_san_email} client metadata field. 1417 * 1418 * @param email The expected rfc822Name SAN entry in the X.509 1419 * certificate, {@code null} if not specified. 1420 */ 1421 public void setTLSClientAuthSanEmail(final String email) { 1422 1423 this.tlsClientAuthSanEmail = email; 1424 } 1425 1426 1427 /** 1428 * Ensures that for {@code tls_client_auth} a certificate field for the 1429 * subject is specified. See 1430 * https://www.rfc-editor.org/rfc/rfc8705.html#section-2.1.2 1431 */ 1432 private void ensureExactlyOneCertSubjectFieldForTLSClientAuth() 1433 throws IllegalStateException { 1434 1435 if (! ClientAuthenticationMethod.TLS_CLIENT_AUTH.equals(getTokenEndpointAuthMethod())) { 1436 // Not tls_client_auth, ignore 1437 return; 1438 } 1439 1440 if (tlsClientAuthSubjectDN == null && tlsClientAuthSanDNS == null && tlsClientAuthSanURI == null && tlsClientAuthSanIP == null && tlsClientAuthSanEmail == null) { 1441 throw new IllegalStateException("A certificate field must be specified to indicate the subject in tls_client_auth: " + 1442 "tls_client_auth_subject_dn, tls_client_auth_san_dns, tls_client_auth_san_uri, tls_client_auth_san_ip or tls_client_auth_san_email"); 1443 } 1444 1445 String exceptionMessage = "Exactly one certificate field must be specified to indicate the subject in tls_client_auth: " + 1446 "tls_client_auth_subject_dn, tls_client_auth_san_dns, tls_client_auth_san_uri, tls_client_auth_san_ip or tls_client_auth_san_email"; 1447 1448 if (tlsClientAuthSubjectDN != null) { 1449 if (tlsClientAuthSanDNS != null || tlsClientAuthSanURI != null || tlsClientAuthSanIP != null || tlsClientAuthSanEmail != null) { 1450 throw new IllegalStateException(exceptionMessage); 1451 } 1452 } 1453 1454 if (tlsClientAuthSanDNS != null) { 1455 if (tlsClientAuthSanURI != null || tlsClientAuthSanIP != null || tlsClientAuthSanEmail != null) { 1456 throw new IllegalStateException(exceptionMessage); 1457 } 1458 } 1459 1460 if (tlsClientAuthSanURI != null) { 1461 if (tlsClientAuthSanIP != null || tlsClientAuthSanEmail != null) { 1462 throw new IllegalStateException(exceptionMessage); 1463 } 1464 } 1465 1466 if (tlsClientAuthSanIP != null) { 1467 if (tlsClientAuthSanEmail != null) { 1468 throw new IllegalStateException(exceptionMessage); 1469 } 1470 } 1471 } 1472 1473 1474 /** 1475 * Gets the JWS algorithm for JWT-encoded authorisation responses. 1476 * Corresponds to the {@code authorization_signed_response_alg} client 1477 * metadata field. 1478 * 1479 * @return The JWS algorithm, {@code null} if not specified. 1480 */ 1481 public JWSAlgorithm getAuthorizationJWSAlg() { 1482 1483 return authzJWSAlg; 1484 } 1485 1486 1487 /** 1488 * Sets the JWS algorithm for JWT-encoded authorisation responses. 1489 * Corresponds to the {@code authorization_signed_response_alg} client 1490 * metadata field. 1491 * 1492 * @param authzJWSAlg The JWS algorithm, {@code null} if not specified. 1493 * Must not be {@code "none"}. 1494 */ 1495 public void setAuthorizationJWSAlg(final JWSAlgorithm authzJWSAlg) { 1496 1497 if (new JWSAlgorithm("none").equals(authzJWSAlg)) { 1498 // Prevent passing none as JWS alg 1499 throw new IllegalArgumentException("The JWS algorithm must not be \"none\""); 1500 } 1501 1502 this.authzJWSAlg = authzJWSAlg; 1503 } 1504 1505 1506 /** 1507 * Gets the JWE algorithm for JWT-encoded authorisation responses. 1508 * Corresponds to the {@code authorization_encrypted_response_alg} 1509 * client metadata field. 1510 * 1511 * @return The JWE algorithm, {@code null} if not specified. 1512 */ 1513 public JWEAlgorithm getAuthorizationJWEAlg() { 1514 1515 return authzJWEAlg; 1516 } 1517 1518 1519 /** 1520 * Sets the JWE algorithm for JWT-encoded authorisation responses. 1521 * Corresponds to the {@code authorization_encrypted_response_alg} 1522 * client metadata field. 1523 * 1524 * @param authzJWEAlg The JWE algorithm, {@code null} if not specified. 1525 */ 1526 public void setAuthorizationJWEAlg(final JWEAlgorithm authzJWEAlg) { 1527 1528 this.authzJWEAlg = authzJWEAlg; 1529 } 1530 1531 1532 /** 1533 * Sets the encryption method for JWT-encoded authorisation responses. 1534 * Corresponds to the {@code authorization_encrypted_response_enc} 1535 * client metadata field. 1536 * 1537 * @return The encryption method, {@code null} if specified. 1538 */ 1539 public EncryptionMethod getAuthorizationJWEEnc() { 1540 1541 return authzJWEEnc; 1542 } 1543 1544 1545 /** 1546 * Sets the encryption method for JWT-encoded authorisation responses. 1547 * Corresponds to the {@code authorization_encrypted_response_enc} 1548 * client metadata field. 1549 * 1550 * @param authzJWEEnc The encryption method, {@code null} if specified. 1551 */ 1552 public void setAuthorizationJWEEnc(final EncryptionMethod authzJWEEnc) { 1553 1554 this.authzJWEEnc = authzJWEEnc; 1555 } 1556 1557 1558 /** 1559 * Gets the supported OpenID Connect Federation 1.0 types. Corresponds 1560 * to the {@code federation_type} metadata field. 1561 * 1562 * @return The supported federation types, {@code null} if not 1563 * specified. 1564 */ 1565 public List<FederationType> getFederationTypes() { 1566 1567 return federationTypes; 1568 } 1569 1570 1571 /** 1572 * Sets the supported OpenID Connect Federation 1.0 types. Corresponds 1573 * to the {@code federation_type} metadata field. 1574 * 1575 * @param federationTypes The supported federation types, {@code null} 1576 * if not specified. 1577 */ 1578 public void setFederationTypes(final List<FederationType> federationTypes) { 1579 1580 this.federationTypes = federationTypes; 1581 } 1582 1583 1584 /** 1585 * Gets the organisation name in OpenID Connect Federation 1.0. 1586 * Corresponds to the {@code organization_name} metadata field. 1587 * 1588 * @return The organisation name, {@code null} if not specified. 1589 */ 1590 public String getOrganizationName() { 1591 1592 return organizationName; 1593 } 1594 1595 1596 /** 1597 * Sets the organisation name in OpenID Connect Federation 1.0. 1598 * Corresponds to the {@code organization_name} metadata field. 1599 * 1600 * @param organizationName The organisation name, {@code null} if not 1601 * specified. 1602 */ 1603 public void setOrganizationName(final String organizationName) { 1604 1605 this.organizationName = organizationName; 1606 } 1607 1608 1609 /** 1610 * Gets the used trust anchor in a explicit client registration in 1611 * OpenID Connect Federation 1.0. Corresponds to the 1612 * {@code trust_anchor_id} client metadata field. 1613 * 1614 * @return The trust anchor ID, {@code null} if not specified. 1615 */ 1616 public EntityID getTrustAnchorID() { 1617 1618 return trustAnchorID; 1619 } 1620 1621 1622 /** 1623 * Sets the used trust anchor in a explicit client registration in 1624 * OpenID Connect Federation 1.0. Corresponds to the 1625 * {@code trust_anchor_id} client metadata field. 1626 * 1627 * @param trustAnchorID The trust anchor ID, {@code null} if not 1628 * specified. 1629 */ 1630 public void setTrustAnchorID(final EntityID trustAnchorID) { 1631 1632 this.trustAnchorID = trustAnchorID; 1633 } 1634 1635 1636 /** 1637 * Gets the specified custom metadata field. 1638 * 1639 * @param name The field name. Must not be {@code null}. 1640 * 1641 * @return The field value, typically serialisable to a JSON entity, 1642 * {@code null} if none. 1643 */ 1644 public Object getCustomField(final String name) { 1645 1646 return customFields.get(name); 1647 } 1648 1649 1650 /** 1651 * Gets the custom metadata fields. 1652 * 1653 * @return The custom metadata fields, as a JSON object, empty object 1654 * if none. 1655 */ 1656 public JSONObject getCustomFields() { 1657 1658 return customFields; 1659 } 1660 1661 1662 /** 1663 * Sets the specified custom metadata field. 1664 * 1665 * @param name The field name. Must not be {@code null}. 1666 * @param value The field value. Should serialise to a JSON entity. 1667 */ 1668 public void setCustomField(final String name, final Object value) { 1669 1670 customFields.put(name, value); 1671 } 1672 1673 1674 /** 1675 * Sets the custom metadata fields. 1676 * 1677 * @param customFields The custom metadata fields, as a JSON object, 1678 * empty object if none. Must not be {@code null}. 1679 */ 1680 public void setCustomFields(final JSONObject customFields) { 1681 1682 if (customFields == null) 1683 throw new IllegalArgumentException("The custom fields JSON object must not be null"); 1684 1685 this.customFields = customFields; 1686 } 1687 1688 1689 /** 1690 * Applies the client metadata defaults where no values have been 1691 * specified. 1692 * 1693 * <ul> 1694 * <li>The response types default to {@code ["code"]}. 1695 * <li>The grant types default to {@code ["authorization_code"]}. 1696 * <li>The client authentication method defaults to 1697 * "client_secret_basic", unless the grant type is "implicit" 1698 * only. 1699 * <li>The encryption method for JWT-encoded authorisation 1700 * responses defaults to {@code A128CBC-HS256} if a JWE 1701 * algorithm is set. 1702 * </ul> 1703 */ 1704 public void applyDefaults() { 1705 1706 if (responseTypes == null) { 1707 responseTypes = new HashSet<>(); 1708 responseTypes.add(ResponseType.getDefault()); 1709 } 1710 1711 if (grantTypes == null) { 1712 grantTypes = new HashSet<>(); 1713 grantTypes.add(GrantType.AUTHORIZATION_CODE); 1714 } 1715 1716 if (authMethod == null) { 1717 1718 if (grantTypes.contains(GrantType.IMPLICIT) && grantTypes.size() == 1) { 1719 authMethod = ClientAuthenticationMethod.NONE; 1720 } else { 1721 authMethod = ClientAuthenticationMethod.getDefault(); 1722 } 1723 } 1724 1725 if (authzJWEAlg != null && authzJWEEnc == null) { 1726 authzJWEEnc = EncryptionMethod.A128CBC_HS256; 1727 } 1728 } 1729 1730 1731 /** 1732 * Returns the JSON object representation of this client metadata, 1733 * including any custom fields. 1734 * 1735 * @return The JSON object. 1736 */ 1737 public JSONObject toJSONObject() { 1738 1739 return toJSONObject(true); 1740 } 1741 1742 1743 /** 1744 * Returns the JSON object representation of this client metadata. 1745 * 1746 * @param includeCustomFields {@code true} to include any custom 1747 * metadata fields, {@code false} to omit 1748 * them. 1749 * 1750 * @return The JSON object. 1751 */ 1752 public JSONObject toJSONObject(final boolean includeCustomFields) { 1753 1754 JSONObject o; 1755 1756 if (includeCustomFields) 1757 o = new JSONObject(customFields); 1758 else 1759 o = new JSONObject(); 1760 1761 1762 if (redirectURIs != null) { 1763 1764 JSONArray uriList = new JSONArray(); 1765 1766 for (URI uri: redirectURIs) 1767 uriList.add(uri.toString()); 1768 1769 o.put("redirect_uris", uriList); 1770 } 1771 1772 1773 if (scope != null) 1774 o.put("scope", scope.toString()); 1775 1776 1777 if (responseTypes != null) { 1778 1779 JSONArray rtList = new JSONArray(); 1780 1781 for (ResponseType rt: responseTypes) 1782 rtList.add(rt.toString()); 1783 1784 o.put("response_types", rtList); 1785 } 1786 1787 1788 if (grantTypes != null) { 1789 1790 JSONArray grantList = new JSONArray(); 1791 1792 for (GrantType grant: grantTypes) 1793 grantList.add(grant.toString()); 1794 1795 o.put("grant_types", grantList); 1796 } 1797 1798 1799 if (contacts != null) { 1800 o.put("contacts", contacts); 1801 } 1802 1803 1804 if (! nameEntries.isEmpty()) { 1805 1806 for (Map.Entry<LangTag,String> entry: nameEntries.entrySet()) { 1807 1808 LangTag langTag = entry.getKey(); 1809 String name = entry.getValue(); 1810 1811 if (name == null) 1812 continue; 1813 1814 if (langTag == null) 1815 o.put("client_name", entry.getValue()); 1816 else 1817 o.put("client_name#" + langTag, entry.getValue()); 1818 } 1819 } 1820 1821 1822 if (! logoURIEntries.isEmpty()) { 1823 1824 for (Map.Entry<LangTag,URI> entry: logoURIEntries.entrySet()) { 1825 1826 LangTag langTag = entry.getKey(); 1827 URI uri = entry.getValue(); 1828 1829 if (uri == null) 1830 continue; 1831 1832 if (langTag == null) 1833 o.put("logo_uri", entry.getValue().toString()); 1834 else 1835 o.put("logo_uri#" + langTag, entry.getValue().toString()); 1836 } 1837 } 1838 1839 1840 if (! uriEntries.isEmpty()) { 1841 1842 for (Map.Entry<LangTag,URI> entry: uriEntries.entrySet()) { 1843 1844 LangTag langTag = entry.getKey(); 1845 URI uri = entry.getValue(); 1846 1847 if (uri == null) 1848 continue; 1849 1850 if (langTag == null) 1851 o.put("client_uri", entry.getValue().toString()); 1852 else 1853 o.put("client_uri#" + langTag, entry.getValue().toString()); 1854 } 1855 } 1856 1857 1858 if (! policyURIEntries.isEmpty()) { 1859 1860 for (Map.Entry<LangTag,URI> entry: policyURIEntries.entrySet()) { 1861 1862 LangTag langTag = entry.getKey(); 1863 URI uri = entry.getValue(); 1864 1865 if (uri == null) 1866 continue; 1867 1868 if (langTag == null) 1869 o.put("policy_uri", entry.getValue().toString()); 1870 else 1871 o.put("policy_uri#" + langTag, entry.getValue().toString()); 1872 } 1873 } 1874 1875 1876 if (! tosURIEntries.isEmpty()) { 1877 1878 for (Map.Entry<LangTag,URI> entry: tosURIEntries.entrySet()) { 1879 1880 LangTag langTag = entry.getKey(); 1881 URI uri = entry.getValue(); 1882 1883 if (uri == null) 1884 continue; 1885 1886 if (langTag == null) 1887 o.put("tos_uri", entry.getValue().toString()); 1888 else 1889 o.put("tos_uri#" + langTag, entry.getValue().toString()); 1890 } 1891 } 1892 1893 1894 if (authMethod != null) 1895 o.put("token_endpoint_auth_method", authMethod.toString()); 1896 1897 1898 if (authJWSAlg != null) 1899 o.put("token_endpoint_auth_signing_alg", authJWSAlg.getName()); 1900 1901 1902 if (jwkSetURI != null) 1903 o.put("jwks_uri", jwkSetURI.toString()); 1904 1905 1906 if (jwkSet != null) 1907 o.put("jwks", jwkSet.toJSONObject(true)); // prevent private keys from leaking 1908 1909 1910 if (requestObjectURIs != null) { 1911 1912 JSONArray uriList = new JSONArray(); 1913 1914 for (URI uri: requestObjectURIs) 1915 uriList.add(uri.toString()); 1916 1917 o.put("request_uris", uriList); 1918 } 1919 1920 1921 if (requestObjectJWSAlg != null) 1922 o.put("request_object_signing_alg", requestObjectJWSAlg.getName()); 1923 1924 if (requestObjectJWEAlg != null) 1925 o.put("request_object_encryption_alg", requestObjectJWEAlg.getName()); 1926 1927 if (requestObjectJWEEnc != null) 1928 o.put("request_object_encryption_enc", requestObjectJWEEnc.getName()); 1929 1930 1931 if (softwareID != null) 1932 o.put("software_id", softwareID.getValue()); 1933 1934 if (softwareVersion != null) 1935 o.put("software_version", softwareVersion.getValue()); 1936 1937 if (getTLSClientCertificateBoundAccessTokens()) { 1938 o.put("tls_client_certificate_bound_access_tokens", tlsClientCertificateBoundAccessTokens); 1939 } 1940 1941 if (tlsClientAuthSubjectDN != null) 1942 o.put("tls_client_auth_subject_dn", tlsClientAuthSubjectDN); 1943 1944 if (tlsClientAuthSanDNS != null) 1945 o.put("tls_client_auth_san_dns", tlsClientAuthSanDNS); 1946 1947 if (tlsClientAuthSanURI != null) 1948 o.put("tls_client_auth_san_uri", tlsClientAuthSanURI); 1949 1950 if (tlsClientAuthSanIP != null) 1951 o.put("tls_client_auth_san_ip", tlsClientAuthSanIP); 1952 1953 if (tlsClientAuthSanEmail != null) 1954 o.put("tls_client_auth_san_email", tlsClientAuthSanEmail); 1955 1956 if (authzJWSAlg != null) { 1957 o.put("authorization_signed_response_alg", authzJWSAlg.getName()); 1958 } 1959 1960 if (authzJWEAlg != null) { 1961 o.put("authorization_encrypted_response_alg", authzJWEAlg.getName()); 1962 } 1963 1964 if (authzJWEEnc != null) { 1965 o.put("authorization_encrypted_response_enc", authzJWEEnc.getName()); 1966 } 1967 1968 // Federation 1969 1970 if (CollectionUtils.isNotEmpty(federationTypes)) { 1971 o.put("federation_type", Identifier.toStringList(federationTypes)); 1972 } 1973 if (organizationName != null) { 1974 o.put("organization_name", organizationName); 1975 } 1976 1977 if (trustAnchorID != null) { 1978 o.put("trust_anchor_id", trustAnchorID.getValue()); 1979 } 1980 1981 return o; 1982 } 1983 1984 1985 @Override 1986 public String toString() { 1987 return toJSONObject().toJSONString(); 1988 } 1989 1990 1991 /** 1992 * Parses an client metadata instance from the specified JSON object. 1993 * 1994 * @param jsonObject The JSON object to parse. Must not be 1995 * {@code null}. 1996 * 1997 * @return The client metadata. 1998 * 1999 * @throws ParseException If the JSON object couldn't be parsed to a 2000 * client metadata instance. 2001 */ 2002 public static ClientMetadata parse(final JSONObject jsonObject) 2003 throws ParseException { 2004 2005 // Copy JSON object, then parse 2006 return parseFromModifiableJSONObject(new JSONObject(jsonObject)); 2007 } 2008 2009 2010 /** 2011 * Parses an client metadata instance from the specified JSON object. 2012 * 2013 * @param jsonObject The JSON object to parse, will be modified by 2014 * the parse routine. Must not be {@code null}. 2015 * 2016 * @return The client metadata. 2017 * 2018 * @throws ParseException If the JSON object couldn't be parsed to a 2019 * client metadata instance. 2020 */ 2021 private static ClientMetadata parseFromModifiableJSONObject(final JSONObject jsonObject) 2022 throws ParseException { 2023 2024 ClientMetadata metadata = new ClientMetadata(); 2025 2026 if (jsonObject.get("redirect_uris") != null) { 2027 2028 Set<URI> redirectURIs = new LinkedHashSet<>(); 2029 2030 for (String uriString: JSONObjectUtils.getStringArray(jsonObject, "redirect_uris")) { 2031 URI uri; 2032 try { 2033 uri = new URI(uriString); 2034 } catch (URISyntaxException e) { 2035 throw new ParseException("Invalid \"redirect_uris\" parameter: " + e.getMessage(), RegistrationError.INVALID_REDIRECT_URI.appendDescription(": " + e.getMessage())); 2036 } 2037 2038 if (uri.getFragment() != null) { 2039 String detail = "URI must not contain fragment"; 2040 throw new ParseException("Invalid \"redirect_uris\" parameter: " + detail, RegistrationError.INVALID_REDIRECT_URI.appendDescription(": " + detail)); 2041 } 2042 2043 redirectURIs.add(uri); 2044 } 2045 2046 metadata.setRedirectionURIs(redirectURIs); 2047 jsonObject.remove("redirect_uris"); 2048 } 2049 2050 try { 2051 2052 if (jsonObject.get("scope") != null) { 2053 metadata.setScope(Scope.parse(JSONObjectUtils.getString(jsonObject, "scope"))); 2054 jsonObject.remove("scope"); 2055 } 2056 2057 2058 if (jsonObject.get("response_types") != null) { 2059 2060 Set<ResponseType> responseTypes = new LinkedHashSet<>(); 2061 2062 for (String rt : JSONObjectUtils.getStringArray(jsonObject, "response_types")) { 2063 2064 responseTypes.add(ResponseType.parse(rt)); 2065 } 2066 2067 metadata.setResponseTypes(responseTypes); 2068 jsonObject.remove("response_types"); 2069 } 2070 2071 2072 if (jsonObject.get("grant_types") != null) { 2073 2074 Set<GrantType> grantTypes = new LinkedHashSet<>(); 2075 2076 for (String grant : JSONObjectUtils.getStringArray(jsonObject, "grant_types")) { 2077 2078 grantTypes.add(GrantType.parse(grant)); 2079 } 2080 2081 metadata.setGrantTypes(grantTypes); 2082 jsonObject.remove("grant_types"); 2083 } 2084 2085 2086 if (jsonObject.get("contacts") != null) { 2087 metadata.setEmailContacts(JSONObjectUtils.getStringList(jsonObject, "contacts")); 2088 jsonObject.remove("contacts"); 2089 } 2090 2091 2092 // Find lang-tagged client_name params 2093 Map<LangTag, Object> matches = LangTagUtils.find("client_name", jsonObject); 2094 2095 for (Map.Entry<LangTag, Object> entry : matches.entrySet()) { 2096 2097 try { 2098 metadata.setName((String) entry.getValue(), entry.getKey()); 2099 2100 } catch (ClassCastException e) { 2101 2102 throw new ParseException("Invalid \"client_name\" (language tag) parameter"); 2103 } 2104 2105 removeMember(jsonObject, "client_name", entry.getKey()); 2106 } 2107 2108 2109 matches = LangTagUtils.find("logo_uri", jsonObject); 2110 2111 for (Map.Entry<LangTag, Object> entry : matches.entrySet()) { 2112 2113 if (entry.getValue() == null) continue; 2114 2115 try { 2116 metadata.setLogoURI(new URI((String) entry.getValue()), entry.getKey()); 2117 2118 } catch (Exception e) { 2119 2120 throw new ParseException("Invalid \"logo_uri\" (language tag) parameter"); 2121 } 2122 2123 removeMember(jsonObject, "logo_uri", entry.getKey()); 2124 } 2125 2126 2127 matches = LangTagUtils.find("client_uri", jsonObject); 2128 2129 for (Map.Entry<LangTag, Object> entry : matches.entrySet()) { 2130 2131 if (entry.getValue() == null) continue; 2132 2133 try { 2134 metadata.setURI(new URI((String) entry.getValue()), entry.getKey()); 2135 2136 2137 } catch (Exception e) { 2138 2139 throw new ParseException("Invalid \"client_uri\" (language tag) parameter"); 2140 } 2141 2142 removeMember(jsonObject, "client_uri", entry.getKey()); 2143 } 2144 2145 2146 matches = LangTagUtils.find("policy_uri", jsonObject); 2147 2148 for (Map.Entry<LangTag, Object> entry : matches.entrySet()) { 2149 2150 if (entry.getValue() == null) continue; 2151 2152 try { 2153 metadata.setPolicyURI(new URI((String) entry.getValue()), entry.getKey()); 2154 2155 } catch (Exception e) { 2156 2157 throw new ParseException("Invalid \"policy_uri\" (language tag) parameter"); 2158 } 2159 2160 removeMember(jsonObject, "policy_uri", entry.getKey()); 2161 } 2162 2163 2164 matches = LangTagUtils.find("tos_uri", jsonObject); 2165 2166 for (Map.Entry<LangTag, Object> entry : matches.entrySet()) { 2167 2168 if (entry.getValue() == null) continue; 2169 2170 try { 2171 metadata.setTermsOfServiceURI(new URI((String) entry.getValue()), entry.getKey()); 2172 2173 } catch (Exception e) { 2174 2175 throw new ParseException("Invalid \"tos_uri\" (language tag) parameter"); 2176 } 2177 2178 removeMember(jsonObject, "tos_uri", entry.getKey()); 2179 } 2180 2181 2182 if (jsonObject.get("token_endpoint_auth_method") != null) { 2183 metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.parse( 2184 JSONObjectUtils.getString(jsonObject, "token_endpoint_auth_method"))); 2185 2186 jsonObject.remove("token_endpoint_auth_method"); 2187 } 2188 2189 2190 if (jsonObject.get("token_endpoint_auth_signing_alg") != null) { 2191 metadata.setTokenEndpointAuthJWSAlg(JWSAlgorithm.parse( 2192 JSONObjectUtils.getString(jsonObject, "token_endpoint_auth_signing_alg"))); 2193 2194 jsonObject.remove("token_endpoint_auth_signing_alg"); 2195 } 2196 2197 2198 if (jsonObject.get("jwks_uri") != null) { 2199 metadata.setJWKSetURI(JSONObjectUtils.getURI(jsonObject, "jwks_uri")); 2200 jsonObject.remove("jwks_uri"); 2201 } 2202 2203 if (jsonObject.get("jwks") != null) { 2204 2205 try { 2206 metadata.setJWKSet(JWKSet.parse(JSONObjectUtils.getJSONObject(jsonObject, "jwks"))); 2207 2208 } catch (java.text.ParseException e) { 2209 throw new ParseException(e.getMessage(), e); 2210 } 2211 2212 jsonObject.remove("jwks"); 2213 } 2214 2215 if (jsonObject.get("request_uris") != null) { 2216 2217 Set<URI> requestURIs = new LinkedHashSet<>(); 2218 2219 for (String uriString : JSONObjectUtils.getStringArray(jsonObject, "request_uris")) { 2220 2221 try { 2222 requestURIs.add(new URI(uriString)); 2223 2224 } catch (URISyntaxException e) { 2225 2226 throw new ParseException("Invalid \"request_uris\" parameter"); 2227 } 2228 } 2229 2230 metadata.setRequestObjectURIs(requestURIs); 2231 jsonObject.remove("request_uris"); 2232 } 2233 2234 if (jsonObject.get("request_object_signing_alg") != null) { 2235 metadata.setRequestObjectJWSAlg(JWSAlgorithm.parse( 2236 JSONObjectUtils.getString(jsonObject, "request_object_signing_alg"))); 2237 2238 jsonObject.remove("request_object_signing_alg"); 2239 } 2240 2241 if (jsonObject.get("request_object_encryption_alg") != null) { 2242 metadata.setRequestObjectJWEAlg(JWEAlgorithm.parse( 2243 JSONObjectUtils.getString(jsonObject, "request_object_encryption_alg"))); 2244 2245 jsonObject.remove("request_object_encryption_alg"); 2246 } 2247 2248 if (jsonObject.get("request_object_encryption_enc") != null) { 2249 metadata.setRequestObjectJWEEnc(EncryptionMethod.parse( 2250 JSONObjectUtils.getString(jsonObject, "request_object_encryption_enc"))); 2251 2252 jsonObject.remove("request_object_encryption_enc"); 2253 } 2254 2255 if (jsonObject.get("software_id") != null) { 2256 metadata.setSoftwareID(new SoftwareID(JSONObjectUtils.getString(jsonObject, "software_id"))); 2257 jsonObject.remove("software_id"); 2258 } 2259 2260 if (jsonObject.get("software_version") != null) { 2261 metadata.setSoftwareVersion(new SoftwareVersion(JSONObjectUtils.getString(jsonObject, "software_version"))); 2262 jsonObject.remove("software_version"); 2263 } 2264 2265 if (jsonObject.get("tls_client_certificate_bound_access_tokens") != null) { 2266 metadata.setTLSClientCertificateBoundAccessTokens(JSONObjectUtils.getBoolean(jsonObject, "tls_client_certificate_bound_access_tokens")); 2267 jsonObject.remove("tls_client_certificate_bound_access_tokens"); 2268 } 2269 2270 if (jsonObject.get("tls_client_auth_subject_dn") != null) { 2271 metadata.setTLSClientAuthSubjectDN(JSONObjectUtils.getString(jsonObject, "tls_client_auth_subject_dn")); 2272 jsonObject.remove("tls_client_auth_subject_dn"); 2273 } 2274 2275 if (jsonObject.get("tls_client_auth_san_dns") != null) { 2276 metadata.setTLSClientAuthSanDNS(JSONObjectUtils.getString(jsonObject, "tls_client_auth_san_dns")); 2277 jsonObject.remove("tls_client_auth_san_dns"); 2278 } 2279 2280 if (jsonObject.get("tls_client_auth_san_uri") != null) { 2281 metadata.setTLSClientAuthSanURI(JSONObjectUtils.getString(jsonObject, "tls_client_auth_san_uri")); 2282 jsonObject.remove("tls_client_auth_san_uri"); 2283 } 2284 2285 if (jsonObject.get("tls_client_auth_san_ip") != null) { 2286 metadata.setTLSClientAuthSanIP(JSONObjectUtils.getString(jsonObject, "tls_client_auth_san_ip")); 2287 jsonObject.remove("tls_client_auth_san_ip"); 2288 } 2289 2290 if (jsonObject.get("tls_client_auth_san_email") != null) { 2291 metadata.setTLSClientAuthSanEmail(JSONObjectUtils.getString(jsonObject, "tls_client_auth_san_email")); 2292 jsonObject.remove("tls_client_auth_san_email"); 2293 } 2294 2295 metadata.ensureExactlyOneCertSubjectFieldForTLSClientAuth(); 2296 2297 if (jsonObject.get("authorization_signed_response_alg") != null) { 2298 metadata.setAuthorizationJWSAlg(JWSAlgorithm.parse(JSONObjectUtils.getString(jsonObject, "authorization_signed_response_alg"))); 2299 jsonObject.remove("authorization_signed_response_alg"); 2300 } 2301 2302 if (jsonObject.get("authorization_encrypted_response_alg") != null) { 2303 metadata.setAuthorizationJWEAlg(JWEAlgorithm.parse(JSONObjectUtils.getString(jsonObject, "authorization_encrypted_response_alg"))); 2304 jsonObject.remove("authorization_encrypted_response_alg"); 2305 } 2306 2307 if (jsonObject.get("authorization_encrypted_response_enc") != null) { 2308 metadata.setAuthorizationJWEEnc(EncryptionMethod.parse(JSONObjectUtils.getString(jsonObject, "authorization_encrypted_response_enc"))); 2309 jsonObject.remove("authorization_encrypted_response_enc"); 2310 } 2311 2312 // Federation 2313 2314 if (jsonObject.get("federation_type") != null) { 2315 List<FederationType> types = new LinkedList<>(); 2316 for (String v: JSONObjectUtils.getStringList(jsonObject, "federation_type")) { 2317 types.add(new FederationType(v)); 2318 } 2319 metadata.setFederationTypes(types); 2320 jsonObject.remove("federation_type"); 2321 } 2322 2323 if (jsonObject.get("organization_name") != null) { 2324 metadata.setOrganizationName(JSONObjectUtils.getString(jsonObject, "organization_name")); 2325 jsonObject.remove("organization_name"); 2326 } 2327 2328 if (jsonObject.get("trust_anchor_id") != null) { 2329 metadata.setTrustAnchorID(EntityID.parse(JSONObjectUtils.getString(jsonObject, "trust_anchor_id"))); 2330 jsonObject.remove("trust_anchor_id"); 2331 } 2332 2333 } catch (ParseException | IllegalStateException e) { 2334 // Insert client_client_metadata error code so that it 2335 // can be reported back to the client if we have a 2336 // registration event 2337 throw new ParseException(e.getMessage(), RegistrationError.INVALID_CLIENT_METADATA.appendDescription(": " + e.getMessage()), e.getCause()); 2338 } 2339 2340 // The remaining fields are custom 2341 metadata.customFields = jsonObject; 2342 2343 return metadata; 2344 } 2345 2346 2347 /** 2348 * Removes a JSON object member with the specified base name and 2349 * optional language tag. 2350 * 2351 * @param jsonObject The JSON object. Must not be {@code null}. 2352 * @param name The base member name. Must not be {@code null}. 2353 * @param langTag The language tag, {@code null} if none. 2354 */ 2355 private static void removeMember(final JSONObject jsonObject, final String name, final LangTag langTag) { 2356 2357 if (langTag == null) 2358 jsonObject.remove(name); 2359 else 2360 jsonObject.remove(name + "#" + langTag); 2361 } 2362}