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