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