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