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