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