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