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