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 com.nimbusds.jose.Algorithm; 022import com.nimbusds.jose.EncryptionMethod; 023import com.nimbusds.jose.JWEAlgorithm; 024import com.nimbusds.jose.JWSAlgorithm; 025import com.nimbusds.jose.jwk.JWKSet; 026import com.nimbusds.langtag.LangTag; 027import com.nimbusds.langtag.LangTagException; 028import com.nimbusds.oauth2.sdk.*; 029import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod; 030import com.nimbusds.oauth2.sdk.ciba.BackChannelTokenDeliveryMode; 031import com.nimbusds.oauth2.sdk.client.ClientType; 032import com.nimbusds.oauth2.sdk.http.HTTPRequest; 033import com.nimbusds.oauth2.sdk.http.HTTPRequestConfigurator; 034import com.nimbusds.oauth2.sdk.http.HTTPRequestModifier; 035import com.nimbusds.oauth2.sdk.http.HTTPResponse; 036import com.nimbusds.oauth2.sdk.id.Identifier; 037import com.nimbusds.oauth2.sdk.id.Issuer; 038import com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod; 039import com.nimbusds.oauth2.sdk.rar.AuthorizationType; 040import com.nimbusds.oauth2.sdk.util.*; 041import com.nimbusds.openid.connect.sdk.Prompt; 042import com.nimbusds.openid.connect.sdk.federation.registration.ClientRegistrationType; 043import com.nimbusds.openid.connect.sdk.op.EndpointName; 044import net.minidev.json.JSONObject; 045 046import java.io.IOException; 047import java.net.MalformedURLException; 048import java.net.URI; 049import java.net.URISyntaxException; 050import java.net.URL; 051import java.util.*; 052 053 054/** 055 * OAuth 2.0 Authorisation Server (AS) metadata. 056 * 057 * <p>Related specifications: 058 * 059 * <ul> 060 * <li>OAuth 2.0 Authorization Server Metadata (RFC 8414) 061 * <li>OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound 062 * Access Tokens (RFC 8705) 063 * <li>OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer 064 * (DPoP) (RFC 9449) 065 * <li>Financial-grade API: JWT Secured Authorization Response Mode for 066 * OAuth 2.0 (JARM) 067 * <li>OAuth 2.0 Authorization Server Issuer Identification (RFC 9207) 068 * <li>Financial-grade API - Part 2: Read and Write API Security Profile 069 * <li>OAuth 2.0 Pushed Authorization Requests (RFC 9126) 070 * <li>OAuth 2.0 Rich Authorization Requests (RFC 9396) 071 * <li>OAuth 2.0 Device Authorization Grant (RFC 8628) 072 * <li>OpenID Connect Client Initiated Backchannel Authentication Flow - 073 * Core 1.0 074 * <li>OAuth 2.0 Incremental Authorization 075 * (draft-ietf-oauth-incremental-authz) 076 * <li>Initiating User Registration via OpenID Connect 1.0 077 * <li>OpenID Connect Federation 1.0 078 * </ul> 079 */ 080public class AuthorizationServerMetadata extends AuthorizationServerEndpointMetadata implements ReadOnlyAuthorizationServerMetadata { 081 082 /** 083 * The registered parameter names. 084 */ 085 private static final Set<String> REGISTERED_PARAMETER_NAMES; 086 087 static { 088 Set<String> p = new HashSet<>(AuthorizationServerEndpointMetadata.getRegisteredParameterNames()); 089 p.add("issuer"); 090 p.add("jwks_uri"); 091 p.add("scopes_supported"); 092 p.add("response_types_supported"); 093 p.add("response_modes_supported"); 094 p.add("grant_types_supported"); 095 p.add("code_challenge_methods_supported"); 096 p.add("token_endpoint_auth_methods_supported"); 097 p.add("token_endpoint_auth_signing_alg_values_supported"); 098 p.add("request_parameter_supported"); 099 p.add("request_uri_parameter_supported"); 100 p.add("require_request_uri_registration"); 101 p.add("request_object_signing_alg_values_supported"); 102 p.add("request_object_encryption_alg_values_supported"); 103 p.add("request_object_encryption_enc_values_supported"); 104 p.add("ui_locales_supported"); 105 p.add("service_documentation"); 106 p.add("op_policy_uri"); 107 p.add("op_tos_uri"); 108 p.add("introspection_endpoint_auth_methods_supported"); 109 p.add("introspection_endpoint_auth_signing_alg_values_supported"); 110 p.add("revocation_endpoint_auth_methods_supported"); 111 p.add("revocation_endpoint_auth_signing_alg_values_supported"); 112 p.add("mtls_endpoint_aliases"); 113 p.add("tls_client_certificate_bound_access_tokens"); 114 p.add("dpop_signing_alg_values_supported"); 115 p.add("authorization_signing_alg_values_supported"); 116 p.add("authorization_encryption_alg_values_supported"); 117 p.add("authorization_encryption_enc_values_supported"); 118 p.add("require_pushed_authorization_requests"); 119 p.add("authorization_details_types_supported"); 120 p.add("incremental_authz_types_supported"); 121 p.add("authorization_response_iss_parameter_supported"); 122 p.add("backchannel_token_delivery_modes_supported"); 123 p.add("backchannel_authentication_request_signing_alg_values_supported"); 124 p.add("backchannel_user_code_parameter_supported"); 125 p.add("prompt_values_supported"); 126 p.add("organization_name"); 127 p.add("jwks"); 128 p.add("signed_jwks_uri"); 129 p.add("client_registration_types_supported"); 130 p.add("request_authentication_methods_supported"); 131 p.add("request_authentication_signing_alg_values_supported"); 132 p.add("federation_registration_endpoint"); 133 REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p); 134 } 135 136 137 /** 138 * Gets the registered OpenID Connect provider metadata parameter 139 * names. 140 * 141 * @return The registered OpenID Connect provider metadata parameter 142 * names, as an unmodifiable set. 143 */ 144 public static Set<String> getRegisteredParameterNames() { 145 146 return REGISTERED_PARAMETER_NAMES; 147 } 148 149 150 /** 151 * The issuer. 152 */ 153 private final Issuer issuer; 154 155 156 /** 157 * The JWK set URI. 158 */ 159 private URI jwkSetURI; 160 161 162 /** 163 * The supported scope values. 164 */ 165 private Scope scope; 166 167 168 /** 169 * The supported response types. 170 */ 171 private List<ResponseType> rts; 172 173 174 /** 175 * The supported response modes. 176 */ 177 private List<ResponseMode> rms; 178 179 180 /** 181 * The supported grant types. 182 */ 183 private List<GrantType> gts; 184 185 186 /** 187 * The supported code challenge methods for PKCE. 188 */ 189 private List<CodeChallengeMethod> codeChallengeMethods; 190 191 192 /** 193 * The supported token endpoint authentication methods. 194 */ 195 private List<ClientAuthenticationMethod> tokenEndpointAuthMethods; 196 197 198 /** 199 * The supported JWS algorithms for the {@code private_key_jwt} and 200 * {@code client_secret_jwt} token endpoint authentication methods. 201 */ 202 private List<JWSAlgorithm> tokenEndpointJWSAlgs; 203 204 205 /** 206 * The supported introspection endpoint authentication methods. 207 */ 208 private List<ClientAuthenticationMethod> introspectionEndpointAuthMethods; 209 210 211 /** 212 * The supported JWS algorithms for the {@code private_key_jwt} and 213 * {@code client_secret_jwt} introspection endpoint authentication 214 * methods. 215 */ 216 private List<JWSAlgorithm> introspectionEndpointJWSAlgs; 217 218 219 /** 220 * The supported revocation endpoint authentication methods. 221 */ 222 private List<ClientAuthenticationMethod> revocationEndpointAuthMethods; 223 224 225 /** 226 * The supported JWS algorithms for the {@code private_key_jwt} and 227 * {@code client_secret_jwt} revocation endpoint authentication 228 * methods. 229 */ 230 private List<JWSAlgorithm> revocationEndpointJWSAlgs; 231 232 233 /** 234 * The supported JWS algorithms for request objects. 235 */ 236 private List<JWSAlgorithm> requestObjectJWSAlgs; 237 238 239 /** 240 * The supported JWE algorithms for request objects. 241 */ 242 private List<JWEAlgorithm> requestObjectJWEAlgs; 243 244 245 /** 246 * The supported encryption methods for request objects. 247 */ 248 private List<EncryptionMethod> requestObjectJWEEncs; 249 250 251 /** 252 * If {@code true} the {@code request} parameter is supported, else 253 * not. 254 */ 255 private boolean requestParamSupported = false; 256 257 258 /** 259 * If {@code true} the {@code request_uri} parameter is supported, else 260 * not. 261 */ 262 private boolean requestURIParamSupported = false; 263 264 265 /** 266 * If {@code true} the {@code request_uri} parameters must be 267 * pre-registered with the provider, else not. 268 */ 269 private boolean requireRequestURIReg = false; 270 271 272 /** 273 * If {@code true} the {@code iss} authorisation response is supported, 274 * else not. 275 */ 276 private boolean authzResponseIssParameterSupported = false; 277 278 279 /** 280 * The supported UI locales. 281 */ 282 private List<LangTag> uiLocales; 283 284 285 /** 286 * The service documentation URI. 287 */ 288 private URI serviceDocsURI; 289 290 291 /** 292 * The provider's policy regarding relying party use of data. 293 */ 294 private URI policyURI; 295 296 297 /** 298 * The provider's terms of service. 299 */ 300 private URI tosURI; 301 302 303 /** 304 * Aliases for endpoints with mutial TLS authentication. 305 */ 306 private AuthorizationServerEndpointMetadata mtlsEndpointAliases; 307 308 309 /** 310 * If {@code true} the 311 * {@code tls_client_certificate_bound_access_tokens} if set, else 312 * not. 313 */ 314 private boolean tlsClientCertificateBoundAccessTokens = false; 315 316 317 /** 318 * The supported JWS algorithms for DPoP. 319 */ 320 private List<JWSAlgorithm> dPoPJWSAlgs; 321 322 323 /** 324 * The supported JWS algorithms for JWT-encoded authorisation 325 * responses. 326 */ 327 private List<JWSAlgorithm> authzJWSAlgs; 328 329 330 /** 331 * The supported JWE algorithms for JWT-encoded authorisation 332 * responses. 333 */ 334 private List<JWEAlgorithm> authzJWEAlgs; 335 336 337 /** 338 * The supported encryption methods for JWT-encoded authorisation 339 * responses. 340 */ 341 private List<EncryptionMethod> authzJWEEncs; 342 343 344 /** 345 * If {@code true} PAR is required, else not. 346 */ 347 private boolean requirePAR = false; 348 349 350 /** 351 * The supported authorisation details types. 352 */ 353 private List<AuthorizationType> authzTypes; 354 355 356 /** 357 * The supported OAuth 2.0 client types for incremental authorisation. 358 */ 359 private List<ClientType> incrementalAuthzTypes; 360 361 362 /** 363 * The supported CIBA token delivery modes. 364 */ 365 private List<BackChannelTokenDeliveryMode> backChannelTokenDeliveryModes; 366 367 368 /** 369 * The supported JWS algorithms for CIBA requests. If omitted signed 370 * authentication requests are not supported. 371 */ 372 private List<JWSAlgorithm> backChannelAuthRequestJWSAlgs; 373 374 375 /** 376 * If {@code true} the CIBA {@code user_code} parameter is supported, 377 * else not. 378 */ 379 private boolean backChannelUserCodeSupported = false; 380 381 382 /** 383 * The supported prompt types. 384 */ 385 private List<Prompt.Type> promptTypes; 386 387 388 /** 389 * The organisation name (OpenID Connect Federation 1.0). 390 */ 391 private String organizationName; 392 393 394 /** 395 * The OP JWK set (OpenID Connect Federation 1.0). 396 */ 397 private JWKSet jwkSet; 398 399 400 /** 401 * The signed OP JWK set (OpenID Connect Federation 1.0). 402 */ 403 private URI signedJWKSetURI; 404 405 406 /** 407 * The supported OpenID Connect Federation 1.0 client registration 408 * types. 409 */ 410 private List<ClientRegistrationType> clientRegistrationTypes; 411 412 413 /** 414 * The supported request authentication methods for automatic OpenID 415 * Connect Federation 1.0 client registration. 416 */ 417 private Map<EndpointName,List<ClientAuthenticationMethod>> clientRegistrationAuthMethods; 418 419 420 /** 421 * The supported JWS algorithms for authenticating automatic OpenID 422 * Connect Federation 1.0 client registration requests. 423 */ 424 private List<JWSAlgorithm> clientRegistrationAuthJWSAlgs; 425 426 427 /** 428 * The OpenID Connect Federation 1.0 registration endpoint. 429 */ 430 private URI federationRegistrationEndpoint; 431 432 433 /** 434 * Custom (not-registered) parameters. 435 */ 436 private final JSONObject customParameters = new JSONObject(); 437 438 439 /** 440 * Creates a new OAuth 2.0 Authorisation Server (AS) metadata instance. 441 * 442 * @param issuer The issuer identifier. Must be a URI using the https 443 * scheme with no query or fragment component. Must not 444 * be {@code null}. 445 */ 446 public AuthorizationServerMetadata(final Issuer issuer) { 447 448 URI uri; 449 try { 450 uri = new URI(issuer.getValue()); 451 } catch (URISyntaxException e) { 452 throw new IllegalArgumentException("The issuer identifier must be a URI: " + e.getMessage(), e); 453 } 454 455 if (uri.getRawQuery() != null) 456 throw new IllegalArgumentException("The issuer URI must be without a query component"); 457 458 if (uri.getRawFragment() != null) 459 throw new IllegalArgumentException("The issuer URI must be without a fragment component"); 460 461 this.issuer = issuer; 462 } 463 464 465 @Override 466 public Issuer getIssuer() { 467 return issuer; 468 } 469 470 471 @Override 472 public URI getJWKSetURI() { 473 return jwkSetURI; 474 } 475 476 477 /** 478 * Sets the JSON Web Key (JWT) set URI. Corresponds to the 479 * {@code jwks_uri} metadata field. 480 * 481 * @param jwkSetURI The JWK set URI, {@code null} if not specified. 482 */ 483 public void setJWKSetURI(final URI jwkSetURI) { 484 this.jwkSetURI = jwkSetURI; 485 } 486 487 488 @Override 489 public Scope getScopes() { 490 return scope; 491 } 492 493 494 /** 495 * Sets the supported scope values. Corresponds to the 496 * {@code scopes_supported} metadata field. 497 * 498 * @param scope The supported scope values, {@code null} if not 499 * specified. 500 */ 501 public void setScopes(final Scope scope) { 502 this.scope = scope; 503 } 504 505 506 @Override 507 public List<ResponseType> getResponseTypes() { 508 return rts; 509 } 510 511 512 /** 513 * Sets the supported response type values. Corresponds to the 514 * {@code response_types_supported} metadata field. 515 * 516 * @param rts The supported response type values, {@code null} if not 517 * specified. 518 */ 519 public void setResponseTypes(final List<ResponseType> rts) { 520 this.rts = rts; 521 } 522 523 524 @Override 525 public List<ResponseMode> getResponseModes() { 526 return rms; 527 } 528 529 530 /** 531 * Sets the supported response mode values. Corresponds to the 532 * {@code response_modes_supported}. 533 * 534 * @param rms The supported response mode values, {@code null} if not 535 * specified. 536 */ 537 public void setResponseModes(final List<ResponseMode> rms) { 538 this.rms = rms; 539 } 540 541 542 @Override 543 public List<GrantType> getGrantTypes() { 544 return gts; 545 } 546 547 548 /** 549 * Sets the supported OAuth 2.0 grant types. Corresponds to the 550 * {@code grant_types_supported} metadata field. 551 * 552 * @param gts The supported grant types, {@code null} if not specified. 553 */ 554 public void setGrantTypes(final List<GrantType> gts) { 555 this.gts = gts; 556 } 557 558 559 @Override 560 public List<CodeChallengeMethod> getCodeChallengeMethods() { 561 return codeChallengeMethods; 562 } 563 564 565 /** 566 * Gets the supported authorisation code challenge methods for PKCE. 567 * Corresponds to the {@code code_challenge_methods_supported} metadata 568 * field. 569 * 570 * @param codeChallengeMethods The supported code challenge methods, 571 * {@code null} if not specified. 572 */ 573 public void setCodeChallengeMethods(final List<CodeChallengeMethod> codeChallengeMethods) { 574 this.codeChallengeMethods = codeChallengeMethods; 575 } 576 577 578 @Override 579 public List<ClientAuthenticationMethod> getTokenEndpointAuthMethods() { 580 return tokenEndpointAuthMethods; 581 } 582 583 584 /** 585 * Sets the supported token endpoint authentication methods. 586 * Corresponds to the {@code token_endpoint_auth_methods_supported} 587 * metadata field. 588 * 589 * @param authMethods The supported token endpoint authentication 590 * methods, {@code null} if not specified. 591 */ 592 public void setTokenEndpointAuthMethods(final List<ClientAuthenticationMethod> authMethods) { 593 this.tokenEndpointAuthMethods = authMethods; 594 } 595 596 597 @Override 598 public List<JWSAlgorithm> getTokenEndpointJWSAlgs() { 599 return tokenEndpointJWSAlgs; 600 } 601 602 603 /** 604 * Sets the supported JWS algorithms for the {@code private_key_jwt} 605 * and {@code client_secret_jwt} token endpoint authentication methods. 606 * Corresponds to the 607 * {@code token_endpoint_auth_signing_alg_values_supported} metadata 608 * field. 609 * 610 * @param jwsAlgs The supported JWS algorithms, {@code null} if not 611 * specified. Must not contain the {@code none} 612 * algorithm. 613 */ 614 public void setTokenEndpointJWSAlgs(final List<JWSAlgorithm> jwsAlgs) { 615 if (jwsAlgs != null && jwsAlgs.contains(Algorithm.NONE)) 616 throw new IllegalArgumentException("The \"none\" algorithm is not accepted"); 617 618 this.tokenEndpointJWSAlgs = jwsAlgs; 619 } 620 621 622 @Override 623 public List<ClientAuthenticationMethod> getIntrospectionEndpointAuthMethods() { 624 return introspectionEndpointAuthMethods; 625 } 626 627 628 /** 629 * Sets the supported introspection endpoint authentication methods. 630 * Corresponds to the 631 * {@code introspection_endpoint_auth_methods_supported} metadata 632 * field. 633 * 634 * @param authMethods The supported introspection endpoint 635 * authentication methods, {@code null} if not 636 * specified. 637 */ 638 public void setIntrospectionEndpointAuthMethods(final List<ClientAuthenticationMethod> authMethods) { 639 this.introspectionEndpointAuthMethods = authMethods; 640 } 641 642 643 @Override 644 public List<JWSAlgorithm> getIntrospectionEndpointJWSAlgs() { 645 return introspectionEndpointJWSAlgs; 646 } 647 648 649 /** 650 * Sets the supported JWS algorithms for the {@code private_key_jwt} 651 * and {@code client_secret_jwt} introspection endpoint authentication 652 * methods. Corresponds to the 653 * {@code introspection_endpoint_auth_signing_alg_values_supported} 654 * metadata field. 655 * 656 * @param jwsAlgs The supported JWS algorithms, {@code null} if not 657 * specified. Must not contain the {@code none} 658 * algorithm. 659 */ 660 public void setIntrospectionEndpointJWSAlgs(final List<JWSAlgorithm> jwsAlgs) { 661 662 if (jwsAlgs != null && jwsAlgs.contains(Algorithm.NONE)) 663 throw new IllegalArgumentException("The \"none\" algorithm is not accepted"); 664 665 introspectionEndpointJWSAlgs = jwsAlgs; 666 } 667 668 669 @Override 670 public List<ClientAuthenticationMethod> getRevocationEndpointAuthMethods() { 671 return revocationEndpointAuthMethods; 672 } 673 674 675 /** 676 * Sets the supported revocation endpoint authentication methods. 677 * Corresponds to the 678 * {@code revocation_endpoint_auth_methods_supported} metadata field. 679 * 680 * @param authMethods The supported revocation endpoint authentication 681 * methods, {@code null} if not specified. 682 */ 683 public void setRevocationEndpointAuthMethods(final List<ClientAuthenticationMethod> authMethods) { 684 revocationEndpointAuthMethods = authMethods; 685 } 686 687 688 @Override 689 public List<JWSAlgorithm> getRevocationEndpointJWSAlgs() { 690 return revocationEndpointJWSAlgs; 691 } 692 693 694 /** 695 * Sets the supported JWS algorithms for the {@code private_key_jwt} 696 * and {@code client_secret_jwt} revocation endpoint authentication 697 * methods. Corresponds to the 698 * {@code revocation_endpoint_auth_signing_alg_values_supported} 699 * metadata field. 700 * 701 * @param jwsAlgs The supported JWS algorithms, {@code null} if not 702 * specified. Must not contain the {@code none} 703 * algorithm. 704 */ 705 public void setRevocationEndpointJWSAlgs(final List<JWSAlgorithm> jwsAlgs) { 706 707 if (jwsAlgs != null && jwsAlgs.contains(Algorithm.NONE)) 708 throw new IllegalArgumentException("The \"none\" algorithm is not accepted"); 709 710 revocationEndpointJWSAlgs = jwsAlgs; 711 } 712 713 714 @Override 715 public List<JWSAlgorithm> getRequestObjectJWSAlgs() { 716 return requestObjectJWSAlgs; 717 } 718 719 720 /** 721 * Sets the supported JWS algorithms for request objects. Corresponds 722 * to the {@code request_object_signing_alg_values_supported} metadata 723 * field. 724 * 725 * @param requestObjectJWSAlgs The supported JWS algorithms, 726 * {@code null} if not specified. 727 */ 728 public void setRequestObjectJWSAlgs(final List<JWSAlgorithm> requestObjectJWSAlgs) { 729 this.requestObjectJWSAlgs = requestObjectJWSAlgs; 730 } 731 732 733 @Override 734 public List<JWEAlgorithm> getRequestObjectJWEAlgs() { 735 return requestObjectJWEAlgs; 736 } 737 738 739 /** 740 * Sets the supported JWE algorithms for request objects. Corresponds 741 * to the {@code request_object_encryption_alg_values_supported} 742 * metadata field. 743 * 744 * @param requestObjectJWEAlgs The supported JWE algorithms, 745 * {@code null} if not specified. 746 */ 747 public void setRequestObjectJWEAlgs(final List<JWEAlgorithm> requestObjectJWEAlgs) { 748 this.requestObjectJWEAlgs = requestObjectJWEAlgs; 749 } 750 751 752 @Override 753 public List<EncryptionMethod> getRequestObjectJWEEncs() { 754 return requestObjectJWEEncs; 755 } 756 757 758 /** 759 * Sets the supported encryption methods for request objects. 760 * Corresponds to the 761 * {@code request_object_encryption_enc_values_supported} metadata 762 * field. 763 * 764 * @param requestObjectJWEEncs The supported encryption methods, 765 * {@code null} if not specified. 766 */ 767 public void setRequestObjectJWEEncs(final List<EncryptionMethod> requestObjectJWEEncs) { 768 this.requestObjectJWEEncs = requestObjectJWEEncs; 769 } 770 771 772 @Override 773 public boolean supportsRequestParam() { 774 return requestParamSupported; 775 } 776 777 778 /** 779 * Sets the support for the {@code request} authorisation request 780 * parameter. Corresponds to the {@code request_parameter_supported} 781 * metadata field. 782 * 783 * @param requestParamSupported {@code true} if the {@code reqeust} 784 * parameter is supported, else 785 * {@code false}. 786 */ 787 public void setSupportsRequestParam(final boolean requestParamSupported) { 788 this.requestParamSupported = requestParamSupported; 789 } 790 791 792 @Override 793 public boolean supportsRequestURIParam() { 794 return requestURIParamSupported; 795 } 796 797 798 /** 799 * Sets the support for the {@code request_uri} authorisation request 800 * parameter. Corresponds to the 801 * {@code request_uri_parameter_supported} metadata field. 802 * 803 * @param requestURIParamSupported {@code true} if the 804 * {@code request_uri} parameter is 805 * supported, else {@code false}. 806 */ 807 public void setSupportsRequestURIParam(final boolean requestURIParamSupported) { 808 this.requestURIParamSupported = requestURIParamSupported; 809 } 810 811 812 @Override 813 public boolean requiresRequestURIRegistration() { 814 return requireRequestURIReg; 815 } 816 817 818 /** 819 * Sets the requirement for the {@code request_uri} parameter 820 * pre-registration. Corresponds to the 821 * {@code require_request_uri_registration} metadata field. 822 * 823 * @param requireRequestURIReg {@code true} if the {@code request_uri} 824 * parameter values must be pre-registered, 825 * else {@code false}. 826 */ 827 public void setRequiresRequestURIRegistration(final boolean requireRequestURIReg) { 828 this.requireRequestURIReg = requireRequestURIReg; 829 } 830 831 832 @Override 833 public boolean supportsAuthorizationResponseIssuerParam() { 834 return authzResponseIssParameterSupported; 835 } 836 837 838 /** 839 * Sets the support for the {@code iss} authorisation response 840 * parameter. Corresponds to the 841 * {@code authorization_response_iss_parameter_supported} metadata 842 * field. 843 * 844 * @param authzResponseIssParameterSupported {@code true} if the 845 * {@code iss} authorisation 846 * response parameter is 847 * provided, else 848 * {@code false}. 849 */ 850 public void setSupportsAuthorizationResponseIssuerParam(final boolean authzResponseIssParameterSupported) { 851 this.authzResponseIssParameterSupported = authzResponseIssParameterSupported; 852 } 853 854 855 @Override 856 public List<LangTag> getUILocales() { 857 return uiLocales; 858 } 859 860 861 /** 862 * Sets the supported UI locales. Corresponds to the 863 * {@code ui_locales_supported} metadata field. 864 * 865 * @param uiLocales The supported UI locales, {@code null} if not 866 * specified. 867 */ 868 public void setUILocales(final List<LangTag> uiLocales) { 869 this.uiLocales = uiLocales; 870 } 871 872 873 @Override 874 public URI getServiceDocsURI() { 875 return serviceDocsURI; 876 } 877 878 879 /** 880 * Sets the service documentation URI. Corresponds to the 881 * {@code service_documentation} metadata field. 882 * 883 * @param serviceDocsURI The service documentation URI, {@code null} if 884 * not specified. The URI scheme must be https or 885 * http. 886 */ 887 public void setServiceDocsURI(final URI serviceDocsURI) { 888 URIUtils.ensureSchemeIsHTTPSorHTTP(serviceDocsURI); 889 this.serviceDocsURI = serviceDocsURI; 890 } 891 892 893 @Override 894 public URI getPolicyURI() { 895 return policyURI; 896 } 897 898 899 /** 900 * Sets the provider's policy regarding relying party use of data. 901 * Corresponds to the {@code op_policy_uri} metadata field. 902 * 903 * @param policyURI The policy URI, {@code null} if not specified. The 904 * URI scheme must be https or http. 905 */ 906 public void setPolicyURI(final URI policyURI) { 907 URIUtils.ensureSchemeIsHTTPSorHTTP(policyURI); 908 this.policyURI = policyURI; 909 } 910 911 912 @Override 913 public URI getTermsOfServiceURI() { 914 return tosURI; 915 } 916 917 918 /** 919 * Sets the provider's terms of service. Corresponds to the 920 * {@code op_tos_uri} metadata field. 921 * 922 * @param tosURI The terms of service URI, {@code null} if not 923 * specified. The URI scheme must be https or http. 924 */ 925 public void setTermsOfServiceURI(final URI tosURI) { 926 URIUtils.ensureSchemeIsHTTPSorHTTP(tosURI); 927 this.tosURI = tosURI; 928 } 929 930 931 @Override 932 public ReadOnlyAuthorizationServerEndpointMetadata getReadOnlyMtlsEndpointAliases() { 933 return getMtlsEndpointAliases(); 934 } 935 936 937 /** 938 * Gets the aliases for communication with mutual TLS. Corresponds to 939 * the {@code mtls_endpoint_aliases} metadata field. 940 * 941 * @return The aliases for communication with mutual TLS, {@code null} 942 * when no aliases are defined. 943 */ 944 public AuthorizationServerEndpointMetadata getMtlsEndpointAliases() { 945 return mtlsEndpointAliases; 946 } 947 948 949 /** 950 * Sets the aliases for communication with mutual TLS. Corresponds to the 951 * {@code mtls_endpoint_aliases} metadata field. 952 * 953 * @param mtlsEndpointAliases The aliases for communication with mutual 954 * TLS, or {@code null} when no aliases are 955 * defined. 956 */ 957 public void setMtlsEndpointAliases(AuthorizationServerEndpointMetadata mtlsEndpointAliases) { 958 this.mtlsEndpointAliases = mtlsEndpointAliases; 959 } 960 961 962 @Override 963 public boolean supportsTLSClientCertificateBoundAccessTokens() { 964 return tlsClientCertificateBoundAccessTokens; 965 } 966 967 968 /** 969 * Sets the support for TLS client certificate bound access tokens. 970 * Corresponds to the 971 * {@code tls_client_certificate_bound_access_tokens} metadata field. 972 * 973 * @param tlsClientCertBoundTokens {@code true} if TLS client 974 * certificate bound access tokens are 975 * supported, else {@code false}. 976 */ 977 public void setSupportsTLSClientCertificateBoundAccessTokens(final boolean tlsClientCertBoundTokens) { 978 tlsClientCertificateBoundAccessTokens = tlsClientCertBoundTokens; 979 } 980 981 982 @Override 983 @Deprecated 984 public boolean supportsMutualTLSSenderConstrainedAccessTokens() { 985 return supportsTLSClientCertificateBoundAccessTokens(); 986 } 987 988 989 /** 990 * Sets the support for TLS client certificate bound access tokens. 991 * Corresponds to the 992 * {@code tls_client_certificate_bound_access_tokens} metadata field. 993 * 994 * @param mutualTLSSenderConstrainedAccessTokens {@code true} if TLS 995 * client certificate 996 * bound access tokens 997 * are supported, else 998 * {@code false}. 999 */ 1000 @Deprecated 1001 public void setSupportsMutualTLSSenderConstrainedAccessTokens(final boolean mutualTLSSenderConstrainedAccessTokens) { 1002 setSupportsTLSClientCertificateBoundAccessTokens(mutualTLSSenderConstrainedAccessTokens); 1003 } 1004 1005 1006 @Override 1007 public List<JWSAlgorithm> getDPoPJWSAlgs() { 1008 return dPoPJWSAlgs; 1009 } 1010 1011 1012 /** 1013 * Sets the supported JWS algorithms for Demonstrating 1014 * Proof-of-Possession at the Application Layer (DPoP). Corresponds to 1015 * the "dpop_signing_alg_values_supported" metadata field. 1016 * 1017 * @param dPoPJWSAlgs The supported JWS algorithms for DPoP, 1018 * {@code null} if none. 1019 */ 1020 public void setDPoPJWSAlgs(final List<JWSAlgorithm> dPoPJWSAlgs) { 1021 this.dPoPJWSAlgs = dPoPJWSAlgs; 1022 } 1023 1024 1025 @Override 1026 public List<JWSAlgorithm> getAuthorizationJWSAlgs() { 1027 return authzJWSAlgs; 1028 } 1029 1030 1031 /** 1032 * Sets the supported JWS algorithms for JWT-encoded authorisation 1033 * responses. Corresponds to the 1034 * {@code authorization_signing_alg_values_supported} metadata field. 1035 * 1036 * @param authzJWSAlgs The supported JWS algorithms, {@code null} if 1037 * not specified. 1038 */ 1039 public void setAuthorizationJWSAlgs(final List<JWSAlgorithm> authzJWSAlgs) { 1040 this.authzJWSAlgs = authzJWSAlgs; 1041 } 1042 1043 1044 @Override 1045 public List<JWEAlgorithm> getAuthorizationJWEAlgs() { 1046 return authzJWEAlgs; 1047 } 1048 1049 1050 /** 1051 * Sets the supported JWE algorithms for JWT-encoded authorisation 1052 * responses. Corresponds to the 1053 * {@code authorization_encryption_alg_values_supported} metadata 1054 * field. 1055 * 1056 * @param authzJWEAlgs The supported JWE algorithms, {@code null} if 1057 * not specified. 1058 */ 1059 public void setAuthorizationJWEAlgs(final List<JWEAlgorithm> authzJWEAlgs) { 1060 this.authzJWEAlgs = authzJWEAlgs; 1061 } 1062 1063 1064 @Override 1065 public List<EncryptionMethod> getAuthorizationJWEEncs() { 1066 return authzJWEEncs; 1067 } 1068 1069 1070 /** 1071 * Sets the supported encryption methods for JWT-encoded authorisation 1072 * responses. Corresponds to the 1073 * {@code authorization_encryption_enc_values_supported} metadata 1074 * field. 1075 * 1076 * @param authzJWEEncs The supported encryption methods, {@code null} 1077 * if not specified. 1078 */ 1079 public void setAuthorizationJWEEncs(final List<EncryptionMethod> authzJWEEncs) { 1080 this.authzJWEEncs = authzJWEEncs; 1081 } 1082 1083 1084 @Override 1085 public boolean requiresPushedAuthorizationRequests() { 1086 return requirePAR; 1087 } 1088 1089 1090 /** 1091 * Sets the requirement for pushed authorisation requests (PAR). 1092 * Corresponds to the {@code pushed_authorization_request_endpoint} 1093 * metadata field. 1094 * 1095 * @param requirePAR {@code true} if PAR is required, else 1096 * {@code false}. 1097 */ 1098 public void requiresPushedAuthorizationRequests(final boolean requirePAR) { 1099 this.requirePAR = requirePAR; 1100 } 1101 1102 1103 @Override 1104 public List<AuthorizationType> getAuthorizationDetailsTypes() { 1105 return authzTypes; 1106 } 1107 1108 1109 /** 1110 * Sets the supported authorisation details types for Rich 1111 * Authorisation Requests (RAR). Corresponds to the 1112 * {@code authorization_details_types_supported} metadata field. 1113 * 1114 * @param authzTypes The supported authorisation types, {@code null} if 1115 * not specified. 1116 */ 1117 public void setAuthorizationDetailsTypes(final List<AuthorizationType> authzTypes) { 1118 this.authzTypes = authzTypes; 1119 } 1120 1121 1122 @Override 1123 public List<ClientType> getIncrementalAuthorizationTypes() { 1124 return incrementalAuthzTypes; 1125 } 1126 1127 1128 /** 1129 * Sets the supported OAuth 2.0 client types for incremental 1130 * authorisation. Corresponds to the 1131 * {@code incremental_authz_types_supported} metadata field. 1132 * 1133 * @param incrementalAuthzTypes The supported client types for 1134 * incremental authorisation, {@code null} 1135 * if not specified. 1136 */ 1137 public void setIncrementalAuthorizationTypes(final List<ClientType> incrementalAuthzTypes) { 1138 this.incrementalAuthzTypes = incrementalAuthzTypes; 1139 } 1140 1141 1142 @Override 1143 public List<BackChannelTokenDeliveryMode> getBackChannelTokenDeliveryModes() { 1144 return backChannelTokenDeliveryModes; 1145 } 1146 1147 1148 /** 1149 * Sets the supported CIBA token delivery modes. Corresponds to the 1150 * {@code backchannel_token_delivery_modes_supported} metadata field. 1151 * 1152 * @param backChannelTokenDeliveryModes The CIBA token delivery modes, 1153 * {@code null} if not specified. 1154 */ 1155 public void setBackChannelTokenDeliveryModes(final List<BackChannelTokenDeliveryMode> backChannelTokenDeliveryModes) { 1156 this.backChannelTokenDeliveryModes = backChannelTokenDeliveryModes; 1157 } 1158 1159 @Override 1160 public List<JWSAlgorithm> getBackChannelAuthenticationRequestJWSAlgs() { 1161 return backChannelAuthRequestJWSAlgs; 1162 } 1163 1164 /** 1165 * Gets the supported JWS algorithms for CIBA requests. Corresponds to 1166 * the {@code backchannel_authentication_request_signing_alg_values_supported} 1167 * metadata field. 1168 * 1169 * @param backChannelAuthRequestJWSAlgs The supported JWS algorithms, 1170 * {@code null} if not specified. 1171 */ 1172 public void setBackChannelAuthenticationRequestJWSAlgs(final List<JWSAlgorithm> backChannelAuthRequestJWSAlgs) { 1173 this.backChannelAuthRequestJWSAlgs = backChannelAuthRequestJWSAlgs; 1174 } 1175 1176 1177 @Override 1178 public boolean supportsBackChannelUserCodeParam() { 1179 return backChannelUserCodeSupported; 1180 } 1181 1182 1183 /** 1184 * Sets the support for the {@code user_code} CIBA request parameter. 1185 * Corresponds to the {@code backchannel_user_code_parameter_supported} 1186 * metadata field. 1187 * 1188 * @param backChannelUserCodeSupported {@code true} if the 1189 * {@code user_code} parameter is 1190 * supported, else {@code false}. 1191 */ 1192 public void setSupportsBackChannelUserCodeParam(final boolean backChannelUserCodeSupported) { 1193 this.backChannelUserCodeSupported = backChannelUserCodeSupported; 1194 } 1195 1196 1197 @Override 1198 public List<Prompt.Type> getPromptTypes() { 1199 return promptTypes; 1200 } 1201 1202 1203 /** 1204 * Sets the supported {@link Prompt.Type prompt types}. Corresponds to 1205 * the {@code prompt_values_supported} metadata field. 1206 * 1207 * @param promptTypes The supported prompt types, {@code null} if not 1208 * specified. 1209 */ 1210 public void setPromptTypes(final List<Prompt.Type> promptTypes) { 1211 this.promptTypes = promptTypes; 1212 } 1213 1214 1215 @Override 1216 public String getOrganizationName() { 1217 return organizationName; 1218 } 1219 1220 1221 /** 1222 * Sets the organisation name (in federation). Corresponds to the 1223 * {@code organization_name} metadata field. 1224 * 1225 * @param organizationName The organisation name, {@code null} if not 1226 * specified. 1227 */ 1228 public void setOrganizationName(final String organizationName) { 1229 this.organizationName = organizationName; 1230 } 1231 1232 1233 @Override 1234 public JWKSet getJWKSet() { 1235 return jwkSet; 1236 } 1237 1238 1239 /** 1240 * Sets the JWK set (OpenID Connect Federation 1.0). Corresponds to the 1241 * {@code jwks} metadata field. 1242 * 1243 * @param jwkSet The JWK set, {@code null} if not specified. 1244 */ 1245 public void setJWKSet(final JWKSet jwkSet) { 1246 this.jwkSet = jwkSet; 1247 } 1248 1249 1250 @Override 1251 public URI getSignedJWKSetURI() { 1252 return signedJWKSetURI; 1253 } 1254 1255 1256 /** 1257 * Sets the signed JWK set URI (OpenID Connect Federation 1.0). 1258 * Corresponds to the {@code signed_jwks_uri} metadata field. 1259 * 1260 * @param signedJWKSetURI The signed JWK set URI, {@code null} if not 1261 * specified. 1262 */ 1263 public void setSignedJWKSetURI(final URI signedJWKSetURI) { 1264 this.signedJWKSetURI = signedJWKSetURI; 1265 } 1266 1267 1268 @Override 1269 public List<ClientRegistrationType> getClientRegistrationTypes() { 1270 return clientRegistrationTypes; 1271 } 1272 1273 1274 /** 1275 * Sets the supported federation client registration types. Corresponds 1276 * to the {@code client_registration_types_supported} metadata field. 1277 * 1278 * @param clientRegistrationTypes The supported client registration 1279 * types, {@code null} if not specified. 1280 */ 1281 public void setClientRegistrationTypes(final List<ClientRegistrationType> clientRegistrationTypes) { 1282 this.clientRegistrationTypes = clientRegistrationTypes; 1283 } 1284 1285 1286 @Override 1287 public Map<EndpointName, List<ClientAuthenticationMethod>> getClientRegistrationAuthnMethods() { 1288 return clientRegistrationAuthMethods; 1289 } 1290 1291 1292 /** 1293 * Sets the supported request authentication methods for automatic 1294 * OpenID Connect Federation 1.0 client registration. Corresponds to 1295 * the {@code request_authentication_methods_supported} field. 1296 * 1297 * @param methods The supported request authentication methods for 1298 * automatic federation client registration, 1299 * {@code null} if not specified. 1300 */ 1301 public void setClientRegistrationAuthnMethods(final Map<EndpointName,List<ClientAuthenticationMethod>> methods) { 1302 clientRegistrationAuthMethods = methods; 1303 } 1304 1305 1306 @Override 1307 public List<JWSAlgorithm> getClientRegistrationAuthnJWSAlgs() { 1308 return clientRegistrationAuthJWSAlgs; 1309 } 1310 1311 1312 /** 1313 * Sets the supported JWS algorithms for authenticating automatic 1314 * OpenID Connect Federation 1.0 client registration requests. 1315 * Corresponds to the 1316 * {@code request_authentication_signing_alg_values_supported}. 1317 * 1318 * @param jwsAlgs The supported JWS algorithms, {@code null} if 1319 * not specified. 1320 */ 1321 public void setClientRegistrationAuthnJWSAlgs(final List<JWSAlgorithm> jwsAlgs) { 1322 clientRegistrationAuthJWSAlgs = jwsAlgs; 1323 } 1324 1325 1326 @Override 1327 public URI getFederationRegistrationEndpointURI() { 1328 return federationRegistrationEndpoint; 1329 } 1330 1331 1332 /** 1333 * Sets the federation registration endpoint URI. Corresponds to the 1334 * {@code federation_registration_endpoint} metadata field. 1335 * 1336 * @param federationRegistrationEndpoint The federation registration 1337 * endpoint URI, {@code null} if 1338 * not specified. 1339 */ 1340 public void setFederationRegistrationEndpointURI(final URI federationRegistrationEndpoint) { 1341 this.federationRegistrationEndpoint = federationRegistrationEndpoint; 1342 } 1343 1344 1345 @Override 1346 public Object getCustomParameter(final String name) { 1347 1348 return customParameters.get(name); 1349 } 1350 1351 1352 @Override 1353 public URI getCustomURIParameter(final String name) { 1354 1355 try { 1356 return JSONObjectUtils.getURI(customParameters, name, null); 1357 } catch (ParseException e) { 1358 return null; 1359 } 1360 } 1361 1362 1363 /** 1364 * Sets the specified custom (not registered) parameter. 1365 * 1366 * @param name The parameter name. Must not be {@code null}. 1367 * @param value The parameter value, {@code null} if not specified. 1368 */ 1369 public void setCustomParameter(final String name, final Object value) { 1370 1371 if (REGISTERED_PARAMETER_NAMES.contains(name)) { 1372 throw new IllegalArgumentException("The " + name + " parameter is registered"); 1373 } 1374 1375 customParameters.put(name, value); 1376 } 1377 1378 1379 @Override 1380 public JSONObject getCustomParameters() { 1381 1382 return customParameters; 1383 } 1384 1385 1386 /** 1387 * Applies the OAuth 2.0 Authorisation Server metadata defaults where 1388 * no values have been specified. 1389 * 1390 * <ul> 1391 * <li>The response modes default to {@code ["query", "fragment"]}. 1392 * <li>The grant types default to {@code ["authorization_code", 1393 * "implicit"]}. 1394 * <li>The token endpoint authentication methods default to 1395 * {@code ["client_secret_basic"]}. 1396 * </ul> 1397 */ 1398 public void applyDefaults() { 1399 1400 if (rms == null) { 1401 rms = new ArrayList<>(2); 1402 rms.add(ResponseMode.QUERY); 1403 rms.add(ResponseMode.FRAGMENT); 1404 } 1405 1406 if (gts == null) { 1407 gts = new ArrayList<>(2); 1408 gts.add(GrantType.AUTHORIZATION_CODE); 1409 gts.add(GrantType.IMPLICIT); 1410 } 1411 1412 if (tokenEndpointAuthMethods == null) { 1413 tokenEndpointAuthMethods = new ArrayList<>(); 1414 tokenEndpointAuthMethods.add(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); 1415 } 1416 } 1417 1418 1419 @Override 1420 public JSONObject toJSONObject() { 1421 JSONObject o = super.toJSONObject(); 1422 1423 // Mandatory fields 1424 o.put("issuer", issuer.getValue()); 1425 1426 1427 // Optional fields 1428 if (jwkSetURI != null) 1429 o.put("jwks_uri", jwkSetURI.toString()); 1430 1431 if (scope != null) 1432 o.put("scopes_supported", scope.toStringList()); 1433 1434 List<String> stringList; 1435 1436 if (rts != null) { 1437 1438 stringList = new ArrayList<>(rts.size()); 1439 1440 for (ResponseType rt: rts) 1441 stringList.add(rt.toString()); 1442 1443 o.put("response_types_supported", stringList); 1444 } 1445 1446 if (rms != null) { 1447 1448 stringList = new ArrayList<>(rms.size()); 1449 1450 for (ResponseMode rm: rms) 1451 stringList.add(rm.getValue()); 1452 1453 o.put("response_modes_supported", stringList); 1454 } 1455 1456 if (gts != null) { 1457 1458 stringList = new ArrayList<>(gts.size()); 1459 1460 for (GrantType gt: gts) 1461 stringList.add(gt.toString()); 1462 1463 o.put("grant_types_supported", stringList); 1464 } 1465 1466 if (codeChallengeMethods != null) { 1467 1468 stringList = new ArrayList<>(codeChallengeMethods.size()); 1469 1470 for (CodeChallengeMethod m: codeChallengeMethods) 1471 stringList.add(m.getValue()); 1472 1473 o.put("code_challenge_methods_supported", stringList); 1474 } 1475 1476 1477 if (tokenEndpointAuthMethods != null) { 1478 1479 stringList = new ArrayList<>(tokenEndpointAuthMethods.size()); 1480 1481 for (ClientAuthenticationMethod m: tokenEndpointAuthMethods) 1482 stringList.add(m.getValue()); 1483 1484 o.put("token_endpoint_auth_methods_supported", stringList); 1485 } 1486 1487 if (tokenEndpointJWSAlgs != null) { 1488 1489 stringList = new ArrayList<>(tokenEndpointJWSAlgs.size()); 1490 1491 for (JWSAlgorithm alg: tokenEndpointJWSAlgs) 1492 stringList.add(alg.getName()); 1493 1494 o.put("token_endpoint_auth_signing_alg_values_supported", stringList); 1495 } 1496 1497 if (introspectionEndpointAuthMethods != null) { 1498 1499 stringList = new ArrayList<>(introspectionEndpointAuthMethods.size()); 1500 1501 for (ClientAuthenticationMethod m: introspectionEndpointAuthMethods) 1502 stringList.add(m.getValue()); 1503 1504 o.put("introspection_endpoint_auth_methods_supported", stringList); 1505 } 1506 1507 if (introspectionEndpointJWSAlgs != null) { 1508 1509 stringList = new ArrayList<>(introspectionEndpointJWSAlgs.size()); 1510 1511 for (JWSAlgorithm alg: introspectionEndpointJWSAlgs) 1512 stringList.add(alg.getName()); 1513 1514 o.put("introspection_endpoint_auth_signing_alg_values_supported", stringList); 1515 } 1516 1517 if (revocationEndpointAuthMethods != null) { 1518 1519 stringList = new ArrayList<>(revocationEndpointAuthMethods.size()); 1520 1521 for (ClientAuthenticationMethod m: revocationEndpointAuthMethods) 1522 stringList.add(m.getValue()); 1523 1524 o.put("revocation_endpoint_auth_methods_supported", stringList); 1525 } 1526 1527 if (revocationEndpointJWSAlgs != null) { 1528 1529 stringList = new ArrayList<>(revocationEndpointJWSAlgs.size()); 1530 1531 for (JWSAlgorithm alg: revocationEndpointJWSAlgs) 1532 stringList.add(alg.getName()); 1533 1534 o.put("revocation_endpoint_auth_signing_alg_values_supported", stringList); 1535 } 1536 1537 if (requestObjectJWSAlgs != null) { 1538 1539 stringList = new ArrayList<>(requestObjectJWSAlgs.size()); 1540 1541 for (JWSAlgorithm alg: requestObjectJWSAlgs) 1542 stringList.add(alg.getName()); 1543 1544 o.put("request_object_signing_alg_values_supported", stringList); 1545 } 1546 1547 if (requestObjectJWEAlgs != null) { 1548 1549 stringList = new ArrayList<>(requestObjectJWEAlgs.size()); 1550 1551 for (JWEAlgorithm alg: requestObjectJWEAlgs) 1552 stringList.add(alg.getName()); 1553 1554 o.put("request_object_encryption_alg_values_supported", stringList); 1555 } 1556 1557 if (requestObjectJWEEncs != null) { 1558 1559 stringList = new ArrayList<>(requestObjectJWEEncs.size()); 1560 1561 for (EncryptionMethod m: requestObjectJWEEncs) 1562 stringList.add(m.getName()); 1563 1564 o.put("request_object_encryption_enc_values_supported", stringList); 1565 } 1566 1567 if (uiLocales != null) { 1568 1569 stringList = new ArrayList<>(uiLocales.size()); 1570 1571 for (LangTag l: uiLocales) 1572 stringList.add(l.toString()); 1573 1574 o.put("ui_locales_supported", stringList); 1575 } 1576 1577 if (serviceDocsURI != null) 1578 o.put("service_documentation", serviceDocsURI.toString()); 1579 1580 if (policyURI != null) 1581 o.put("op_policy_uri", policyURI.toString()); 1582 1583 if (tosURI != null) 1584 o.put("op_tos_uri", tosURI.toString()); 1585 1586 if (requestParamSupported) { 1587 o.put("request_parameter_supported", true); 1588 } 1589 1590 if (requestURIParamSupported) { 1591 o.put("request_uri_parameter_supported", true); 1592 } 1593 1594 if (requireRequestURIReg) { 1595 o.put("require_request_uri_registration", true); 1596 } 1597 1598 if (authzResponseIssParameterSupported) { 1599 o.put("authorization_response_iss_parameter_supported", true); 1600 } 1601 1602 if (mtlsEndpointAliases != null) 1603 o.put("mtls_endpoint_aliases", mtlsEndpointAliases.toJSONObject()); 1604 1605 if (tlsClientCertificateBoundAccessTokens) { 1606 o.put("tls_client_certificate_bound_access_tokens", true); 1607 } 1608 1609 // DPoP 1610 if (dPoPJWSAlgs != null) { 1611 1612 stringList = new ArrayList<>(dPoPJWSAlgs.size()); 1613 1614 for (JWSAlgorithm alg: dPoPJWSAlgs) 1615 stringList.add(alg.getName()); 1616 1617 o.put("dpop_signing_alg_values_supported", stringList); 1618 } 1619 1620 // JARM 1621 if (authzJWSAlgs != null) { 1622 1623 stringList = new ArrayList<>(authzJWSAlgs.size()); 1624 1625 for (JWSAlgorithm alg: authzJWSAlgs) 1626 stringList.add(alg.getName()); 1627 1628 o.put("authorization_signing_alg_values_supported", stringList); 1629 } 1630 1631 if (authzJWEAlgs != null) { 1632 1633 stringList = new ArrayList<>(authzJWEAlgs.size()); 1634 1635 for (JWEAlgorithm alg: authzJWEAlgs) 1636 stringList.add(alg.getName()); 1637 1638 o.put("authorization_encryption_alg_values_supported", stringList); 1639 } 1640 1641 if (authzJWEEncs != null) { 1642 1643 stringList = new ArrayList<>(authzJWEEncs.size()); 1644 1645 for (EncryptionMethod m: authzJWEEncs) 1646 stringList.add(m.getName()); 1647 1648 o.put("authorization_encryption_enc_values_supported", stringList); 1649 } 1650 1651 // PAR 1652 if (requirePAR) { 1653 o.put("require_pushed_authorization_requests", true); 1654 } 1655 1656 // RAR 1657 if (authzTypes != null) { 1658 o.put("authorization_details_types_supported", Identifier.toStringList(authzTypes)); 1659 } 1660 1661 // Incremental authz 1662 if (CollectionUtils.isNotEmpty(incrementalAuthzTypes)) { 1663 stringList = new ArrayList<>(incrementalAuthzTypes.size()); 1664 for (ClientType clientType: incrementalAuthzTypes) { 1665 if (clientType != null) { 1666 stringList.add(clientType.name().toLowerCase()); 1667 } 1668 } 1669 o.put("incremental_authz_types_supported", stringList); 1670 } 1671 1672 // CIBA 1673 if (backChannelTokenDeliveryModes != null) { 1674 1675 stringList = new ArrayList<>(backChannelTokenDeliveryModes.size()); 1676 1677 for (BackChannelTokenDeliveryMode mode: backChannelTokenDeliveryModes) { 1678 if (mode != null) { 1679 stringList.add(mode.getValue()); 1680 } 1681 } 1682 1683 o.put("backchannel_token_delivery_modes_supported", stringList); 1684 } 1685 1686 if (backChannelAuthRequestJWSAlgs != null) { 1687 1688 stringList = new ArrayList<>(backChannelAuthRequestJWSAlgs.size()); 1689 1690 for (JWSAlgorithm alg : backChannelAuthRequestJWSAlgs) { 1691 if (alg != null) { 1692 stringList.add(alg.getName()); 1693 } 1694 } 1695 1696 o.put("backchannel_authentication_request_signing_alg_values_supported", stringList); 1697 } 1698 1699 if (backChannelUserCodeSupported) { 1700 o.put("backchannel_user_code_parameter_supported", true); 1701 } 1702 1703 1704 // Prompt=create 1705 if (promptTypes != null) { 1706 stringList = new ArrayList<>(promptTypes.size()); 1707 for (Prompt.Type type: promptTypes) { 1708 stringList.add(type.toString()); 1709 } 1710 o.put("prompt_values_supported", stringList); 1711 } 1712 1713 // OIDC Federation 1.0 1714 1715 if (organizationName != null) { 1716 o.put("organization_name", organizationName); 1717 } 1718 1719 if (CollectionUtils.isNotEmpty(clientRegistrationTypes)) { 1720 1721 o.put("client_registration_types_supported", Identifier.toStringList(clientRegistrationTypes)); 1722 1723 if (jwkSet != null) { 1724 o.put("jwks", JSONObjectUtils.toJSONObject(jwkSet.toPublicJWKSet())); // prevent private keys from leaking 1725 } else if (signedJWKSetURI != null) { 1726 o.put("signed_jwks_uri", signedJWKSetURI.toString()); 1727 } 1728 1729 if (clientRegistrationTypes.contains(ClientRegistrationType.AUTOMATIC) && MapUtils.isNotEmpty(clientRegistrationAuthMethods)) { 1730 JSONObject map = new JSONObject(); 1731 for (Map.Entry<EndpointName,List<ClientAuthenticationMethod>> en: getClientRegistrationAuthnMethods().entrySet()) { 1732 List<String> methodNames = new LinkedList<>(); 1733 for (ClientAuthenticationMethod method: en.getValue()) { 1734 methodNames.add(method.getValue()); 1735 } 1736 map.put(en.getKey().getValue(), methodNames); 1737 } 1738 o.put("request_authentication_methods_supported", map); 1739 } 1740 1741 if (clientRegistrationTypes.contains(ClientRegistrationType.AUTOMATIC) && CollectionUtils.isNotEmpty(clientRegistrationAuthJWSAlgs)) { 1742 1743 stringList = new ArrayList<>(clientRegistrationAuthJWSAlgs.size()); 1744 1745 for (JWSAlgorithm alg: clientRegistrationAuthJWSAlgs) 1746 stringList.add(alg.getName()); 1747 1748 o.put("request_authentication_signing_alg_values_supported", stringList); 1749 } 1750 1751 if (clientRegistrationTypes.contains(ClientRegistrationType.EXPLICIT) && federationRegistrationEndpoint != null) { 1752 o.put("federation_registration_endpoint", federationRegistrationEndpoint.toString()); 1753 } else { 1754 o.remove("federation_registration_endpoint"); 1755 } 1756 } 1757 1758 // Append any custom (not registered) parameters 1759 o.putAll(customParameters); 1760 1761 return o; 1762 } 1763 1764 1765 /** 1766 * Parses an OAuth 2.0 Authorisation Server metadata from the specified 1767 * JSON object. 1768 * 1769 * @param jsonObject The JSON object to parse. Must not be 1770 * {@code null}. 1771 * 1772 * @return The OAuth 2.0 Authorisation Server metadata. 1773 * 1774 * @throws ParseException If the JSON object couldn't be parsed to an 1775 * OAuth 2.0 Authorisation Server metadata. 1776 */ 1777 public static AuthorizationServerMetadata parse(final JSONObject jsonObject) 1778 throws ParseException { 1779 1780 // Parse issuer and subject_types_supported first 1781 1782 Issuer issuer = new Issuer(JSONObjectUtils.getURI(jsonObject, "issuer").toString()); 1783 1784 AuthorizationServerEndpointMetadata asEndpoints = AuthorizationServerEndpointMetadata.parse(jsonObject); 1785 1786 AuthorizationServerMetadata as; 1787 1788 try { 1789 as = new AuthorizationServerMetadata(issuer); // validates issuer syntax 1790 } catch (IllegalArgumentException e) { 1791 throw new ParseException(e.getMessage(), e); 1792 } 1793 1794 // Endpoints 1795 as.setAuthorizationEndpointURI(asEndpoints.getAuthorizationEndpointURI()); 1796 as.setTokenEndpointURI(asEndpoints.getTokenEndpointURI()); 1797 as.setRegistrationEndpointURI(asEndpoints.getRegistrationEndpointURI()); 1798 as.setIntrospectionEndpointURI(asEndpoints.getIntrospectionEndpointURI()); 1799 as.setRevocationEndpointURI(asEndpoints.getRevocationEndpointURI()); 1800 as.setRequestObjectEndpoint(asEndpoints.getRequestObjectEndpoint()); 1801 as.setPushedAuthorizationRequestEndpointURI(asEndpoints.getPushedAuthorizationRequestEndpointURI()); 1802 as.setDeviceAuthorizationEndpointURI(asEndpoints.getDeviceAuthorizationEndpointURI()); 1803 as.setBackChannelAuthenticationEndpointURI(asEndpoints.getBackChannelAuthenticationEndpointURI()); 1804 as.jwkSetURI = JSONObjectUtils.getURI(jsonObject, "jwks_uri", null); 1805 1806 // AS capabilities 1807 if (jsonObject.get("scopes_supported") != null) { 1808 1809 as.scope = new Scope(); 1810 1811 for (String v: JSONObjectUtils.getStringArray(jsonObject, "scopes_supported")) { 1812 1813 if (v != null) 1814 as.scope.add(new Scope.Value(v)); 1815 } 1816 } 1817 1818 if (jsonObject.get("response_types_supported") != null) { 1819 1820 as.rts = new ArrayList<>(); 1821 1822 for (String v: JSONObjectUtils.getStringArray(jsonObject, "response_types_supported")) { 1823 1824 if (v != null) 1825 as.rts.add(ResponseType.parse(v)); 1826 } 1827 } 1828 1829 if (jsonObject.get("response_modes_supported") != null) { 1830 1831 as.rms = new ArrayList<>(); 1832 1833 for (String v: JSONObjectUtils.getStringArray(jsonObject, "response_modes_supported")) { 1834 1835 if (v != null) 1836 as.rms.add(new ResponseMode(v)); 1837 } 1838 } 1839 1840 if (jsonObject.get("grant_types_supported") != null) { 1841 1842 as.gts = new ArrayList<>(); 1843 1844 for (String v: JSONObjectUtils.getStringArray(jsonObject, "grant_types_supported")) { 1845 1846 if (v != null) 1847 as.gts.add(GrantType.parse(v)); 1848 } 1849 } 1850 1851 if (jsonObject.get("code_challenge_methods_supported") != null) { 1852 1853 as.codeChallengeMethods = new ArrayList<>(); 1854 1855 for (String v: JSONObjectUtils.getStringArray(jsonObject, "code_challenge_methods_supported")) { 1856 1857 if (v != null) 1858 as.codeChallengeMethods.add(CodeChallengeMethod.parse(v)); 1859 } 1860 } 1861 1862 if (jsonObject.get("token_endpoint_auth_methods_supported") != null) { 1863 1864 as.tokenEndpointAuthMethods = new ArrayList<>(); 1865 1866 for (String v: JSONObjectUtils.getStringArray(jsonObject, "token_endpoint_auth_methods_supported")) { 1867 1868 if (v != null) 1869 as.tokenEndpointAuthMethods.add(ClientAuthenticationMethod.parse(v)); 1870 } 1871 } 1872 1873 if (jsonObject.get("token_endpoint_auth_signing_alg_values_supported") != null) { 1874 1875 as.tokenEndpointJWSAlgs = new ArrayList<>(); 1876 1877 for (String v: JSONObjectUtils.getStringArray(jsonObject, "token_endpoint_auth_signing_alg_values_supported")) { 1878 1879 if (v != null && v.equals(Algorithm.NONE.getName())) 1880 throw new ParseException("The none algorithm is not accepted"); 1881 1882 if (v != null) 1883 as.tokenEndpointJWSAlgs.add(JWSAlgorithm.parse(v)); 1884 } 1885 } 1886 1887 if (jsonObject.get("introspection_endpoint_auth_methods_supported") != null) { 1888 1889 as.introspectionEndpointAuthMethods = new ArrayList<>(); 1890 1891 for (String v: JSONObjectUtils.getStringArray(jsonObject, "introspection_endpoint_auth_methods_supported")) { 1892 1893 if (v != null) 1894 as.introspectionEndpointAuthMethods.add(ClientAuthenticationMethod.parse(v)); 1895 } 1896 } 1897 1898 if (jsonObject.get("introspection_endpoint_auth_signing_alg_values_supported") != null) { 1899 1900 as.introspectionEndpointJWSAlgs = new ArrayList<>(); 1901 1902 for (String v: JSONObjectUtils.getStringArray(jsonObject, "introspection_endpoint_auth_signing_alg_values_supported")) { 1903 1904 if (v != null && v.equals(Algorithm.NONE.getName())) 1905 throw new ParseException("The none algorithm is not accepted"); 1906 1907 if (v != null) 1908 as.introspectionEndpointJWSAlgs.add(JWSAlgorithm.parse(v)); 1909 } 1910 } 1911 1912 if (jsonObject.get("revocation_endpoint_auth_methods_supported") != null) { 1913 1914 as.revocationEndpointAuthMethods = new ArrayList<>(); 1915 1916 for (String v: JSONObjectUtils.getStringArray(jsonObject, "revocation_endpoint_auth_methods_supported")) { 1917 1918 if (v != null) 1919 as.revocationEndpointAuthMethods.add(ClientAuthenticationMethod.parse(v)); 1920 } 1921 } 1922 1923 if (jsonObject.get("revocation_endpoint_auth_signing_alg_values_supported") != null) { 1924 1925 as.revocationEndpointJWSAlgs = new ArrayList<>(); 1926 1927 for (String v: JSONObjectUtils.getStringArray(jsonObject, "revocation_endpoint_auth_signing_alg_values_supported")) { 1928 1929 if (v != null && v.equals(Algorithm.NONE.getName())) 1930 throw new ParseException("The none algorithm is not accepted"); 1931 1932 if (v != null) 1933 as.revocationEndpointJWSAlgs.add(JWSAlgorithm.parse(v)); 1934 } 1935 } 1936 1937 1938 // Request object 1939 if (jsonObject.get("request_object_signing_alg_values_supported") != null) { 1940 1941 as.requestObjectJWSAlgs = new ArrayList<>(); 1942 1943 for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_signing_alg_values_supported")) { 1944 1945 if (v != null) 1946 as.requestObjectJWSAlgs.add(JWSAlgorithm.parse(v)); 1947 } 1948 } 1949 1950 1951 if (jsonObject.get("request_object_encryption_alg_values_supported") != null) { 1952 1953 as.requestObjectJWEAlgs = new ArrayList<>(); 1954 1955 for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_encryption_alg_values_supported")) { 1956 1957 if (v != null) 1958 as.requestObjectJWEAlgs.add(JWEAlgorithm.parse(v)); 1959 } 1960 } 1961 1962 1963 if (jsonObject.get("request_object_encryption_enc_values_supported") != null) { 1964 1965 as.requestObjectJWEEncs = new ArrayList<>(); 1966 1967 for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_encryption_enc_values_supported")) { 1968 1969 if (v != null) 1970 as.requestObjectJWEEncs.add(EncryptionMethod.parse(v)); 1971 } 1972 } 1973 1974 1975 // Misc 1976 1977 if (jsonObject.get("ui_locales_supported") != null) { 1978 1979 as.uiLocales = new ArrayList<>(); 1980 1981 for (String v : JSONObjectUtils.getStringArray(jsonObject, "ui_locales_supported")) { 1982 1983 if (v != null) { 1984 1985 try { 1986 as.uiLocales.add(LangTag.parse(v)); 1987 1988 } catch (LangTagException e) { 1989 1990 throw new ParseException("Invalid ui_locales_supported field: " + e.getMessage(), e); 1991 } 1992 } 1993 } 1994 } 1995 1996 if (jsonObject.get("service_documentation") != null) { 1997 try { 1998 as.setServiceDocsURI(JSONObjectUtils.getURI(jsonObject, "service_documentation")); 1999 } catch (IllegalArgumentException e) { 2000 throw new ParseException("Illegal service_documentation parameter: " + e.getMessage()); 2001 } 2002 } 2003 2004 if (jsonObject.get("op_policy_uri") != null) { 2005 try { 2006 as.setPolicyURI(JSONObjectUtils.getURI(jsonObject, "op_policy_uri")); 2007 } catch (IllegalArgumentException e) { 2008 throw new ParseException("Illegal op_policy_uri parameter: " + e.getMessage()); 2009 } 2010 } 2011 2012 if (jsonObject.get("op_tos_uri") != null) { 2013 try { 2014 as.setTermsOfServiceURI(JSONObjectUtils.getURI(jsonObject, "op_tos_uri")); 2015 } catch (IllegalArgumentException e) { 2016 throw new ParseException("Illegal op_tos_uri parameter: " + e.getMessage()); 2017 } 2018 } 2019 2020 if (jsonObject.get("request_parameter_supported") != null) 2021 as.requestParamSupported = JSONObjectUtils.getBoolean(jsonObject, "request_parameter_supported"); 2022 2023 if (jsonObject.get("request_uri_parameter_supported") != null) 2024 as.requestURIParamSupported = JSONObjectUtils.getBoolean(jsonObject, "request_uri_parameter_supported"); 2025 2026 if (jsonObject.get("require_request_uri_registration") != null) 2027 as.requireRequestURIReg = JSONObjectUtils.getBoolean(jsonObject, "require_request_uri_registration"); 2028 2029 if (jsonObject.get("authorization_response_iss_parameter_supported") != null) 2030 as.authzResponseIssParameterSupported = JSONObjectUtils.getBoolean(jsonObject, "authorization_response_iss_parameter_supported"); 2031 2032 if (jsonObject.get("mtls_endpoint_aliases") != null) 2033 as.mtlsEndpointAliases = AuthorizationServerEndpointMetadata.parse(JSONObjectUtils.getJSONObject(jsonObject, "mtls_endpoint_aliases")); 2034 2035 if (jsonObject.get("tls_client_certificate_bound_access_tokens") != null) 2036 as.tlsClientCertificateBoundAccessTokens = JSONObjectUtils.getBoolean(jsonObject, "tls_client_certificate_bound_access_tokens"); 2037 2038 // DPoP 2039 if (jsonObject.get("dpop_signing_alg_values_supported") != null) { 2040 2041 as.dPoPJWSAlgs = new ArrayList<>(); 2042 2043 for (String v: JSONObjectUtils.getStringArray(jsonObject, "dpop_signing_alg_values_supported")) { 2044 2045 if (v != null) 2046 as.dPoPJWSAlgs.add(JWSAlgorithm.parse(v)); 2047 } 2048 } 2049 2050 // JARM 2051 if (jsonObject.get("authorization_signing_alg_values_supported") != null) { 2052 2053 as.authzJWSAlgs = new ArrayList<>(); 2054 2055 for (String v: JSONObjectUtils.getStringArray(jsonObject, "authorization_signing_alg_values_supported")) { 2056 2057 if (v != null) 2058 as.authzJWSAlgs.add(JWSAlgorithm.parse(v)); 2059 } 2060 } 2061 2062 2063 if (jsonObject.get("authorization_encryption_alg_values_supported") != null) { 2064 2065 as.authzJWEAlgs = new ArrayList<>(); 2066 2067 for (String v: JSONObjectUtils.getStringArray(jsonObject, "authorization_encryption_alg_values_supported")) { 2068 2069 if (v != null) 2070 as.authzJWEAlgs.add(JWEAlgorithm.parse(v)); 2071 } 2072 } 2073 2074 2075 if (jsonObject.get("authorization_encryption_enc_values_supported") != null) { 2076 2077 as.authzJWEEncs = new ArrayList<>(); 2078 2079 for (String v: JSONObjectUtils.getStringArray(jsonObject, "authorization_encryption_enc_values_supported")) { 2080 2081 if (v != null) 2082 as.authzJWEEncs.add(EncryptionMethod.parse(v)); 2083 } 2084 } 2085 2086 // PAR 2087 if (jsonObject.get("require_pushed_authorization_requests") != null) { 2088 as.requiresPushedAuthorizationRequests(JSONObjectUtils.getBoolean(jsonObject, "require_pushed_authorization_requests")); 2089 } 2090 2091 // RAR 2092 if (jsonObject.get("authorization_details_types_supported") != null) { 2093 2094 as.authzTypes = new ArrayList<>(); 2095 2096 for (String v: JSONObjectUtils.getStringArray(jsonObject, "authorization_details_types_supported")) { 2097 2098 if (StringUtils.isNotBlank(v)) { 2099 as.authzTypes.add(new AuthorizationType(v)); 2100 } 2101 } 2102 } 2103 2104 // Incremental authz 2105 if (jsonObject.get("incremental_authz_types_supported") != null) { 2106 2107 as.incrementalAuthzTypes = new ArrayList<>(); 2108 2109 for (String v: JSONObjectUtils.getStringArray(jsonObject, "incremental_authz_types_supported")) { 2110 2111 if (v != null) { 2112 ClientType clientType; 2113 try { 2114 clientType = ClientType.valueOf(v.toUpperCase()); 2115 } catch (IllegalArgumentException e) { 2116 throw new ParseException("Illegal client type in incremental_authz_types_supported field: " + v); 2117 } 2118 as.incrementalAuthzTypes.add(clientType); 2119 } 2120 } 2121 } 2122 2123 // CIBA 2124 if (jsonObject.get("backchannel_token_delivery_modes_supported") != null) { 2125 2126 as.backChannelTokenDeliveryModes = new ArrayList<>(); 2127 2128 for (String v : JSONObjectUtils.getStringArray(jsonObject, "backchannel_token_delivery_modes_supported")) { 2129 2130 if (v != null) 2131 as.backChannelTokenDeliveryModes.add(BackChannelTokenDeliveryMode.parse(v)); 2132 } 2133 } 2134 2135 if (jsonObject.get("backchannel_authentication_request_signing_alg_values_supported") != null) { 2136 2137 as.backChannelAuthRequestJWSAlgs = new ArrayList<>(); 2138 2139 for (String v : JSONObjectUtils.getStringArray(jsonObject, "backchannel_authentication_request_signing_alg_values_supported")) { 2140 2141 if (v != null) 2142 as.backChannelAuthRequestJWSAlgs.add(JWSAlgorithm.parse(v)); 2143 } 2144 } 2145 2146 if (jsonObject.get("backchannel_user_code_parameter_supported") != null) { 2147 as.backChannelUserCodeSupported = JSONObjectUtils.getBoolean(jsonObject, "backchannel_user_code_parameter_supported"); 2148 } 2149 2150 // prompt=create 2151 if (jsonObject.get("prompt_values_supported") != null) { 2152 2153 as.promptTypes = new ArrayList<>(); 2154 for (String v: JSONObjectUtils.getStringList(jsonObject, "prompt_values_supported")) { 2155 2156 if (v != null) 2157 as.promptTypes.add(Prompt.Type.parse(v)); 2158 } 2159 } 2160 2161 // OIDC Federation 1.0 2162 if (jsonObject.get("client_registration_types_supported") != null) { 2163 2164 as.clientRegistrationTypes = new LinkedList<>(); 2165 for (String v : JSONObjectUtils.getStringList(jsonObject, "client_registration_types_supported")) { 2166 as.clientRegistrationTypes.add(new ClientRegistrationType(v)); 2167 } 2168 2169 if (jsonObject.get("jwks") != null) { 2170 try { 2171 as.jwkSet = JWKSet.parse(JSONObjectUtils.getJSONObject(jsonObject, "jwks")); 2172 } catch (java.text.ParseException e) { 2173 throw new ParseException(e.getMessage(), e); 2174 } 2175 } 2176 2177 as.signedJWKSetURI = JSONObjectUtils.getURI(jsonObject, "signed_jwks_uri", null); 2178 2179 if (jsonObject.get("request_authentication_methods_supported") != null) { 2180 Map<EndpointName, List<ClientAuthenticationMethod>> requestAuthMethods = new HashMap<>(); 2181 JSONObject spec = JSONObjectUtils.getJSONObject(jsonObject, "request_authentication_methods_supported"); 2182 // authorization_endpoint or RAR 2183 for (String endpointName : spec.keySet()) { 2184 List<String> methodNames = JSONObjectUtils.getStringList(spec, endpointName, Collections.<String>emptyList()); 2185 List<ClientAuthenticationMethod> authMethods = new LinkedList<>(); 2186 for (String name : methodNames) { 2187 authMethods.add(ClientAuthenticationMethod.parse(name)); 2188 } 2189 requestAuthMethods.put(new EndpointName(endpointName), authMethods); 2190 } 2191 as.setClientRegistrationAuthnMethods(requestAuthMethods); 2192 } 2193 2194 if (jsonObject.get("request_authentication_signing_alg_values_supported") != null) { 2195 as.clientRegistrationAuthJWSAlgs = new ArrayList<>(); 2196 2197 for (String v : JSONObjectUtils.getStringArray(jsonObject, "request_authentication_signing_alg_values_supported")) { 2198 2199 if (v != null) 2200 as.clientRegistrationAuthJWSAlgs.add(JWSAlgorithm.parse(v)); 2201 } 2202 } 2203 2204 as.federationRegistrationEndpoint = JSONObjectUtils.getURI(jsonObject, "federation_registration_endpoint", null); 2205 } 2206 2207 as.organizationName = JSONObjectUtils.getString(jsonObject, "organization_name", null); 2208 2209 // Parse custom (not registered) parameters 2210 JSONObject customParams = new JSONObject(jsonObject); 2211 customParams.keySet().removeAll(REGISTERED_PARAMETER_NAMES); 2212 for (Map.Entry<String,Object> customEntry: customParams.entrySet()) { 2213 as.setCustomParameter(customEntry.getKey(), customEntry.getValue()); 2214 } 2215 2216 return as; 2217 } 2218 2219 2220 /** 2221 * Parses an OAuth 2.0 Authorisation Server metadata from the specified 2222 * JSON object string. 2223 * 2224 * @param s The JSON object sting to parse. Must not be {@code null}. 2225 * 2226 * @return The OAuth 2.0 Authorisation Server metadata. 2227 * 2228 * @throws ParseException If the JSON object string couldn't be parsed 2229 * to an OAuth 2.0 Authorisation Server 2230 * metadata. 2231 */ 2232 public static AuthorizationServerMetadata parse(final String s) 2233 throws ParseException { 2234 2235 return parse(JSONObjectUtils.parse(s)); 2236 } 2237 2238 2239 /** 2240 * Resolves the OAuth 2.0 authorisation server metadata URL for the 2241 * specified issuer. 2242 * 2243 * @param issuer The issuer. Must represent a valid HTTPS or HTTP URL. 2244 * Must not be {@code null}. 2245 * 2246 * @return The OAuth 2.0 authorisation server metadata URL. 2247 * 2248 * @throws GeneralException If the issuer is invalid. 2249 */ 2250 public static URL resolveURL(final Issuer issuer) 2251 throws GeneralException { 2252 2253 try { 2254 URL issuerURL = new URL(issuer.getValue()); 2255 2256 // Validate but don't insist on HTTPS 2257 if (issuerURL.getQuery() != null && ! issuerURL.getQuery().trim().isEmpty()) { 2258 throw new GeneralException("The issuer must not contain a query component"); 2259 } 2260 2261 if (issuerURL.getPath() != null && issuerURL.getPath().endsWith("/")) { 2262 return new URL(issuerURL + ".well-known/oauth-authorization-server"); 2263 } else { 2264 return new URL(issuerURL + "/.well-known/oauth-authorization-server"); 2265 } 2266 2267 } catch (MalformedURLException e) { 2268 throw new GeneralException("The issuer is not a valid URL", e); 2269 } 2270 } 2271 2272 2273 /** 2274 * Resolves the OAuth 2.0 authorisation server metadata for the 2275 * specified issuer. The metadata is downloaded by HTTP GET from 2276 * {@code [issuer-url]/.well-known/oauth-authorization-server}. 2277 * 2278 * @param issuer The issuer. Must represent a valid HTTPS or HTTP URL. 2279 * Must not be {@code null}. 2280 * 2281 * @return The OAuth 2.0 authorisation server metadata. 2282 * 2283 * @throws GeneralException On invalid issuer or metadata. 2284 * @throws IOException On an HTTP exception. 2285 */ 2286 public static AuthorizationServerMetadata resolve(final Issuer issuer) 2287 throws GeneralException, IOException { 2288 2289 return resolve(issuer, null, 0, 0); 2290 } 2291 2292 2293 /** 2294 * Resolves the OAuth 2.0 authorisation server metadata for the 2295 * specified issuer. The metadata is downloaded by HTTP GET from 2296 * {@code [issuer-url]/.well-known/oauth-authorization-server}. 2297 * 2298 * @param issuer The issuer. Must represent a valid HTTPS or HTTP 2299 * URL. Must not be {@code null}. 2300 * @param altBaseURL Alternative base URL to use instead of the issuer 2301 * URL, when the issuer URL is not resolvable or 2302 * accessible. When {@code null} the issuer URL is 2303 * used as the base URL. 2304 * 2305 * @return The OAuth 2.0 authorisation server metadata. 2306 * 2307 * @throws GeneralException On invalid issuer or metadata. 2308 * @throws IOException On an HTTP exception. 2309 */ 2310 public static AuthorizationServerMetadata resolve(final Issuer issuer, final URL altBaseURL) 2311 throws GeneralException, IOException { 2312 2313 return resolve(issuer, altBaseURL, 0, 0); 2314 } 2315 2316 2317 /** 2318 * Resolves the OAuth 2.0 authorisation server metadata for the 2319 * specified issuer. The metadata is downloaded by HTTP GET from 2320 * {@code [issuer-url]/.well-known/oauth-authorization-server}. 2321 * 2322 * @param issuer The issuer. Must represent a valid HTTPS or 2323 * HTTP URL. Must not be {@code null}. 2324 * @param connectTimeout The HTTP connect timeout, in milliseconds. 2325 * Zero implies no timeout. Must not be negative. 2326 * @param readTimeout The HTTP response read timeout, in 2327 * milliseconds. Zero implies no timeout. Must 2328 * not be negative. 2329 * 2330 * @return The OAuth 2.0 authorisation server metadata. 2331 * 2332 * @throws GeneralException On invalid issuer or metadata. 2333 * @throws IOException On an HTTP exception. 2334 */ 2335 public static AuthorizationServerMetadata resolve(final Issuer issuer, 2336 final int connectTimeout, 2337 final int readTimeout) 2338 throws GeneralException, IOException { 2339 2340 HTTPRequestConfigurator requestConfigurator = new HTTPRequestConfigurator() { 2341 @Override 2342 public void configure(HTTPRequest httpRequest) { 2343 httpRequest.setConnectTimeout(connectTimeout); 2344 httpRequest.setReadTimeout(readTimeout); 2345 } 2346 }; 2347 2348 return resolve(issuer, requestConfigurator); 2349 } 2350 2351 2352 /** 2353 * Resolves the OAuth 2.0 authorisation server metadata for the 2354 * specified issuer. The metadata is downloaded by HTTP GET from 2355 * {@code [issuer-url]/.well-known/oauth-authorization-server}. 2356 * 2357 * @param issuer The issuer. Must represent a valid HTTPS or 2358 * HTTP URL. Must not be {@code null}. 2359 * @param altBaseURL Alternative base URL to use instead of the 2360 * issuer URL, when the issuer URL is not 2361 * resolvable or accessible. When {@code null} 2362 * the issuer URL is used as the base URL. 2363 * @param connectTimeout The HTTP connect timeout, in milliseconds. 2364 * Zero implies no timeout. Must not be negative. 2365 * @param readTimeout The HTTP response read timeout, in 2366 * milliseconds. Zero implies no timeout. Must 2367 * not be negative. 2368 * 2369 * @return The OAuth 2.0 authorisation server metadata. 2370 * 2371 * @throws GeneralException On invalid issuer or metadata. 2372 * @throws IOException On an HTTP exception. 2373 */ 2374 public static AuthorizationServerMetadata resolve(final Issuer issuer, 2375 final URL altBaseURL, 2376 final int connectTimeout, 2377 final int readTimeout) 2378 throws GeneralException, IOException { 2379 2380 HTTPRequestConfigurator requestConfigurator = new HTTPRequestConfigurator() { 2381 @Override 2382 public void configure(HTTPRequest httpRequest) { 2383 httpRequest.setConnectTimeout(connectTimeout); 2384 httpRequest.setReadTimeout(readTimeout); 2385 } 2386 }; 2387 2388 return resolve(issuer, altBaseURL, requestConfigurator); 2389 } 2390 2391 2392 /** 2393 * Resolves the OAuth 2.0 authorisation server metadata for the 2394 * specified issuer. The metadata is downloaded by HTTP GET from 2395 * {@code [issuer-url]/.well-known/oauth-authorization-server}, using 2396 * the specified HTTP request configurator. 2397 * 2398 * @param issuer The issuer. Must represent a valid HTTPS 2399 * or HTTP URL. Must not be {@code null}. 2400 * @param requestConfigurator An {@link HTTPRequestConfigurator} 2401 * instance to perform additional 2402 * {@link HTTPRequest} configuration. Must 2403 * not be {@code null}. 2404 * 2405 * @return The OAuth 2.0 authorisation server metadata. 2406 * 2407 * @throws GeneralException On invalid issuer or metadata. 2408 * @throws IOException On an HTTP exception. 2409 */ 2410 public static AuthorizationServerMetadata resolve(final Issuer issuer, 2411 final HTTPRequestConfigurator requestConfigurator) 2412 throws GeneralException, IOException { 2413 2414 return resolve(issuer, null, requestConfigurator); 2415 } 2416 2417 2418 /** 2419 * Resolves the OAuth 2.0 authorisation server metadata for the 2420 * specified issuer. The metadata is downloaded by HTTP GET from 2421 * {@code [issuer-url]/.well-known/oauth-authorization-server}, using 2422 * the specified HTTP request configurator. 2423 * 2424 * @param issuer The issuer. Must represent a valid HTTPS 2425 * or HTTP URL. Must not be {@code null}. 2426 * @param altBaseURL Alternative base URL to use instead of 2427 * the issuer URL, when the issuer URL is 2428 * not resolvable or accessible. When 2429 * {@code null} the issuer URL is used as 2430 * the base URL. 2431 * @param requestConfigurator An {@link HTTPRequestConfigurator} 2432 * instance to perform additional 2433 * {@link HTTPRequest} configuration. Must 2434 * not be {@code null}. 2435 * 2436 * @return The OAuth 2.0 authorisation server metadata. 2437 * 2438 * @throws GeneralException On invalid issuer or metadata. 2439 * @throws IOException On an HTTP exception. 2440 */ 2441 public static AuthorizationServerMetadata resolve(final Issuer issuer, 2442 final URL altBaseURL, 2443 final HTTPRequestConfigurator requestConfigurator) 2444 throws GeneralException, IOException { 2445 2446 return resolve( 2447 issuer, 2448 altBaseURL, 2449 new HTTPRequestModifier() { 2450 @Override 2451 public HTTPRequest modify(HTTPRequest httpRequest) { 2452 requestConfigurator.configure(httpRequest); 2453 return httpRequest; 2454 } 2455 }, 2456 false); 2457 } 2458 2459 2460 /** 2461 * Resolves the OAuth 2.0 authorisation server metadata for the 2462 * specified issuer. The metadata is downloaded by HTTP GET from 2463 * {@code [issuer-url]/.well-known/oauth-authorization-server}, using 2464 * the specified HTTP request modifier. 2465 * 2466 * @param issuer The issuer. Must represent a valid HTTPS 2467 * or HTTP URL. Must not be {@code null}. 2468 * @param altBaseURL Alternative base URL to use instead of 2469 * the issuer URL, when the issuer URL is 2470 * not resolvable or accessible. When 2471 * {@code null} the issuer URL is used as 2472 * the base URL. 2473 * @param requestModifier An {@link HTTPRequestModifier} to perform 2474 * additional {@link HTTPRequest} 2475 * configuration. Must not be {@code null}. 2476 * @param ignoreTrailingSlash If {@code true} compares the issuer URL 2477 * to the issuer in the authorisation server 2478 * metadata ignoring any trailing slashes. 2479 * 2480 * @return The OAuth 2.0 authorisation server metadata. 2481 * 2482 * @throws GeneralException On invalid issuer or metadata. 2483 * @throws IOException On an HTTP exception. 2484 */ 2485 public static AuthorizationServerMetadata resolve(final Issuer issuer, 2486 final URL altBaseURL, 2487 final HTTPRequestModifier requestModifier, 2488 final boolean ignoreTrailingSlash) 2489 throws GeneralException, IOException { 2490 2491 URL configURL = resolveURL(altBaseURL != null ? new Issuer(altBaseURL.toString()) : issuer); 2492 2493 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.GET, configURL); 2494 httpRequest = requestModifier.modify(httpRequest); 2495 2496 HTTPResponse httpResponse = httpRequest.send(); 2497 2498 if (httpResponse.getStatusCode() != 200) { 2499 throw new IOException("Couldn't download OAuth 2.0 Authorization Server metadata from " + configURL + 2500 ": Status code " + httpResponse.getStatusCode()); 2501 } 2502 2503 JSONObject jsonObject = httpResponse.getBodyAsJSONObject(); 2504 2505 AuthorizationServerMetadata as = AuthorizationServerMetadata.parse(jsonObject); 2506 2507 if (ignoreTrailingSlash ? ! issuer.equalsIgnoreTrailingSlash(as.getIssuer()) : ! issuer.equals(as.getIssuer())) { 2508 throw new GeneralException("The returned issuer doesn't match the expected: " + as.getIssuer()); 2509 } 2510 2511 return as; 2512 } 2513}