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