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