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