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