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