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