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