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