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.as; 019 020 021import java.io.IOException; 022import java.net.MalformedURLException; 023import java.net.URI; 024import java.net.URISyntaxException; 025import java.net.URL; 026import java.util.*; 027 028import net.minidev.json.JSONObject; 029 030import com.nimbusds.jose.Algorithm; 031import com.nimbusds.jose.EncryptionMethod; 032import com.nimbusds.jose.JWEAlgorithm; 033import com.nimbusds.jose.JWSAlgorithm; 034import com.nimbusds.langtag.LangTag; 035import com.nimbusds.langtag.LangTagException; 036import com.nimbusds.oauth2.sdk.*; 037import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod; 038import com.nimbusds.oauth2.sdk.client.ClientType; 039import com.nimbusds.oauth2.sdk.http.HTTPRequest; 040import com.nimbusds.oauth2.sdk.http.HTTPResponse; 041import com.nimbusds.oauth2.sdk.id.Issuer; 042import com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod; 043import com.nimbusds.oauth2.sdk.util.CollectionUtils; 044import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 045import com.nimbusds.oauth2.sdk.util.URIUtils; 046 047 048/** 049 * OAuth 2.0 Authorisation Server (AS) metadata. 050 * 051 * <p>Related specifications: 052 * 053 * <ul> 054 * <li>OAuth 2.0 Authorization Server Metadata (RFC 8414) 055 * <li>OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound 056 * Access Tokens (RFC 8705) 057 * <li>OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer 058 * (DPoP) (draft-ietf-oauth-dpop-02) 059 * <li>Financial-grade API: JWT Secured Authorization Response Mode for 060 * OAuth 2.0 (JARM) 061 * <li>OAuth 2.0 Authorization Server Issuer Identifier in Authorization 062 * Response (draft-meyerzuselhausen-oauth-iss-auth-resp-01) 063 * <li>Financial-grade API - Part 2: Read and Write API Security Profile 064 * <li>OAuth 2.0 Pushed Authorization Requests (draft-ietf-oauth-par-02) 065 * <li>OAuth 2.0 Device Flow for Browserless and Input Constrained Devices 066 * (RFC 8628) 067 * <li>OAuth 2.0 Incremental Authorization 068 * (draft-ietf-oauth-incremental-authz-04) 069 * </ul> 070 */ 071public class AuthorizationServerMetadata extends AuthorizationServerEndpointMetadata { 072 073 /** 074 * The registered parameter names. 075 */ 076 private static final Set<String> REGISTERED_PARAMETER_NAMES; 077 078 079 static { 080 Set<String> p = new HashSet<>(AuthorizationServerEndpointMetadata.getRegisteredParameterNames()); 081 p.add("issuer"); 082 p.add("jwks_uri"); 083 p.add("scopes_supported"); 084 p.add("response_types_supported"); 085 p.add("response_modes_supported"); 086 p.add("grant_types_supported"); 087 p.add("code_challenge_methods_supported"); 088 p.add("token_endpoint_auth_methods_supported"); 089 p.add("token_endpoint_auth_signing_alg_values_supported"); 090 p.add("request_parameter_supported"); 091 p.add("request_uri_parameter_supported"); 092 p.add("require_request_uri_registration"); 093 p.add("request_object_signing_alg_values_supported"); 094 p.add("request_object_encryption_alg_values_supported"); 095 p.add("request_object_encryption_enc_values_supported"); 096 p.add("ui_locales_supported"); 097 p.add("service_documentation"); 098 p.add("op_policy_uri"); 099 p.add("op_tos_uri"); 100 p.add("introspection_endpoint_auth_methods_supported"); 101 p.add("introspection_endpoint_auth_signing_alg_values_supported"); 102 p.add("revocation_endpoint_auth_methods_supported"); 103 p.add("revocation_endpoint_auth_signing_alg_values_supported"); 104 p.add("mtls_endpoint_aliases"); 105 p.add("tls_client_certificate_bound_access_tokens"); 106 p.add("dpop_signing_alg_values_supported"); 107 p.add("authorization_signing_alg_values_supported"); 108 p.add("authorization_encryption_alg_values_supported"); 109 p.add("authorization_encryption_enc_values_supported"); 110 p.add("require_pushed_authorization_requests"); 111 p.add("incremental_authz_types_supported"); 112 p.add("authorization_response_iss_parameter_supported"); 113 REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p); 114 } 115 116 117 /** 118 * Gets the registered OpenID Connect provider metadata parameter 119 * names. 120 * 121 * @return The registered OpenID Connect provider metadata parameter 122 * names, as an unmodifiable set. 123 */ 124 public static Set<String> getRegisteredParameterNames() { 125 126 return REGISTERED_PARAMETER_NAMES; 127 } 128 129 130 /** 131 * The issuer. 132 */ 133 private final Issuer issuer; 134 135 136 /** 137 * The JWK set URI. 138 */ 139 private URI jwkSetURI; 140 141 142 /** 143 * The supported scope values. 144 */ 145 private Scope scope; 146 147 148 /** 149 * The supported response types. 150 */ 151 private List<ResponseType> rts; 152 153 154 /** 155 * The supported response modes. 156 */ 157 private List<ResponseMode> rms; 158 159 160 /** 161 * The supported grant types. 162 */ 163 private List<GrantType> gts; 164 165 166 /** 167 * The supported code challenge methods for PKCE. 168 */ 169 private List<CodeChallengeMethod> codeChallengeMethods; 170 171 172 /** 173 * The supported token endpoint authentication methods. 174 */ 175 private List<ClientAuthenticationMethod> tokenEndpointAuthMethods; 176 177 178 /** 179 * The supported JWS algorithms for the {@code private_key_jwt} and 180 * {@code client_secret_jwt} token endpoint authentication methods. 181 */ 182 private List<JWSAlgorithm> tokenEndpointJWSAlgs; 183 184 185 /** 186 * The supported introspection endpoint authentication methods. 187 */ 188 private List<ClientAuthenticationMethod> introspectionEndpointAuthMethods; 189 190 191 /** 192 * The supported JWS algorithms for the {@code private_key_jwt} and 193 * {@code client_secret_jwt} introspection endpoint authentication 194 * methods. 195 */ 196 private List<JWSAlgorithm> introspectionEndpointJWSAlgs; 197 198 199 /** 200 * The supported revocation endpoint authentication methods. 201 */ 202 private List<ClientAuthenticationMethod> revocationEndpointAuthMethods; 203 204 205 /** 206 * The supported JWS algorithms for the {@code private_key_jwt} and 207 * {@code client_secret_jwt} revocation endpoint authentication 208 * methods. 209 */ 210 private List<JWSAlgorithm> revocationEndpointJWSAlgs; 211 212 213 /** 214 * The supported JWS algorithms for request objects. 215 */ 216 private List<JWSAlgorithm> requestObjectJWSAlgs; 217 218 219 /** 220 * The supported JWE algorithms for request objects. 221 */ 222 private List<JWEAlgorithm> requestObjectJWEAlgs; 223 224 225 /** 226 * The supported encryption methods for request objects. 227 */ 228 private List<EncryptionMethod> requestObjectJWEEncs; 229 230 231 /** 232 * If {@code true} the {@code request} parameter is supported, else 233 * not. 234 */ 235 private boolean requestParamSupported = false; 236 237 238 /** 239 * If {@code true} the {@code request_uri} parameter is supported, else 240 * not. 241 */ 242 private boolean requestURIParamSupported = false; 243 244 245 /** 246 * If {@code true} the {@code request_uri} parameters must be 247 * pre-registered with the provider, else not. 248 */ 249 private boolean requireRequestURIReg = false; 250 251 252 /** 253 * If {@code true} the {@code iss} authorisation response is supported, 254 * else not. 255 */ 256 private boolean authzResponseIssParameterSupported = false; 257 258 259 /** 260 * The supported UI locales. 261 */ 262 private List<LangTag> uiLocales; 263 264 265 /** 266 * The service documentation URI. 267 */ 268 private URI serviceDocsURI; 269 270 271 /** 272 * The provider's policy regarding relying party use of data. 273 */ 274 private URI policyURI; 275 276 277 /** 278 * The provider's terms of service. 279 */ 280 private URI tosURI; 281 282 283 /** 284 * Aliases for endpoints with mutial TLS authentication. 285 */ 286 private AuthorizationServerEndpointMetadata mtlsEndpointAliases; 287 288 289 /** 290 * If {@code true} the 291 * {@code tls_client_certificate_bound_access_tokens} if set, else 292 * not. 293 */ 294 private boolean tlsClientCertificateBoundAccessTokens = false; 295 296 297 /** 298 * The supported JWS algorithms for DPoP. 299 */ 300 private List<JWSAlgorithm> dPoPJWSAlgs; 301 302 303 /** 304 * The supported JWS algorithms for JWT-encoded authorisation 305 * responses. 306 */ 307 private List<JWSAlgorithm> authzJWSAlgs; 308 309 310 /** 311 * The supported JWE algorithms for JWT-encoded authorisation 312 * responses. 313 */ 314 private List<JWEAlgorithm> authzJWEAlgs; 315 316 317 /** 318 * The supported encryption methods for JWT-encoded authorisation 319 * responses. 320 */ 321 private List<EncryptionMethod> authzJWEEncs; 322 323 324 /** 325 * If {@code true} PAR is required, else not. 326 */ 327 private boolean requirePAR = false; 328 329 330 /** 331 * The supported OAuth 2.0 client types for incremental authorisation. 332 */ 333 private List<ClientType> incrementalAuthzTypes; 334 335 336 /** 337 * Custom (not-registered) parameters. 338 */ 339 private final JSONObject customParameters = new JSONObject(); 340 341 342 /** 343 * Creates a new OAuth 2.0 Authorisation Server (AS) metadata instance. 344 * 345 * @param issuer The issuer identifier. Must be an URI using the https 346 * scheme with no query or fragment component. Must not 347 * be {@code null}. 348 */ 349 public AuthorizationServerMetadata(final Issuer issuer) { 350 351 URI uri; 352 try { 353 uri = new URI(issuer.getValue()); 354 } catch (URISyntaxException e) { 355 throw new IllegalArgumentException("The issuer identifier must be a URI: " + e.getMessage(), e); 356 } 357 358 if (uri.getRawQuery() != null) 359 throw new IllegalArgumentException("The issuer URI must be without a query component"); 360 361 if (uri.getRawFragment() != null) 362 throw new IllegalArgumentException("The issuer URI must be without a fragment component"); 363 364 this.issuer = issuer; 365 } 366 367 368 /** 369 * Gets the issuer identifier. Corresponds to the {@code issuer} 370 * metadata field. 371 * 372 * @return The issuer identifier. 373 */ 374 public Issuer getIssuer() { 375 376 return issuer; 377 } 378 379 380 /** 381 * Gets the JSON Web Key (JWK) set URI. Corresponds to the 382 * {@code jwks_uri} metadata field. 383 * 384 * @return The JWK set URI, {@code null} if not specified. 385 */ 386 public URI getJWKSetURI() { 387 388 return jwkSetURI; 389 } 390 391 392 /** 393 * Sets the JSON Web Key (JWT) set URI. Corresponds to the 394 * {@code jwks_uri} metadata field. 395 * 396 * @param jwkSetURI The JWK set URI, {@code null} if not specified. 397 */ 398 public void setJWKSetURI(final URI jwkSetURI) { 399 400 this.jwkSetURI = jwkSetURI; 401 } 402 403 404 /** 405 * Gets the supported scope values. Corresponds to the 406 * {@code scopes_supported} metadata field. 407 * 408 * @return The supported scope values, {@code null} if not specified. 409 */ 410 public Scope getScopes() { 411 412 return scope; 413 } 414 415 416 /** 417 * Sets the supported scope values. Corresponds to the 418 * {@code scopes_supported} metadata field. 419 * 420 * @param scope The supported scope values, {@code null} if not 421 * specified. 422 */ 423 public void setScopes(final Scope scope) { 424 425 this.scope = scope; 426 } 427 428 429 /** 430 * Gets the supported response type values. Corresponds to the 431 * {@code response_types_supported} metadata field. 432 * 433 * @return The supported response type values, {@code null} if not 434 * specified. 435 */ 436 public List<ResponseType> getResponseTypes() { 437 438 return rts; 439 } 440 441 442 /** 443 * Sets the supported response type values. Corresponds to the 444 * {@code response_types_supported} metadata field. 445 * 446 * @param rts The supported response type values, {@code null} if not 447 * specified. 448 */ 449 public void setResponseTypes(final List<ResponseType> rts) { 450 451 this.rts = rts; 452 } 453 454 455 /** 456 * Gets the supported response mode values. Corresponds to the 457 * {@code response_modes_supported}. 458 * 459 * @return The supported response mode values, {@code null} if not 460 * specified. 461 */ 462 public List<ResponseMode> getResponseModes() { 463 464 return rms; 465 } 466 467 468 /** 469 * Sets the supported response mode values. Corresponds to the 470 * {@code response_modes_supported}. 471 * 472 * @param rms The supported response mode values, {@code null} if not 473 * specified. 474 */ 475 public void setResponseModes(final List<ResponseMode> rms) { 476 477 this.rms = rms; 478 } 479 480 481 /** 482 * Gets the supported OAuth 2.0 grant types. Corresponds to the 483 * {@code grant_types_supported} metadata field. 484 * 485 * @return The supported grant types, {@code null} if not specified. 486 */ 487 public List<GrantType> getGrantTypes() { 488 489 return gts; 490 } 491 492 493 /** 494 * Sets the supported OAuth 2.0 grant types. Corresponds to the 495 * {@code grant_types_supported} metadata field. 496 * 497 * @param gts The supported grant types, {@code null} if not specified. 498 */ 499 public void setGrantTypes(final List<GrantType> gts) { 500 501 this.gts = gts; 502 } 503 504 505 /** 506 * Gets the supported authorisation code challenge methods for PKCE. 507 * Corresponds to the {@code code_challenge_methods_supported} metadata 508 * field. 509 * 510 * @return The supported code challenge methods, {@code null} if not 511 * specified. 512 */ 513 public List<CodeChallengeMethod> getCodeChallengeMethods() { 514 515 return codeChallengeMethods; 516 } 517 518 519 /** 520 * Gets the supported authorisation code challenge methods for PKCE. 521 * Corresponds to the {@code code_challenge_methods_supported} metadata 522 * field. 523 * 524 * @param codeChallengeMethods The supported code challenge methods, 525 * {@code null} if not specified. 526 */ 527 public void setCodeChallengeMethods(final List<CodeChallengeMethod> codeChallengeMethods) { 528 529 this.codeChallengeMethods = codeChallengeMethods; 530 } 531 532 533 /** 534 * Gets the supported token endpoint authentication methods. 535 * Corresponds to the {@code token_endpoint_auth_methods_supported} 536 * metadata field. 537 * 538 * @return The supported token endpoint authentication methods, 539 * {@code null} if not specified. 540 */ 541 public List<ClientAuthenticationMethod> getTokenEndpointAuthMethods() { 542 543 return tokenEndpointAuthMethods; 544 } 545 546 547 /** 548 * Sets the supported token endpoint authentication methods. 549 * Corresponds to the {@code token_endpoint_auth_methods_supported} 550 * metadata field. 551 * 552 * @param authMethods The supported token endpoint authentication 553 * methods, {@code null} if not specified. 554 */ 555 public void setTokenEndpointAuthMethods(final List<ClientAuthenticationMethod> authMethods) { 556 557 this.tokenEndpointAuthMethods = authMethods; 558 } 559 560 561 /** 562 * Gets the supported JWS algorithms for the {@code private_key_jwt} 563 * and {@code client_secret_jwt} token endpoint authentication methods. 564 * Corresponds to the 565 * {@code token_endpoint_auth_signing_alg_values_supported} metadata 566 * field. 567 * 568 * @return The supported JWS algorithms, {@code null} if not specified. 569 */ 570 public List<JWSAlgorithm> getTokenEndpointJWSAlgs() { 571 572 return tokenEndpointJWSAlgs; 573 } 574 575 576 /** 577 * Sets the supported JWS algorithms for the {@code private_key_jwt} 578 * and {@code client_secret_jwt} token endpoint authentication methods. 579 * Corresponds to the 580 * {@code token_endpoint_auth_signing_alg_values_supported} metadata 581 * field. 582 * 583 * @param jwsAlgs The supported JWS algorithms, {@code null} if not 584 * specified. Must not contain the {@code none} 585 * algorithm. 586 */ 587 public void setTokenEndpointJWSAlgs(final List<JWSAlgorithm> jwsAlgs) { 588 589 if (jwsAlgs != null && jwsAlgs.contains(Algorithm.NONE)) 590 throw new IllegalArgumentException("The \"none\" algorithm is not accepted"); 591 592 this.tokenEndpointJWSAlgs = jwsAlgs; 593 } 594 595 596 /** 597 * Gets the supported introspection endpoint authentication methods. 598 * Corresponds to the 599 * {@code introspection_endpoint_auth_methods_supported} metadata 600 * field. 601 * 602 * @return The supported introspection endpoint authentication methods, 603 * {@code null} if not specified. 604 */ 605 public List<ClientAuthenticationMethod> getIntrospectionEndpointAuthMethods() { 606 return introspectionEndpointAuthMethods; 607 } 608 609 610 /** 611 * Sets the supported introspection endpoint authentication methods. 612 * Corresponds to the 613 * {@code introspection_endpoint_auth_methods_supported} metadata 614 * field. 615 * 616 * @param authMethods The supported introspection endpoint 617 * authentication methods, {@code null} if not 618 * specified. 619 */ 620 public void setIntrospectionEndpointAuthMethods(final List<ClientAuthenticationMethod> authMethods) { 621 622 this.introspectionEndpointAuthMethods = authMethods; 623 } 624 625 626 /** 627 * Gets the supported JWS algorithms for the {@code private_key_jwt} 628 * and {@code client_secret_jwt} introspection endpoint authentication 629 * methods. Corresponds to the 630 * {@code introspection_endpoint_auth_signing_alg_values_supported} 631 * metadata field. 632 * 633 * @return The supported JWS algorithms, {@code null} if not specified. 634 */ 635 public List<JWSAlgorithm> getIntrospectionEndpointJWSAlgs() { 636 637 return introspectionEndpointJWSAlgs; 638 } 639 640 641 /** 642 * Sets the supported JWS algorithms for the {@code private_key_jwt} 643 * and {@code client_secret_jwt} introspection endpoint authentication 644 * methods. Corresponds to the 645 * {@code introspection_endpoint_auth_signing_alg_values_supported} 646 * metadata field. 647 * 648 * @param jwsAlgs The supported JWS algorithms, {@code null} if not 649 * specified. Must not contain the {@code none} 650 * algorithm. 651 */ 652 public void setIntrospectionEndpointJWSAlgs(final List<JWSAlgorithm> jwsAlgs) { 653 654 if (jwsAlgs != null && jwsAlgs.contains(Algorithm.NONE)) 655 throw new IllegalArgumentException("The \"none\" algorithm is not accepted"); 656 657 introspectionEndpointJWSAlgs = jwsAlgs; 658 } 659 660 661 /** 662 * Gets the supported revocation endpoint authentication methods. 663 * Corresponds to the 664 * {@code revocation_endpoint_auth_methods_supported} metadata field. 665 * 666 * @return The supported revocation endpoint authentication methods, 667 * {@code null} if not specified. 668 */ 669 public List<ClientAuthenticationMethod> getRevocationEndpointAuthMethods() { 670 671 return revocationEndpointAuthMethods; 672 } 673 674 675 /** 676 * Sets the supported revocation endpoint authentication methods. 677 * Corresponds to the 678 * {@code revocation_endpoint_auth_methods_supported} metadata field. 679 * 680 * @param authMethods The supported revocation endpoint authentication 681 * methods, {@code null} if not specified. 682 */ 683 public void setRevocationEndpointAuthMethods(final List<ClientAuthenticationMethod> authMethods) { 684 685 revocationEndpointAuthMethods = authMethods; 686 } 687 688 689 /** 690 * Gets the supported JWS algorithms for the {@code private_key_jwt} 691 * and {@code client_secret_jwt} revocation endpoint authentication 692 * methods. Corresponds to the 693 * {@code revocation_endpoint_auth_signing_alg_values_supported} 694 * metadata field. 695 * 696 * @return The supported JWS algorithms, {@code null} if not specified. 697 */ 698 public List<JWSAlgorithm> getRevocationEndpointJWSAlgs() { 699 700 return revocationEndpointJWSAlgs; 701 } 702 703 704 /** 705 * Sets the supported JWS algorithms for the {@code private_key_jwt} 706 * and {@code client_secret_jwt} revocation endpoint authentication 707 * methods. Corresponds to the 708 * {@code revocation_endpoint_auth_signing_alg_values_supported} 709 * metadata field. 710 * 711 * @param jwsAlgs The supported JWS algorithms, {@code null} if not 712 * specified. Must not contain the {@code none} 713 * algorithm. 714 */ 715 public void setRevocationEndpointJWSAlgs(final List<JWSAlgorithm> jwsAlgs) { 716 717 if (jwsAlgs != null && jwsAlgs.contains(Algorithm.NONE)) 718 throw new IllegalArgumentException("The \"none\" algorithm is not accepted"); 719 720 revocationEndpointJWSAlgs = jwsAlgs; 721 } 722 723 724 /** 725 * Gets the supported JWS algorithms for request objects. Corresponds 726 * to the {@code request_object_signing_alg_values_supported} metadata 727 * field. 728 * 729 * @return The supported JWS algorithms, {@code null} if not specified. 730 */ 731 public List<JWSAlgorithm> getRequestObjectJWSAlgs() { 732 733 return requestObjectJWSAlgs; 734 } 735 736 737 /** 738 * Sets the supported JWS algorithms for request objects. Corresponds 739 * to the {@code request_object_signing_alg_values_supported} metadata 740 * field. 741 * 742 * @param requestObjectJWSAlgs The supported JWS algorithms, 743 * {@code null} if not specified. 744 */ 745 public void setRequestObjectJWSAlgs(final List<JWSAlgorithm> requestObjectJWSAlgs) { 746 747 this.requestObjectJWSAlgs = requestObjectJWSAlgs; 748 } 749 750 751 /** 752 * Gets the supported JWE algorithms for request objects. Corresponds 753 * to the {@code request_object_encryption_alg_values_supported} 754 * metadata field. 755 * 756 * @return The supported JWE algorithms, {@code null} if not specified. 757 */ 758 public List<JWEAlgorithm> getRequestObjectJWEAlgs() { 759 760 return requestObjectJWEAlgs; 761 } 762 763 764 /** 765 * Sets the supported JWE algorithms for request objects. Corresponds 766 * to the {@code request_object_encryption_alg_values_supported} 767 * metadata field. 768 * 769 * @param requestObjectJWEAlgs The supported JWE algorithms, 770 * {@code null} if not specified. 771 */ 772 public void setRequestObjectJWEAlgs(final List<JWEAlgorithm> requestObjectJWEAlgs) { 773 774 this.requestObjectJWEAlgs = requestObjectJWEAlgs; 775 } 776 777 778 /** 779 * Gets the supported encryption methods for request objects. 780 * Corresponds to the 781 * {@code request_object_encryption_enc_values_supported} metadata 782 * field. 783 * 784 * @return The supported encryption methods, {@code null} if not 785 * specified. 786 */ 787 public List<EncryptionMethod> getRequestObjectJWEEncs() { 788 789 return requestObjectJWEEncs; 790 } 791 792 793 /** 794 * Sets the supported encryption methods for request objects. 795 * Corresponds to the 796 * {@code request_object_encryption_enc_values_supported} metadata 797 * field. 798 * 799 * @param requestObjectJWEEncs The supported encryption methods, 800 * {@code null} if not specified. 801 */ 802 public void setRequestObjectJWEEncs(final List<EncryptionMethod> requestObjectJWEEncs) { 803 804 this.requestObjectJWEEncs = requestObjectJWEEncs; 805 } 806 807 808 /** 809 * Gets the support for the {@code request} authorisation request 810 * parameter. Corresponds to the {@code request_parameter_supported} 811 * metadata field. 812 * 813 * @return {@code true} if the {@code reqeust} parameter is supported, 814 * else {@code false}. 815 */ 816 public boolean supportsRequestParam() { 817 818 return requestParamSupported; 819 } 820 821 822 /** 823 * Sets the support for the {@code request} authorisation request 824 * parameter. Corresponds to the {@code request_parameter_supported} 825 * metadata field. 826 * 827 * @param requestParamSupported {@code true} if the {@code reqeust} 828 * parameter is supported, else 829 * {@code false}. 830 */ 831 public void setSupportsRequestParam(final boolean requestParamSupported) { 832 833 this.requestParamSupported = requestParamSupported; 834 } 835 836 837 /** 838 * Gets the support for the {@code request_uri} authorisation request 839 * parameter. Corresponds the {@code request_uri_parameter_supported} 840 * metadata field. 841 * 842 * @return {@code true} if the {@code request_uri} parameter is 843 * supported, else {@code false}. 844 */ 845 public boolean supportsRequestURIParam() { 846 847 return requestURIParamSupported; 848 } 849 850 851 /** 852 * Sets the support for the {@code request_uri} authorisation request 853 * parameter. Corresponds the {@code request_uri_parameter_supported} 854 * metadata field. 855 * 856 * @param requestURIParamSupported {@code true} if the 857 * {@code request_uri} parameter is 858 * supported, else {@code false}. 859 */ 860 public void setSupportsRequestURIParam(final boolean requestURIParamSupported) { 861 862 this.requestURIParamSupported = requestURIParamSupported; 863 } 864 865 866 /** 867 * Gets the requirement for the {@code request_uri} parameter 868 * pre-registration. Corresponds to the 869 * {@code require_request_uri_registration} metadata field. 870 * 871 * @return {@code true} if the {@code request_uri} parameter values 872 * must be pre-registered, else {@code false}. 873 */ 874 public boolean requiresRequestURIRegistration() { 875 876 return requireRequestURIReg; 877 } 878 879 880 /** 881 * Sets the requirement for the {@code request_uri} parameter 882 * pre-registration. Corresponds to the 883 * {@code require_request_uri_registration} metadata field. 884 * 885 * @param requireRequestURIReg {@code true} if the {@code request_uri} 886 * parameter values must be pre-registered, 887 * else {@code false}. 888 */ 889 public void setRequiresRequestURIRegistration(final boolean requireRequestURIReg) { 890 891 this.requireRequestURIReg = requireRequestURIReg; 892 } 893 894 895 /** 896 * Gets the support for the {@code iss} authorisation response 897 * parameter. Corresponds to the 898 * {@code authorization_response_iss_parameter_supported} metadata 899 * field. 900 * 901 * @return {@code true} if the {@code iss} authorisation response 902 * parameter is provided, else {@code false}. 903 */ 904 public boolean supportsAuthorizationResponseIssuerParam() { 905 906 return authzResponseIssParameterSupported; 907 } 908 909 910 /** 911 * Sets the support for the {@code iss} authorisation response 912 * parameter. Corresponds to the 913 * {@code authorization_response_iss_parameter_supported} metadata 914 * field. 915 * 916 * @param authzResponseIssParameterSupported {@code true} if the 917 * {@code iss} authorisation 918 * response parameter is 919 * provided, else 920 * {@code false}. 921 */ 922 public void setSupportsAuthorizationResponseIssuerParam(final boolean authzResponseIssParameterSupported) { 923 924 this.authzResponseIssParameterSupported = authzResponseIssParameterSupported; 925 } 926 927 928 /** 929 * Gets the supported UI locales. Corresponds to the 930 * {@code ui_locales_supported} metadata field. 931 * 932 * @return The supported UI locales, {@code null} if not specified. 933 */ 934 public List<LangTag> getUILocales() { 935 936 return uiLocales; 937 } 938 939 940 /** 941 * Sets the supported UI locales. Corresponds to the 942 * {@code ui_locales_supported} metadata field. 943 * 944 * @param uiLocales The supported UI locales, {@code null} if not 945 * specified. 946 */ 947 public void setUILocales(final List<LangTag> uiLocales) { 948 949 this.uiLocales = uiLocales; 950 } 951 952 953 /** 954 * Gets the service documentation URI. Corresponds to the 955 * {@code service_documentation} metadata field. 956 * 957 * @return The service documentation URI, {@code null} if not 958 * specified. 959 */ 960 public URI getServiceDocsURI() { 961 962 return serviceDocsURI; 963 } 964 965 966 /** 967 * Sets the service documentation URI. Corresponds to the 968 * {@code service_documentation} metadata field. 969 * 970 * @param serviceDocsURI The service documentation URI, {@code null} if 971 * not specified. The URI scheme must be https or 972 * http. 973 */ 974 public void setServiceDocsURI(final URI serviceDocsURI) { 975 976 URIUtils.ensureSchemeIsHTTPSorHTTP(serviceDocsURI); 977 this.serviceDocsURI = serviceDocsURI; 978 } 979 980 981 /** 982 * Gets the provider's policy regarding relying party use of data. 983 * Corresponds to the {@code op_policy_uri} metadata field. 984 * 985 * @return The policy URI, {@code null} if not specified. 986 */ 987 public URI getPolicyURI() { 988 989 return policyURI; 990 } 991 992 993 /** 994 * Sets the provider's policy regarding relying party use of data. 995 * Corresponds to the {@code op_policy_uri} metadata field. 996 * 997 * @param policyURI The policy URI, {@code null} if not specified. The 998 * URI scheme must be https or http. 999 */ 1000 public void setPolicyURI(final URI policyURI) { 1001 1002 URIUtils.ensureSchemeIsHTTPSorHTTP(policyURI); 1003 this.policyURI = policyURI; 1004 } 1005 1006 1007 /** 1008 * Gets the provider's terms of service. Corresponds to the 1009 * {@code op_tos_uri} metadata field. 1010 * 1011 * @return The terms of service URI, {@code null} if not specified. 1012 */ 1013 public URI getTermsOfServiceURI() { 1014 1015 return tosURI; 1016 } 1017 1018 1019 /** 1020 * Sets the provider's terms of service. Corresponds to the 1021 * {@code op_tos_uri} metadata field. 1022 * 1023 * @param tosURI The terms of service URI, {@code null} if not 1024 * specified. The URI scheme must be https or http. 1025 */ 1026 public void setTermsOfServiceURI(final URI tosURI) { 1027 1028 URIUtils.ensureSchemeIsHTTPSorHTTP(tosURI); 1029 this.tosURI = tosURI; 1030 } 1031 1032 1033 /** 1034 * Gets the aliases for communication with mutual TLS. Corresponds to the 1035 * {@code mtls_endpoint_aliases} metadata field. 1036 * 1037 * @return The aliases for communication with mutual TLS, or {@code null} 1038 * when no aliases are defined. 1039 */ 1040 public AuthorizationServerEndpointMetadata getMtlsEndpointAliases() { 1041 1042 return mtlsEndpointAliases; 1043 } 1044 1045 1046 /** 1047 * Sets the aliases for communication with mutual TLS. Corresponds to the 1048 * {@code mtls_endpoint_aliases} metadata field. 1049 * 1050 * @param mtlsEndpointAliases The aliases for communication with mutual 1051 * TLS, or {@code null} when no aliases are 1052 * defined. 1053 */ 1054 public void setMtlsEndpointAliases(AuthorizationServerEndpointMetadata mtlsEndpointAliases) { 1055 1056 this.mtlsEndpointAliases = mtlsEndpointAliases; 1057 } 1058 1059 1060 /** 1061 * Gets the support for TLS client certificate bound access tokens. 1062 * Corresponds to the 1063 * {@code tls_client_certificate_bound_access_tokens} metadata field. 1064 * 1065 * @return {@code true} if TLS client certificate bound access tokens 1066 * are supported, else {@code false}. 1067 */ 1068 public boolean supportsTLSClientCertificateBoundAccessTokens() { 1069 1070 return tlsClientCertificateBoundAccessTokens; 1071 } 1072 1073 1074 /** 1075 * Sets the support for TLS client certificate bound access tokens. 1076 * Corresponds to the 1077 * {@code tls_client_certificate_bound_access_tokens} metadata field. 1078 * 1079 * @param tlsClientCertBoundTokens {@code true} if TLS client 1080 * certificate bound access tokens are 1081 * supported, else {@code false}. 1082 */ 1083 public void setSupportsTLSClientCertificateBoundAccessTokens(final boolean tlsClientCertBoundTokens) { 1084 1085 tlsClientCertificateBoundAccessTokens = tlsClientCertBoundTokens; 1086 } 1087 1088 1089 /** 1090 * Gets the support for TLS client certificate bound access tokens. 1091 * Corresponds to the 1092 * {@code tls_client_certificate_bound_access_tokens} metadata field. 1093 * 1094 * @return {@code true} if TLS client certificate bound access tokens 1095 * are supported, else {@code false}. 1096 */ 1097 @Deprecated 1098 public boolean supportsMutualTLSSenderConstrainedAccessTokens() { 1099 1100 return supportsTLSClientCertificateBoundAccessTokens(); 1101 } 1102 1103 1104 /** 1105 * Sets the support for TLS client certificate bound access tokens. 1106 * Corresponds to the 1107 * {@code tls_client_certificate_bound_access_tokens} metadata field. 1108 * 1109 * @param mutualTLSSenderConstrainedAccessTokens {@code true} if TLS 1110 * client certificate 1111 * bound access tokens 1112 * are supported, else 1113 * {@code false}. 1114 */ 1115 @Deprecated 1116 public void setSupportsMutualTLSSenderConstrainedAccessTokens(final boolean mutualTLSSenderConstrainedAccessTokens) { 1117 1118 setSupportsTLSClientCertificateBoundAccessTokens(mutualTLSSenderConstrainedAccessTokens); 1119 } 1120 1121 1122 /** 1123 * Gets the supported JWS algorithms for Demonstrating 1124 * Proof-of-Possession at the Application Layer (DPoP). Corresponds to 1125 * the "dpop_signing_alg_values_supported" metadata field. 1126 * 1127 * @return The supported JWS algorithms for DPoP, {@code null} if none. 1128 */ 1129 public List<JWSAlgorithm> getDPoPJWSAlgs() { 1130 1131 return dPoPJWSAlgs; 1132 } 1133 1134 1135 /** 1136 * Sets the supported JWS algorithms for Demonstrating 1137 * Proof-of-Possession at the Application Layer (DPoP). Corresponds to 1138 * the "dpop_signing_alg_values_supported" metadata field. 1139 * 1140 * @param dPoPJWSAlgs The supported JWS algorithms for DPoP, 1141 * {@code null} if none. 1142 */ 1143 public void setDPoPJWSAlgs(final List<JWSAlgorithm> dPoPJWSAlgs) { 1144 1145 this.dPoPJWSAlgs = dPoPJWSAlgs; 1146 } 1147 1148 1149 /** 1150 * Gets the supported JWS algorithms for JWT-encoded authorisation 1151 * responses. Corresponds to the 1152 * {@code authorization_signing_alg_values_supported} metadata field. 1153 * 1154 * @return The supported JWS algorithms, {@code null} if not specified. 1155 */ 1156 public List<JWSAlgorithm> getAuthorizationJWSAlgs() { 1157 1158 return authzJWSAlgs; 1159 } 1160 1161 1162 /** 1163 * Sets the supported JWS algorithms for JWT-encoded authorisation 1164 * responses. Corresponds to the 1165 * {@code authorization_signing_alg_values_supported} metadata field. 1166 * 1167 * @param authzJWSAlgs The supported JWS algorithms, {@code null} if 1168 * not specified. 1169 */ 1170 public void setAuthorizationJWSAlgs(final List<JWSAlgorithm> authzJWSAlgs) { 1171 1172 this.authzJWSAlgs = authzJWSAlgs; 1173 } 1174 1175 1176 /** 1177 * Gets the supported JWE algorithms for JWT-encoded authorisation 1178 * responses. Corresponds to the 1179 * {@code authorization_encryption_alg_values_supported} metadata 1180 * field. 1181 * 1182 * @return The supported JWE algorithms, {@code null} if not specified. 1183 */ 1184 public List<JWEAlgorithm> getAuthorizationJWEAlgs() { 1185 1186 return authzJWEAlgs; 1187 } 1188 1189 1190 /** 1191 * Sets the supported JWE algorithms for JWT-encoded authorisation 1192 * responses. Corresponds to the 1193 * {@code authorization_encryption_alg_values_supported} metadata 1194 * field. 1195 * 1196 * @param authzJWEAlgs The supported JWE algorithms, {@code null} if 1197 * not specified. 1198 */ 1199 public void setAuthorizationJWEAlgs(final List<JWEAlgorithm> authzJWEAlgs) { 1200 1201 this.authzJWEAlgs = authzJWEAlgs; 1202 } 1203 1204 1205 /** 1206 * Gets the supported encryption methods for JWT-encoded authorisation 1207 * responses. Corresponds to the 1208 * {@code authorization_encryption_enc_values_supported} metadata 1209 * field. 1210 * 1211 * @return The supported encryption methods, {@code null} if not 1212 * specified. 1213 */ 1214 public List<EncryptionMethod> getAuthorizationJWEEncs() { 1215 1216 return authzJWEEncs; 1217 } 1218 1219 1220 /** 1221 * Sets the supported encryption methods for JWT-encoded authorisation 1222 * responses. Corresponds to the 1223 * {@code authorization_encryption_enc_values_supported} metadata 1224 * field. 1225 * 1226 * @param authzJWEEncs The supported encryption methods, {@code null} 1227 * if not specified. 1228 */ 1229 public void setAuthorizationJWEEncs(final List<EncryptionMethod> authzJWEEncs) { 1230 1231 this.authzJWEEncs = authzJWEEncs; 1232 } 1233 1234 1235 /** 1236 * Gets the requirement for pushed authorisation requests (PAR). 1237 * Corresponds to the {@code pushed_authorization_request_endpoint} 1238 * metadata field. 1239 * 1240 * @return {@code true} if PAR is required, else {@code false}. 1241 */ 1242 public boolean requiresPushedAuthorizationRequests() { 1243 1244 return requirePAR; 1245 } 1246 1247 1248 /** 1249 * Sets the requirement for pushed authorisation requests (PAR). 1250 * Corresponds to the {@code pushed_authorization_request_endpoint} 1251 * metadata field. 1252 * 1253 * @param requirePAR {@code true} if PAR is required, else 1254 * {@code false}. 1255 */ 1256 public void requiresPushedAuthorizationRequests(final boolean requirePAR) { 1257 1258 this.requirePAR = requirePAR; 1259 } 1260 1261 1262 /** 1263 * Gets the supported OAuth 2.0 client types for incremental 1264 * authorisation. Corresponds to the 1265 * {@code incremental_authz_types_supported} metadata field. 1266 * 1267 * @return The supported client types for incremental authorisation, 1268 * {@code null} if not specified. 1269 */ 1270 public List<ClientType> getIncrementalAuthorizationTypes() { 1271 1272 return incrementalAuthzTypes; 1273 } 1274 1275 1276 /** 1277 * Sets the supported OAuth 2.0 client types for incremental 1278 * authorisation. Corresponds to the 1279 * {@code incremental_authz_types_supported} metadata field. 1280 * 1281 * @param incrementalAuthzTypes The supported client types for 1282 * incremental authorisation, {@code null} 1283 * if not specified. 1284 */ 1285 public void setIncrementalAuthorizationTypes(final List<ClientType> incrementalAuthzTypes) { 1286 1287 this.incrementalAuthzTypes = incrementalAuthzTypes; 1288 } 1289 1290 1291 /** 1292 * Gets the specified custom (not registered) parameter. 1293 * 1294 * @param name The parameter name. Must not be {@code null}. 1295 * 1296 * @return The parameter value, {@code null} if not specified. 1297 */ 1298 public Object getCustomParameter(final String name) { 1299 1300 return customParameters.get(name); 1301 } 1302 1303 1304 /** 1305 * Gets the specified custom (not registered) URI parameter. 1306 * 1307 * @param name The parameter name. Must not be {@code null}. 1308 * 1309 * @return The parameter URI value, {@code null} if not specified. 1310 */ 1311 public URI getCustomURIParameter(final String name) { 1312 1313 try { 1314 return JSONObjectUtils.getURI(customParameters, name, null); 1315 } catch (ParseException e) { 1316 return null; 1317 } 1318 } 1319 1320 1321 /** 1322 * Sets the specified custom (not registered) parameter. 1323 * 1324 * @param name The parameter name. Must not be {@code null}. 1325 * @param value The parameter value, {@code null} if not specified. 1326 */ 1327 public void setCustomParameter(final String name, final Object value) { 1328 1329 if (REGISTERED_PARAMETER_NAMES.contains(name)) { 1330 throw new IllegalArgumentException("The " + name + " parameter is registered"); 1331 } 1332 1333 customParameters.put(name, value); 1334 } 1335 1336 1337 /** 1338 * Gets the custom (not registered) parameters. 1339 * 1340 * @return The custom parameters, empty JSON object if none. 1341 */ 1342 public JSONObject getCustomParameters() { 1343 1344 return customParameters; 1345 } 1346 1347 1348 /** 1349 * Applies the OAuth 2.0 Authorisation Server metadata defaults where 1350 * no values have been specified. 1351 * 1352 * <ul> 1353 * <li>The response modes default to {@code ["query", "fragment"]}. 1354 * <li>The grant types default to {@code ["authorization_code", 1355 * "implicit"]}. 1356 * <li>The token endpoint authentication methods default to 1357 * {@code ["client_secret_basic"]}. 1358 * </ul> 1359 */ 1360 public void applyDefaults() { 1361 1362 if (rms == null) { 1363 rms = new ArrayList<>(2); 1364 rms.add(ResponseMode.QUERY); 1365 rms.add(ResponseMode.FRAGMENT); 1366 } 1367 1368 if (gts == null) { 1369 gts = new ArrayList<>(2); 1370 gts.add(GrantType.AUTHORIZATION_CODE); 1371 gts.add(GrantType.IMPLICIT); 1372 } 1373 1374 if (tokenEndpointAuthMethods == null) { 1375 tokenEndpointAuthMethods = new ArrayList<>(); 1376 tokenEndpointAuthMethods.add(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); 1377 } 1378 } 1379 1380 1381 /** 1382 * Returns the JSON object representation of this OpenID Connect 1383 * provider metadata. 1384 * 1385 * @return The JSON object representation. 1386 */ 1387 public JSONObject toJSONObject() { 1388 1389 JSONObject o = super.toJSONObject(); 1390 1391 // Mandatory fields 1392 o.put("issuer", issuer.getValue()); 1393 1394 1395 // Optional fields 1396 if (jwkSetURI != null) 1397 o.put("jwks_uri", jwkSetURI.toString()); 1398 1399 if (scope != null) 1400 o.put("scopes_supported", scope.toStringList()); 1401 1402 List<String> stringList; 1403 1404 if (rts != null) { 1405 1406 stringList = new ArrayList<>(rts.size()); 1407 1408 for (ResponseType rt: rts) 1409 stringList.add(rt.toString()); 1410 1411 o.put("response_types_supported", stringList); 1412 } 1413 1414 if (rms != null) { 1415 1416 stringList = new ArrayList<>(rms.size()); 1417 1418 for (ResponseMode rm: rms) 1419 stringList.add(rm.getValue()); 1420 1421 o.put("response_modes_supported", stringList); 1422 } 1423 1424 if (gts != null) { 1425 1426 stringList = new ArrayList<>(gts.size()); 1427 1428 for (GrantType gt: gts) 1429 stringList.add(gt.toString()); 1430 1431 o.put("grant_types_supported", stringList); 1432 } 1433 1434 if (codeChallengeMethods != null) { 1435 1436 stringList = new ArrayList<>(codeChallengeMethods.size()); 1437 1438 for (CodeChallengeMethod m: codeChallengeMethods) 1439 stringList.add(m.getValue()); 1440 1441 o.put("code_challenge_methods_supported", stringList); 1442 } 1443 1444 1445 if (tokenEndpointAuthMethods != null) { 1446 1447 stringList = new ArrayList<>(tokenEndpointAuthMethods.size()); 1448 1449 for (ClientAuthenticationMethod m: tokenEndpointAuthMethods) 1450 stringList.add(m.getValue()); 1451 1452 o.put("token_endpoint_auth_methods_supported", stringList); 1453 } 1454 1455 if (tokenEndpointJWSAlgs != null) { 1456 1457 stringList = new ArrayList<>(tokenEndpointJWSAlgs.size()); 1458 1459 for (JWSAlgorithm alg: tokenEndpointJWSAlgs) 1460 stringList.add(alg.getName()); 1461 1462 o.put("token_endpoint_auth_signing_alg_values_supported", stringList); 1463 } 1464 1465 if (introspectionEndpointAuthMethods != null) { 1466 1467 stringList = new ArrayList<>(introspectionEndpointAuthMethods.size()); 1468 1469 for (ClientAuthenticationMethod m: introspectionEndpointAuthMethods) 1470 stringList.add(m.getValue()); 1471 1472 o.put("introspection_endpoint_auth_methods_supported", stringList); 1473 } 1474 1475 if (introspectionEndpointJWSAlgs != null) { 1476 1477 stringList = new ArrayList<>(introspectionEndpointJWSAlgs.size()); 1478 1479 for (JWSAlgorithm alg: introspectionEndpointJWSAlgs) 1480 stringList.add(alg.getName()); 1481 1482 o.put("introspection_endpoint_auth_signing_alg_values_supported", stringList); 1483 } 1484 1485 if (revocationEndpointAuthMethods != null) { 1486 1487 stringList = new ArrayList<>(revocationEndpointAuthMethods.size()); 1488 1489 for (ClientAuthenticationMethod m: revocationEndpointAuthMethods) 1490 stringList.add(m.getValue()); 1491 1492 o.put("revocation_endpoint_auth_methods_supported", stringList); 1493 } 1494 1495 if (revocationEndpointJWSAlgs != null) { 1496 1497 stringList = new ArrayList<>(revocationEndpointJWSAlgs.size()); 1498 1499 for (JWSAlgorithm alg: revocationEndpointJWSAlgs) 1500 stringList.add(alg.getName()); 1501 1502 o.put("revocation_endpoint_auth_signing_alg_values_supported", stringList); 1503 } 1504 1505 if (requestObjectJWSAlgs != null) { 1506 1507 stringList = new ArrayList<>(requestObjectJWSAlgs.size()); 1508 1509 for (JWSAlgorithm alg: requestObjectJWSAlgs) 1510 stringList.add(alg.getName()); 1511 1512 o.put("request_object_signing_alg_values_supported", stringList); 1513 } 1514 1515 if (requestObjectJWEAlgs != null) { 1516 1517 stringList = new ArrayList<>(requestObjectJWEAlgs.size()); 1518 1519 for (JWEAlgorithm alg: requestObjectJWEAlgs) 1520 stringList.add(alg.getName()); 1521 1522 o.put("request_object_encryption_alg_values_supported", stringList); 1523 } 1524 1525 if (requestObjectJWEEncs != null) { 1526 1527 stringList = new ArrayList<>(requestObjectJWEEncs.size()); 1528 1529 for (EncryptionMethod m: requestObjectJWEEncs) 1530 stringList.add(m.getName()); 1531 1532 o.put("request_object_encryption_enc_values_supported", stringList); 1533 } 1534 1535 if (uiLocales != null) { 1536 1537 stringList = new ArrayList<>(uiLocales.size()); 1538 1539 for (LangTag l: uiLocales) 1540 stringList.add(l.toString()); 1541 1542 o.put("ui_locales_supported", stringList); 1543 } 1544 1545 if (serviceDocsURI != null) 1546 o.put("service_documentation", serviceDocsURI.toString()); 1547 1548 if (policyURI != null) 1549 o.put("op_policy_uri", policyURI.toString()); 1550 1551 if (tosURI != null) 1552 o.put("op_tos_uri", tosURI.toString()); 1553 1554 if (requestParamSupported) { 1555 o.put("request_parameter_supported", true); 1556 } 1557 1558 if (requestURIParamSupported) { 1559 o.put("request_uri_parameter_supported", true); 1560 } 1561 1562 if (requireRequestURIReg) { 1563 o.put("require_request_uri_registration", true); 1564 } 1565 1566 if (authzResponseIssParameterSupported) { 1567 o.put("authorization_response_iss_parameter_supported", true); 1568 } 1569 1570 if (mtlsEndpointAliases != null) 1571 o.put("mtls_endpoint_aliases", mtlsEndpointAliases.toJSONObject()); 1572 1573 if (tlsClientCertificateBoundAccessTokens) { 1574 o.put("tls_client_certificate_bound_access_tokens", true); 1575 } 1576 1577 // DPoP 1578 if (dPoPJWSAlgs != null) { 1579 1580 stringList = new ArrayList<>(dPoPJWSAlgs.size()); 1581 1582 for (JWSAlgorithm alg: dPoPJWSAlgs) 1583 stringList.add(alg.getName()); 1584 1585 o.put("dpop_signing_alg_values_supported", stringList); 1586 } 1587 1588 // JARM 1589 if (authzJWSAlgs != null) { 1590 1591 stringList = new ArrayList<>(authzJWSAlgs.size()); 1592 1593 for (JWSAlgorithm alg: authzJWSAlgs) 1594 stringList.add(alg.getName()); 1595 1596 o.put("authorization_signing_alg_values_supported", stringList); 1597 } 1598 1599 if (authzJWEAlgs != null) { 1600 1601 stringList = new ArrayList<>(authzJWEAlgs.size()); 1602 1603 for (JWEAlgorithm alg: authzJWEAlgs) 1604 stringList.add(alg.getName()); 1605 1606 o.put("authorization_encryption_alg_values_supported", stringList); 1607 } 1608 1609 if (authzJWEEncs != null) { 1610 1611 stringList = new ArrayList<>(authzJWEEncs.size()); 1612 1613 for (EncryptionMethod m: authzJWEEncs) 1614 stringList.add(m.getName()); 1615 1616 o.put("authorization_encryption_enc_values_supported", stringList); 1617 } 1618 1619 // PAR 1620 if (requirePAR) { 1621 o.put("require_pushed_authorization_requests", true); 1622 } 1623 1624 // Incremental authz 1625 if (CollectionUtils.isNotEmpty(incrementalAuthzTypes)) { 1626 stringList = new ArrayList<>(incrementalAuthzTypes.size()); 1627 for (ClientType clientType: incrementalAuthzTypes) { 1628 if (clientType != null) { 1629 stringList.add(clientType.name().toLowerCase()); 1630 } 1631 } 1632 o.put("incremental_authz_types_supported", stringList); 1633 } 1634 1635 // Append any custom (not registered) parameters 1636 o.putAll(customParameters); 1637 1638 return o; 1639 } 1640 1641 1642 /** 1643 * Parses an OAuth 2.0 Authorisation Server metadata from the specified 1644 * JSON object. 1645 * 1646 * @param jsonObject The JSON object to parse. Must not be 1647 * {@code null}. 1648 * 1649 * @return The OAuth 2.0 Authorisation Server metadata. 1650 * 1651 * @throws ParseException If the JSON object couldn't be parsed to an 1652 * OAuth 2.0 Authorisation Server metadata. 1653 */ 1654 public static AuthorizationServerMetadata parse(final JSONObject jsonObject) 1655 throws ParseException { 1656 1657 // Parse issuer and subject_types_supported first 1658 1659 Issuer issuer = new Issuer(JSONObjectUtils.getURI(jsonObject, "issuer").toString()); 1660 1661 AuthorizationServerEndpointMetadata asEndpoints = AuthorizationServerEndpointMetadata.parse(jsonObject); 1662 1663 AuthorizationServerMetadata as; 1664 1665 try { 1666 as = new AuthorizationServerMetadata(issuer); // validates issuer syntax 1667 } catch (IllegalArgumentException e) { 1668 throw new ParseException(e.getMessage(), e); 1669 } 1670 1671 // Endpoints 1672 as.setAuthorizationEndpointURI(asEndpoints.getAuthorizationEndpointURI()); 1673 as.setTokenEndpointURI(asEndpoints.getTokenEndpointURI()); 1674 as.setRegistrationEndpointURI(asEndpoints.getRegistrationEndpointURI()); 1675 as.setIntrospectionEndpointURI(asEndpoints.getIntrospectionEndpointURI()); 1676 as.setRevocationEndpointURI(asEndpoints.getRevocationEndpointURI()); 1677 as.setDeviceAuthorizationEndpointURI(asEndpoints.getDeviceAuthorizationEndpointURI()); 1678 as.setRequestObjectEndpoint(asEndpoints.getRequestObjectEndpoint()); 1679 as.setPushedAuthorizationRequestEndpointURI(asEndpoints.getPushedAuthorizationRequestEndpointURI()); 1680 as.jwkSetURI = JSONObjectUtils.getURI(jsonObject, "jwks_uri", null); 1681 1682 // AS capabilities 1683 if (jsonObject.get("scopes_supported") != null) { 1684 1685 as.scope = new Scope(); 1686 1687 for (String v: JSONObjectUtils.getStringArray(jsonObject, "scopes_supported")) { 1688 1689 if (v != null) 1690 as.scope.add(new Scope.Value(v)); 1691 } 1692 } 1693 1694 if (jsonObject.get("response_types_supported") != null) { 1695 1696 as.rts = new ArrayList<>(); 1697 1698 for (String v: JSONObjectUtils.getStringArray(jsonObject, "response_types_supported")) { 1699 1700 if (v != null) 1701 as.rts.add(ResponseType.parse(v)); 1702 } 1703 } 1704 1705 if (jsonObject.get("response_modes_supported") != null) { 1706 1707 as.rms = new ArrayList<>(); 1708 1709 for (String v: JSONObjectUtils.getStringArray(jsonObject, "response_modes_supported")) { 1710 1711 if (v != null) 1712 as.rms.add(new ResponseMode(v)); 1713 } 1714 } 1715 1716 if (jsonObject.get("grant_types_supported") != null) { 1717 1718 as.gts = new ArrayList<>(); 1719 1720 for (String v: JSONObjectUtils.getStringArray(jsonObject, "grant_types_supported")) { 1721 1722 if (v != null) 1723 as.gts.add(GrantType.parse(v)); 1724 } 1725 } 1726 1727 if (jsonObject.get("code_challenge_methods_supported") != null) { 1728 1729 as.codeChallengeMethods = new ArrayList<>(); 1730 1731 for (String v: JSONObjectUtils.getStringArray(jsonObject, "code_challenge_methods_supported")) { 1732 1733 if (v != null) 1734 as.codeChallengeMethods.add(CodeChallengeMethod.parse(v)); 1735 } 1736 } 1737 1738 if (jsonObject.get("token_endpoint_auth_methods_supported") != null) { 1739 1740 as.tokenEndpointAuthMethods = new ArrayList<>(); 1741 1742 for (String v: JSONObjectUtils.getStringArray(jsonObject, "token_endpoint_auth_methods_supported")) { 1743 1744 if (v != null) 1745 as.tokenEndpointAuthMethods.add(ClientAuthenticationMethod.parse(v)); 1746 } 1747 } 1748 1749 if (jsonObject.get("token_endpoint_auth_signing_alg_values_supported") != null) { 1750 1751 as.tokenEndpointJWSAlgs = new ArrayList<>(); 1752 1753 for (String v: JSONObjectUtils.getStringArray(jsonObject, "token_endpoint_auth_signing_alg_values_supported")) { 1754 1755 if (v != null && v.equals(Algorithm.NONE.getName())) 1756 throw new ParseException("The none algorithm is not accepted"); 1757 1758 if (v != null) 1759 as.tokenEndpointJWSAlgs.add(JWSAlgorithm.parse(v)); 1760 } 1761 } 1762 1763 if (jsonObject.get("introspection_endpoint_auth_methods_supported") != null) { 1764 1765 as.introspectionEndpointAuthMethods = new ArrayList<>(); 1766 1767 for (String v: JSONObjectUtils.getStringArray(jsonObject, "introspection_endpoint_auth_methods_supported")) { 1768 1769 if (v != null) 1770 as.introspectionEndpointAuthMethods.add(ClientAuthenticationMethod.parse(v)); 1771 } 1772 } 1773 1774 if (jsonObject.get("introspection_endpoint_auth_signing_alg_values_supported") != null) { 1775 1776 as.introspectionEndpointJWSAlgs = new ArrayList<>(); 1777 1778 for (String v: JSONObjectUtils.getStringArray(jsonObject, "introspection_endpoint_auth_signing_alg_values_supported")) { 1779 1780 if (v != null && v.equals(Algorithm.NONE.getName())) 1781 throw new ParseException("The none algorithm is not accepted"); 1782 1783 if (v != null) 1784 as.introspectionEndpointJWSAlgs.add(JWSAlgorithm.parse(v)); 1785 } 1786 } 1787 1788 if (jsonObject.get("revocation_endpoint_auth_methods_supported") != null) { 1789 1790 as.revocationEndpointAuthMethods = new ArrayList<>(); 1791 1792 for (String v: JSONObjectUtils.getStringArray(jsonObject, "revocation_endpoint_auth_methods_supported")) { 1793 1794 if (v != null) 1795 as.revocationEndpointAuthMethods.add(ClientAuthenticationMethod.parse(v)); 1796 } 1797 } 1798 1799 if (jsonObject.get("revocation_endpoint_auth_signing_alg_values_supported") != null) { 1800 1801 as.revocationEndpointJWSAlgs = new ArrayList<>(); 1802 1803 for (String v: JSONObjectUtils.getStringArray(jsonObject, "revocation_endpoint_auth_signing_alg_values_supported")) { 1804 1805 if (v != null && v.equals(Algorithm.NONE.getName())) 1806 throw new ParseException("The none algorithm is not accepted"); 1807 1808 if (v != null) 1809 as.revocationEndpointJWSAlgs.add(JWSAlgorithm.parse(v)); 1810 } 1811 } 1812 1813 1814 // Request object 1815 if (jsonObject.get("request_object_signing_alg_values_supported") != null) { 1816 1817 as.requestObjectJWSAlgs = new ArrayList<>(); 1818 1819 for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_signing_alg_values_supported")) { 1820 1821 if (v != null) 1822 as.requestObjectJWSAlgs.add(JWSAlgorithm.parse(v)); 1823 } 1824 } 1825 1826 1827 if (jsonObject.get("request_object_encryption_alg_values_supported") != null) { 1828 1829 as.requestObjectJWEAlgs = new ArrayList<>(); 1830 1831 for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_encryption_alg_values_supported")) { 1832 1833 if (v != null) 1834 as.requestObjectJWEAlgs.add(JWEAlgorithm.parse(v)); 1835 } 1836 } 1837 1838 1839 if (jsonObject.get("request_object_encryption_enc_values_supported") != null) { 1840 1841 as.requestObjectJWEEncs = new ArrayList<>(); 1842 1843 for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_encryption_enc_values_supported")) { 1844 1845 if (v != null) 1846 as.requestObjectJWEEncs.add(EncryptionMethod.parse(v)); 1847 } 1848 } 1849 1850 1851 // Misc 1852 1853 if (jsonObject.get("ui_locales_supported") != null) { 1854 1855 as.uiLocales = new ArrayList<>(); 1856 1857 for (String v : JSONObjectUtils.getStringArray(jsonObject, "ui_locales_supported")) { 1858 1859 if (v != null) { 1860 1861 try { 1862 as.uiLocales.add(LangTag.parse(v)); 1863 1864 } catch (LangTagException e) { 1865 1866 throw new ParseException("Invalid ui_locales_supported field: " + e.getMessage(), e); 1867 } 1868 } 1869 } 1870 } 1871 1872 if (jsonObject.get("service_documentation") != null) { 1873 try { 1874 as.setServiceDocsURI(JSONObjectUtils.getURI(jsonObject, "service_documentation")); 1875 } catch (IllegalArgumentException e) { 1876 throw new ParseException("Illegal service_documentation parameter: " + e.getMessage()); 1877 } 1878 } 1879 1880 if (jsonObject.get("op_policy_uri") != null) { 1881 try { 1882 as.setPolicyURI(JSONObjectUtils.getURI(jsonObject, "op_policy_uri")); 1883 } catch (IllegalArgumentException e) { 1884 throw new ParseException("Illegal op_policy_uri parameter: " + e.getMessage()); 1885 } 1886 } 1887 1888 if (jsonObject.get("op_tos_uri") != null) { 1889 try { 1890 as.setTermsOfServiceURI(JSONObjectUtils.getURI(jsonObject, "op_tos_uri")); 1891 } catch (IllegalArgumentException e) { 1892 throw new ParseException("Illegal op_tos_uri parameter: " + e.getMessage()); 1893 } 1894 } 1895 1896 if (jsonObject.get("request_parameter_supported") != null) 1897 as.requestParamSupported = JSONObjectUtils.getBoolean(jsonObject, "request_parameter_supported"); 1898 1899 if (jsonObject.get("request_uri_parameter_supported") != null) 1900 as.requestURIParamSupported = JSONObjectUtils.getBoolean(jsonObject, "request_uri_parameter_supported"); 1901 1902 if (jsonObject.get("require_request_uri_registration") != null) 1903 as.requireRequestURIReg = JSONObjectUtils.getBoolean(jsonObject, "require_request_uri_registration"); 1904 1905 if (jsonObject.get("authorization_response_iss_parameter_supported") != null) 1906 as.authzResponseIssParameterSupported = JSONObjectUtils.getBoolean(jsonObject, "authorization_response_iss_parameter_supported"); 1907 1908 if (jsonObject.get("mtls_endpoint_aliases") != null) 1909 as.mtlsEndpointAliases = AuthorizationServerEndpointMetadata.parse(JSONObjectUtils.getJSONObject(jsonObject, "mtls_endpoint_aliases")); 1910 1911 if (jsonObject.get("tls_client_certificate_bound_access_tokens") != null) 1912 as.tlsClientCertificateBoundAccessTokens = JSONObjectUtils.getBoolean(jsonObject, "tls_client_certificate_bound_access_tokens"); 1913 1914 // DPoP 1915 if (jsonObject.get("dpop_signing_alg_values_supported") != null) { 1916 1917 as.dPoPJWSAlgs = new ArrayList<>(); 1918 1919 for (String v: JSONObjectUtils.getStringArray(jsonObject, "dpop_signing_alg_values_supported")) { 1920 1921 if (v != null) 1922 as.dPoPJWSAlgs.add(JWSAlgorithm.parse(v)); 1923 } 1924 } 1925 1926 // JARM 1927 if (jsonObject.get("authorization_signing_alg_values_supported") != null) { 1928 1929 as.authzJWSAlgs = new ArrayList<>(); 1930 1931 for (String v: JSONObjectUtils.getStringArray(jsonObject, "authorization_signing_alg_values_supported")) { 1932 1933 if (v != null) 1934 as.authzJWSAlgs.add(JWSAlgorithm.parse(v)); 1935 } 1936 } 1937 1938 1939 if (jsonObject.get("authorization_encryption_alg_values_supported") != null) { 1940 1941 as.authzJWEAlgs = new ArrayList<>(); 1942 1943 for (String v: JSONObjectUtils.getStringArray(jsonObject, "authorization_encryption_alg_values_supported")) { 1944 1945 if (v != null) 1946 as.authzJWEAlgs.add(JWEAlgorithm.parse(v)); 1947 } 1948 } 1949 1950 1951 if (jsonObject.get("authorization_encryption_enc_values_supported") != null) { 1952 1953 as.authzJWEEncs = new ArrayList<>(); 1954 1955 for (String v: JSONObjectUtils.getStringArray(jsonObject, "authorization_encryption_enc_values_supported")) { 1956 1957 if (v != null) 1958 as.authzJWEEncs.add(EncryptionMethod.parse(v)); 1959 } 1960 } 1961 1962 // PAR 1963 if (jsonObject.get("require_pushed_authorization_requests") != null) { 1964 as.requiresPushedAuthorizationRequests(JSONObjectUtils.getBoolean(jsonObject, "require_pushed_authorization_requests")); 1965 } 1966 1967 // Incremental authz 1968 if (jsonObject.get("incremental_authz_types_supported") != null) { 1969 1970 as.incrementalAuthzTypes = new ArrayList<>(); 1971 1972 for (String v: JSONObjectUtils.getStringArray(jsonObject, "incremental_authz_types_supported")) { 1973 1974 if (v != null) { 1975 ClientType clientType; 1976 try { 1977 clientType = ClientType.valueOf(v.toUpperCase()); 1978 } catch (IllegalArgumentException e) { 1979 throw new ParseException("Illegal client type in incremental_authz_types_supported field: " + v); 1980 } 1981 as.incrementalAuthzTypes.add(clientType); 1982 } 1983 } 1984 } 1985 1986 // Parse custom (not registered) parameters 1987 JSONObject customParams = new JSONObject(jsonObject); 1988 customParams.keySet().removeAll(REGISTERED_PARAMETER_NAMES); 1989 for (Map.Entry<String,Object> customEntry: customParams.entrySet()) { 1990 as.setCustomParameter(customEntry.getKey(), customEntry.getValue()); 1991 } 1992 1993 return as; 1994 } 1995 1996 1997 /** 1998 * Parses an OAuth 2.0 Authorisation Server metadata from the specified 1999 * JSON object string. 2000 * 2001 * @param s The JSON object sting to parse. Must not be {@code null}. 2002 * 2003 * @return The OAuth 2.0 Authorisation Server metadata. 2004 * 2005 * @throws ParseException If the JSON object string couldn't be parsed 2006 * to an OAuth 2.0 Authorisation Server 2007 * metadata. 2008 */ 2009 public static AuthorizationServerMetadata parse(final String s) 2010 throws ParseException { 2011 2012 return parse(JSONObjectUtils.parse(s)); 2013 } 2014 2015 2016 /** 2017 * Resolves OAuth 2.0 authorisation server metadata URL from the 2018 * specified issuer identifier. 2019 * 2020 * @param issuer The issuer identifier. Must represent a valid HTTPS or 2021 * HTTP URL. Must not be {@code null}. 2022 * 2023 * @return The OAuth 2.0 authorisation server metadata URL. 2024 * 2025 * @throws GeneralException If the issuer identifier is invalid. 2026 */ 2027 public static URL resolveURL(final Issuer issuer) 2028 throws GeneralException { 2029 2030 try { 2031 URL issuerURL = new URL(issuer.getValue()); 2032 2033 // Validate but don't insist on HTTPS 2034 if (issuerURL.getQuery() != null && ! issuerURL.getQuery().trim().isEmpty()) { 2035 throw new GeneralException("The issuer identifier must not contain a query component"); 2036 } 2037 2038 if (issuerURL.getPath() != null && issuerURL.getPath().endsWith("/")) { 2039 return new URL(issuerURL + ".well-known/oauth-authorization-server"); 2040 } else { 2041 return new URL(issuerURL + "/.well-known/oauth-authorization-server"); 2042 } 2043 2044 } catch (MalformedURLException e) { 2045 throw new GeneralException("The issuer identifier doesn't represent a valid URL: " + e.getMessage(), e); 2046 } 2047 } 2048 2049 2050 /** 2051 * Resolves OAuth 2.0 authorisation server metadata from the specified 2052 * issuer identifier. The metadata is downloaded by HTTP GET from 2053 * {@code [issuer-url]/.well-known/oauth-authorization-server}. 2054 * 2055 * @param issuer The issuer identifier. Must represent a valid HTTPS or 2056 * HTTP URL. Must not be {@code null}. 2057 * 2058 * @return The OAuth 2.0 authorisation server metadata. 2059 * 2060 * @throws GeneralException If the issuer identifier or the downloaded 2061 * metadata are invalid. 2062 * @throws IOException On a HTTP exception. 2063 */ 2064 public static AuthorizationServerMetadata resolve(final Issuer issuer) 2065 throws GeneralException, IOException { 2066 2067 return resolve(issuer, 0, 0); 2068 } 2069 2070 2071 /** 2072 * Resolves OAuth 2.0 authorisation server metadata from the specified 2073 * issuer identifier. The metadata is downloaded by HTTP GET from 2074 * {@code [issuer-url]/.well-known/oauth-authorization-server}. 2075 * 2076 * @param issuer The issuer identifier. Must represent a valid 2077 * HTTPS or HTTP URL. Must not be {@code null}. 2078 * @param connectTimeout The HTTP connect timeout, in milliseconds. 2079 * Zero implies no timeout. Must not be negative. 2080 * @param readTimeout The HTTP response read timeout, in 2081 * milliseconds. Zero implies no timeout. Must 2082 * not be negative. 2083 * 2084 * @return The OAuth 2.0 authorisation server metadata. 2085 * 2086 * @throws GeneralException If the issuer identifier or the downloaded 2087 * metadata are invalid. 2088 * @throws IOException On a HTTP exception. 2089 */ 2090 public static AuthorizationServerMetadata resolve(final Issuer issuer, 2091 final int connectTimeout, 2092 final int readTimeout) 2093 throws GeneralException, IOException { 2094 2095 URL configURL = resolveURL(issuer); 2096 2097 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.GET, configURL); 2098 httpRequest.setConnectTimeout(connectTimeout); 2099 httpRequest.setReadTimeout(readTimeout); 2100 2101 HTTPResponse httpResponse = httpRequest.send(); 2102 2103 if (httpResponse.getStatusCode() != 200) { 2104 throw new IOException("Couldn't download OAuth 2.0 Authorization Server metadata from " + configURL + 2105 ": Status code " + httpResponse.getStatusCode()); 2106 } 2107 2108 JSONObject jsonObject = httpResponse.getContentAsJSONObject(); 2109 2110 AuthorizationServerMetadata as = AuthorizationServerMetadata.parse(jsonObject); 2111 2112 if (! issuer.equals(as.issuer)) { 2113 throw new GeneralException("The returned issuer doesn't match the expected: " + as.getIssuer()); 2114 } 2115 2116 return as; 2117 } 2118}