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