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