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