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