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