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