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