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