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