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