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.URL; 025import java.util.*; 026 027import net.minidev.json.JSONObject; 028 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.GeneralException; 035import com.nimbusds.oauth2.sdk.ParseException; 036import com.nimbusds.oauth2.sdk.as.AuthorizationServerEndpointMetadata; 037import com.nimbusds.oauth2.sdk.as.AuthorizationServerMetadata; 038import com.nimbusds.oauth2.sdk.http.HTTPRequest; 039import com.nimbusds.oauth2.sdk.http.HTTPResponse; 040import com.nimbusds.oauth2.sdk.id.Identifier; 041import com.nimbusds.oauth2.sdk.id.Issuer; 042import com.nimbusds.oauth2.sdk.util.CollectionUtils; 043import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 044import com.nimbusds.openid.connect.sdk.Display; 045import com.nimbusds.openid.connect.sdk.SubjectType; 046import com.nimbusds.openid.connect.sdk.assurance.evidences.IDDocumentType; 047import com.nimbusds.openid.connect.sdk.assurance.evidences.IdentityEvidenceType; 048import com.nimbusds.openid.connect.sdk.assurance.IdentityTrustFramework; 049import com.nimbusds.openid.connect.sdk.assurance.evidences.IdentityVerificationMethod; 050import com.nimbusds.openid.connect.sdk.claims.ACR; 051import com.nimbusds.openid.connect.sdk.claims.ClaimType; 052import com.nimbusds.openid.connect.sdk.federation.FederationType; 053 054 055/** 056 * OpenID Provider (OP) metadata. 057 * 058 * <p>Related specifications: 059 * 060 * <ul> 061 * <li>OpenID Connect Discovery 1.0, section 3. 062 * <li>OpenID Connect Session Management 1.0, section 2.1 (draft 28). 063 * <li>OpenID Connect Front-Channel Logout 1.0, section 3 (draft 02). 064 * <li>OpenID Connect Back-Channel Logout 1.0, section 2.1 (draft 04). 065 * <li>OpenID Connect for Identity Assurance 1.0 (draft 08). 066 * <li>OpenID Connect Federation 1.0 (draft 10). 067 * <li>OAuth 2.0 Authorization Server Metadata (RFC 8414) 068 * <li>OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound 069 * Access Tokens (RFC 8705) 070 * <li>Financial-grade API: JWT Secured Authorization Response Mode for 071 * OAuth 2.0 (JARM) 072 * </ul> 073 */ 074public class OIDCProviderMetadata extends AuthorizationServerMetadata { 075 076 077 /** 078 * The registered parameter names. 079 */ 080 private static final Set<String> REGISTERED_PARAMETER_NAMES; 081 082 083 static { 084 Set<String> p = new HashSet<>(AuthorizationServerMetadata.getRegisteredParameterNames()); 085 p.addAll(OIDCProviderEndpointMetadata.getRegisteredParameterNames()); 086 p.add("check_session_iframe"); 087 p.add("end_session_endpoint"); 088 p.add("acr_values_supported"); 089 p.add("subject_types_supported"); 090 p.add("id_token_signing_alg_values_supported"); 091 p.add("id_token_encryption_alg_values_supported"); 092 p.add("id_token_encryption_enc_values_supported"); 093 p.add("userinfo_signing_alg_values_supported"); 094 p.add("userinfo_encryption_alg_values_supported"); 095 p.add("userinfo_encryption_enc_values_supported"); 096 p.add("display_values_supported"); 097 p.add("claim_types_supported"); 098 p.add("claims_supported"); 099 p.add("claims_locales_supported"); 100 p.add("claims_parameter_supported"); 101 p.add("backchannel_logout_supported"); 102 p.add("backchannel_logout_session_supported"); 103 p.add("frontchannel_logout_supported"); 104 p.add("frontchannel_logout_session_supported"); 105 p.add("verified_claims_supported"); 106 p.add("trust_frameworks_supported"); 107 p.add("evidence_supported"); 108 p.add("id_documents_supported"); 109 p.add("id_documents_verification_methods_supported"); 110 p.add("claims_in_verified_claims_supported"); 111 p.add("federation_types_supported"); 112 p.add("organization_name"); 113 REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p); 114 } 115 116 117 /** 118 * The UserInfo endpoint. 119 */ 120 private URI userInfoEndpoint; 121 122 123 /** 124 * The cross-origin check session iframe. 125 */ 126 private URI checkSessionIframe; 127 128 129 /** 130 * The logout endpoint. 131 */ 132 private URI endSessionEndpoint; 133 134 135 /** 136 * The supported ACRs. 137 */ 138 private List<ACR> acrValues; 139 140 141 /** 142 * The supported subject types. 143 */ 144 private final List<SubjectType> subjectTypes; 145 146 147 /** 148 * The supported ID token JWS algorithms. 149 */ 150 private List<JWSAlgorithm> idTokenJWSAlgs; 151 152 153 /** 154 * The supported ID token JWE algorithms. 155 */ 156 private List<JWEAlgorithm> idTokenJWEAlgs; 157 158 159 /** 160 * The supported ID token encryption methods. 161 */ 162 private List<EncryptionMethod> idTokenJWEEncs; 163 164 165 /** 166 * The supported UserInfo JWS algorithms. 167 */ 168 private List<JWSAlgorithm> userInfoJWSAlgs; 169 170 171 /** 172 * The supported UserInfo JWE algorithms. 173 */ 174 private List<JWEAlgorithm> userInfoJWEAlgs; 175 176 177 /** 178 * The supported UserInfo encryption methods. 179 */ 180 private List<EncryptionMethod> userInfoJWEEncs; 181 182 183 /** 184 * The supported displays. 185 */ 186 private List<Display> displays; 187 188 189 /** 190 * The supported claim types. 191 */ 192 private List<ClaimType> claimTypes; 193 194 195 /** 196 * The supported claims names. 197 */ 198 private List<String> claims; 199 200 201 /** 202 * The supported claims locales. 203 */ 204 private List<LangTag> claimsLocales; 205 206 207 /** 208 * If {@code true} the {@code claims} parameter is supported, else not. 209 */ 210 private boolean claimsParamSupported = false; 211 212 213 /** 214 * If {@code true} the {@code frontchannel_logout_supported} parameter 215 * is set, else not. 216 */ 217 private boolean frontChannelLogoutSupported = false; 218 219 220 /** 221 * If {@code true} the {@code frontchannel_logout_session_supported} 222 * parameter is set, else not. 223 */ 224 private boolean frontChannelLogoutSessionSupported = false; 225 226 227 /** 228 * If {@code true} the {@code backchannel_logout_supported} parameter 229 * is set, else not. 230 */ 231 private boolean backChannelLogoutSupported = false; 232 233 234 /** 235 * If {@code true} the {@code backchannel_logout_session_supported} 236 * parameter is set, else not. 237 */ 238 private boolean backChannelLogoutSessionSupported = false; 239 240 241 /** 242 * If {@code true} verified claims are supported. 243 */ 244 private boolean verifiedClaimsSupported = false; 245 246 247 /** 248 * The supported trust frameworks. 249 */ 250 private List<IdentityTrustFramework> trustFrameworks; 251 252 253 /** 254 * The supported identity evidence types. 255 */ 256 private List<IdentityEvidenceType> evidenceTypes; 257 258 259 /** 260 * The supported identity documents. 261 */ 262 private List<IDDocumentType> idDocuments; 263 264 265 /** 266 * The supported identity verification methods. 267 */ 268 private List<IdentityVerificationMethod> idVerificationMethods; 269 270 271 /** 272 * The supported verified claims. 273 */ 274 private List<String> verifiedClaims; 275 276 277 /** 278 * The supported federation types. 279 */ 280 private List<FederationType> federationTypes; 281 282 283 /** 284 * The organisation name (in federation). 285 */ 286 private String organizationName; 287 288 289 /** 290 * The federation registration endpoint. 291 */ 292 private URI federationRegistrationEndpoint; 293 294 295 /** 296 * Creates a new OpenID Connect provider metadata instance. 297 * 298 * @param issuer The issuer identifier. Must be an URI using the 299 * https scheme with no query or fragment 300 * component. Must not be {@code null}. 301 * @param subjectTypes The supported subject types. At least one must 302 * be specified. Must not be {@code null}. 303 * @param jwkSetURI The JWK set URI. Must not be {@code null}. 304 */ 305 public OIDCProviderMetadata(final Issuer issuer, 306 final List<SubjectType> subjectTypes, 307 final URI jwkSetURI) { 308 309 super(issuer); 310 311 if (subjectTypes.size() < 1) 312 throw new IllegalArgumentException("At least one supported subject type must be specified"); 313 314 this.subjectTypes = subjectTypes; 315 316 if (jwkSetURI == null) 317 throw new IllegalArgumentException("The public JWK set URI must not be null"); 318 319 setJWKSetURI(jwkSetURI); 320 321 // Default OpenID Connect setting is supported 322 setSupportsRequestURIParam(true); 323 } 324 325 326 @Override 327 public void setMtlsEndpointAliases(AuthorizationServerEndpointMetadata mtlsEndpointAliases) { 328 329 if (mtlsEndpointAliases != null && !(mtlsEndpointAliases instanceof OIDCProviderEndpointMetadata)) { 330 // convert the provided endpoints to OIDC 331 super.setMtlsEndpointAliases(new OIDCProviderEndpointMetadata(mtlsEndpointAliases)); 332 } else { 333 super.setMtlsEndpointAliases(mtlsEndpointAliases); 334 } 335 } 336 337 @Override 338 public OIDCProviderEndpointMetadata getMtlsEndpointAliases() { 339 340 return (OIDCProviderEndpointMetadata) super.getMtlsEndpointAliases(); 341 } 342 343 344 /** 345 * Gets the registered OpenID Connect provider metadata parameter 346 * names. 347 * 348 * @return The registered OpenID Connect provider metadata parameter 349 * names, as an unmodifiable set. 350 */ 351 public static Set<String> getRegisteredParameterNames() { 352 353 return REGISTERED_PARAMETER_NAMES; 354 } 355 356 357 /** 358 * Gets the UserInfo endpoint URI. Corresponds the 359 * {@code userinfo_endpoint} metadata field. 360 * 361 * @return The UserInfo endpoint URI, {@code null} if not specified. 362 */ 363 public URI getUserInfoEndpointURI() { 364 365 return userInfoEndpoint; 366 } 367 368 369 /** 370 * Sets the UserInfo endpoint URI. Corresponds the 371 * {@code userinfo_endpoint} metadata field. 372 * 373 * @param userInfoEndpoint The UserInfo endpoint URI, {@code null} if 374 * not specified. 375 */ 376 public void setUserInfoEndpointURI(final URI userInfoEndpoint) { 377 378 this.userInfoEndpoint = userInfoEndpoint; 379 } 380 381 382 /** 383 * Gets the cross-origin check session iframe URI. Corresponds to the 384 * {@code check_session_iframe} metadata field. 385 * 386 * @return The check session iframe URI, {@code null} if not specified. 387 */ 388 public URI getCheckSessionIframeURI() { 389 390 return checkSessionIframe; 391 } 392 393 394 /** 395 * Sets the cross-origin check session iframe URI. Corresponds to the 396 * {@code check_session_iframe} metadata field. 397 * 398 * @param checkSessionIframe The check session iframe URI, {@code null} 399 * if not specified. 400 */ 401 public void setCheckSessionIframeURI(final URI checkSessionIframe) { 402 403 this.checkSessionIframe = checkSessionIframe; 404 } 405 406 407 /** 408 * Gets the logout endpoint URI. Corresponds to the 409 * {@code end_session_endpoint} metadata field. 410 * 411 * @return The logoout endpoint URI, {@code null} if not specified. 412 */ 413 public URI getEndSessionEndpointURI() { 414 415 return endSessionEndpoint; 416 } 417 418 419 /** 420 * Sets the logout endpoint URI. Corresponds to the 421 * {@code end_session_endpoint} metadata field. 422 * 423 * @param endSessionEndpoint The logoout endpoint URI, {@code null} if 424 * not specified. 425 */ 426 public void setEndSessionEndpointURI(final URI endSessionEndpoint) { 427 428 this.endSessionEndpoint = endSessionEndpoint; 429 } 430 431 /** 432 * Gets the supported Authentication Context Class References (ACRs). 433 * Corresponds to the {@code acr_values_supported} metadata field. 434 * 435 * @return The supported ACRs, {@code null} if not specified. 436 */ 437 public List<ACR> getACRs() { 438 439 return acrValues; 440 } 441 442 443 /** 444 * Sets the supported Authentication Context Class References (ACRs). 445 * Corresponds to the {@code acr_values_supported} metadata field. 446 * 447 * @param acrValues The supported ACRs, {@code null} if not specified. 448 */ 449 public void setACRs(final List<ACR> acrValues) { 450 451 this.acrValues = acrValues; 452 } 453 454 455 /** 456 * Gets the supported subject types. Corresponds to the 457 * {@code subject_types_supported} metadata field. 458 * 459 * @return The supported subject types. 460 */ 461 public List<SubjectType> getSubjectTypes() { 462 463 return subjectTypes; 464 } 465 466 467 /** 468 * Gets the supported JWS algorithms for ID tokens. Corresponds to the 469 * {@code id_token_signing_alg_values_supported} metadata field. 470 * 471 * @return The supported JWS algorithms, {@code null} if not specified. 472 */ 473 public List<JWSAlgorithm> getIDTokenJWSAlgs() { 474 475 return idTokenJWSAlgs; 476 } 477 478 479 /** 480 * Sets the supported JWS algorithms for ID tokens. Corresponds to the 481 * {@code id_token_signing_alg_values_supported} metadata field. 482 * 483 * @param idTokenJWSAlgs The supported JWS algorithms, {@code null} if 484 * not specified. 485 */ 486 public void setIDTokenJWSAlgs(final List<JWSAlgorithm> idTokenJWSAlgs) { 487 488 this.idTokenJWSAlgs = idTokenJWSAlgs; 489 } 490 491 492 /** 493 * Gets the supported JWE algorithms for ID tokens. Corresponds to the 494 * {@code id_token_encryption_alg_values_supported} metadata field. 495 * 496 * @return The supported JWE algorithms, {@code null} if not specified. 497 */ 498 public List<JWEAlgorithm> getIDTokenJWEAlgs() { 499 500 return idTokenJWEAlgs; 501 } 502 503 504 /** 505 * Sets the supported JWE algorithms for ID tokens. Corresponds to the 506 * {@code id_token_encryption_alg_values_supported} metadata field. 507 * 508 * @param idTokenJWEAlgs The supported JWE algorithms, {@code null} if 509 * not specified. 510 */ 511 public void setIDTokenJWEAlgs(final List<JWEAlgorithm> idTokenJWEAlgs) { 512 513 this.idTokenJWEAlgs = idTokenJWEAlgs; 514 } 515 516 517 /** 518 * Gets the supported encryption methods for ID tokens. Corresponds to 519 * the {@code id_token_encryption_enc_values_supported} metadata field. 520 * 521 * @return The supported encryption methods, {@code null} if not 522 * specified. 523 */ 524 public List<EncryptionMethod> getIDTokenJWEEncs() { 525 526 return idTokenJWEEncs; 527 } 528 529 530 /** 531 * Sets the supported encryption methods for ID tokens. Corresponds to 532 * the {@code id_token_encryption_enc_values_supported} metadata field. 533 * 534 * @param idTokenJWEEncs The supported encryption methods, {@code null} 535 * if not specified. 536 */ 537 public void setIDTokenJWEEncs(final List<EncryptionMethod> idTokenJWEEncs) { 538 539 this.idTokenJWEEncs = idTokenJWEEncs; 540 } 541 542 543 /** 544 * Gets the supported JWS algorithms for UserInfo JWTs. Corresponds to 545 * the {@code userinfo_signing_alg_values_supported} metadata field. 546 * 547 * @return The supported JWS algorithms, {@code null} if not specified. 548 */ 549 public List<JWSAlgorithm> getUserInfoJWSAlgs() { 550 551 return userInfoJWSAlgs; 552 } 553 554 555 /** 556 * Sets the supported JWS algorithms for UserInfo JWTs. Corresponds to 557 * the {@code userinfo_signing_alg_values_supported} metadata field. 558 * 559 * @param userInfoJWSAlgs The supported JWS algorithms, {@code null} if 560 * not specified. 561 */ 562 public void setUserInfoJWSAlgs(final List<JWSAlgorithm> userInfoJWSAlgs) { 563 564 this.userInfoJWSAlgs = userInfoJWSAlgs; 565 } 566 567 568 /** 569 * Gets the supported JWE algorithms for UserInfo JWTs. Corresponds to 570 * the {@code userinfo_encryption_alg_values_supported} metadata field. 571 * 572 * @return The supported JWE algorithms, {@code null} if not specified. 573 */ 574 public List<JWEAlgorithm> getUserInfoJWEAlgs() { 575 576 return userInfoJWEAlgs; 577 } 578 579 580 /** 581 * Sets the supported JWE algorithms for UserInfo JWTs. Corresponds to 582 * the {@code userinfo_encryption_alg_values_supported} metadata field. 583 * 584 * @param userInfoJWEAlgs The supported JWE algorithms, {@code null} if 585 * not specified. 586 */ 587 public void setUserInfoJWEAlgs(final List<JWEAlgorithm> userInfoJWEAlgs) { 588 589 this.userInfoJWEAlgs = userInfoJWEAlgs; 590 } 591 592 593 /** 594 * Gets the supported encryption methods for UserInfo JWTs. Corresponds 595 * to the {@code userinfo_encryption_enc_values_supported} metadata 596 * field. 597 * 598 * @return The supported encryption methods, {@code null} if not 599 * specified. 600 */ 601 public List<EncryptionMethod> getUserInfoJWEEncs() { 602 603 return userInfoJWEEncs; 604 } 605 606 607 /** 608 * Sets the supported encryption methods for UserInfo JWTs. Corresponds 609 * to the {@code userinfo_encryption_enc_values_supported} metadata 610 * field. 611 * 612 * @param userInfoJWEEncs The supported encryption methods, 613 * {@code null} if not specified. 614 */ 615 public void setUserInfoJWEEncs(final List<EncryptionMethod> userInfoJWEEncs) { 616 617 this.userInfoJWEEncs = userInfoJWEEncs; 618 } 619 620 621 /** 622 * Gets the supported displays. Corresponds to the 623 * {@code display_values_supported} metadata field. 624 * 625 * @return The supported displays, {@code null} if not specified. 626 */ 627 public List<Display> getDisplays() { 628 629 return displays; 630 } 631 632 633 /** 634 * Sets the supported displays. Corresponds to the 635 * {@code display_values_supported} metadata field. 636 * 637 * @param displays The supported displays, {@code null} if not 638 * specified. 639 */ 640 public void setDisplays(final List<Display> displays) { 641 642 this.displays = displays; 643 } 644 645 646 /** 647 * Gets the supported claim types. Corresponds to the 648 * {@code claim_types_supported} metadata field. 649 * 650 * @return The supported claim types, {@code null} if not specified. 651 */ 652 public List<ClaimType> getClaimTypes() { 653 654 return claimTypes; 655 } 656 657 658 /** 659 * Sets the supported claim types. Corresponds to the 660 * {@code claim_types_supported} metadata field. 661 * 662 * @param claimTypes The supported claim types, {@code null} if not 663 * specified. 664 */ 665 public void setClaimTypes(final List<ClaimType> claimTypes) { 666 667 this.claimTypes = claimTypes; 668 } 669 670 671 /** 672 * Gets the supported claims names. Corresponds to the 673 * {@code claims_supported} metadata field. 674 * 675 * @return The supported claims names, {@code null} if not specified. 676 */ 677 public List<String> getClaims() { 678 679 return claims; 680 } 681 682 683 /** 684 * Sets the supported claims names. Corresponds to the 685 * {@code claims_supported} metadata field. 686 * 687 * @param claims The supported claims names, {@code null} if not 688 * specified. 689 */ 690 public void setClaims(final List<String> claims) { 691 692 this.claims = claims; 693 } 694 695 696 /** 697 * Gets the supported claims locales. Corresponds to the 698 * {@code claims_locales_supported} metadata field. 699 * 700 * @return The supported claims locales, {@code null} if not specified. 701 */ 702 public List<LangTag> getClaimsLocales() { 703 704 return claimsLocales; 705 } 706 707 708 /** 709 * Sets the supported claims locales. Corresponds to the 710 * {@code claims_locales_supported} metadata field. 711 * 712 * @param claimsLocales The supported claims locales, {@code null} if 713 * not specified. 714 */ 715 public void setClaimLocales(final List<LangTag> claimsLocales) { 716 717 this.claimsLocales = claimsLocales; 718 } 719 720 721 /** 722 * Gets the support for the {@code claims} authorisation request 723 * parameter. Corresponds to the {@code claims_parameter_supported} 724 * metadata field. 725 * 726 * @return {@code true} if the {@code claim} parameter is supported, 727 * else {@code false}. 728 */ 729 public boolean supportsClaimsParam() { 730 731 return claimsParamSupported; 732 } 733 734 735 /** 736 * Sets the support for the {@code claims} authorisation request 737 * parameter. Corresponds to the {@code claims_parameter_supported} 738 * metadata field. 739 * 740 * @param claimsParamSupported {@code true} if the {@code claim} 741 * parameter is supported, else 742 * {@code false}. 743 */ 744 public void setSupportsClaimsParams(final boolean claimsParamSupported) { 745 746 this.claimsParamSupported = claimsParamSupported; 747 } 748 749 750 /** 751 * Gets the support for front-channel logout. Corresponds to the 752 * {@code frontchannel_logout_supported} metadata field. 753 * 754 * @return {@code true} if front-channel logout is supported, else 755 * {@code false}. 756 */ 757 public boolean supportsFrontChannelLogout() { 758 759 return frontChannelLogoutSupported; 760 } 761 762 763 /** 764 * Sets the support for front-channel logout. Corresponds to the 765 * {@code frontchannel_logout_supported} metadata field. 766 * 767 * @param frontChannelLogoutSupported {@code true} if front-channel 768 * logout is supported, else 769 * {@code false}. 770 */ 771 public void setSupportsFrontChannelLogout(final boolean frontChannelLogoutSupported) { 772 773 this.frontChannelLogoutSupported = frontChannelLogoutSupported; 774 } 775 776 777 /** 778 * Gets the support for front-channel logout with a session ID. 779 * Corresponds to the {@code frontchannel_logout_session_supported} 780 * metadata field. 781 * 782 * @return {@code true} if front-channel logout with a session ID is 783 * supported, else {@code false}. 784 */ 785 public boolean supportsFrontChannelLogoutSession() { 786 787 return frontChannelLogoutSessionSupported; 788 } 789 790 791 /** 792 * Sets the support for front-channel logout with a session ID. 793 * Corresponds to the {@code frontchannel_logout_session_supported} 794 * metadata field. 795 * 796 * @param frontChannelLogoutSessionSupported {@code true} if 797 * front-channel logout with 798 * a session ID is supported, 799 * else {@code false}. 800 */ 801 public void setSupportsFrontChannelLogoutSession(final boolean frontChannelLogoutSessionSupported) { 802 803 this.frontChannelLogoutSessionSupported = frontChannelLogoutSessionSupported; 804 } 805 806 807 /** 808 * Gets the support for back-channel logout. Corresponds to the 809 * {@code backchannel_logout_supported} metadata field. 810 * 811 * @return {@code true} if back-channel logout is supported, else 812 * {@code false}. 813 */ 814 public boolean supportsBackChannelLogout() { 815 816 return backChannelLogoutSupported; 817 } 818 819 820 /** 821 * Sets the support for back-channel logout. Corresponds to the 822 * {@code backchannel_logout_supported} metadata field. 823 * 824 * @param backChannelLogoutSupported {@code true} if back-channel 825 * logout is supported, else 826 * {@code false}. 827 */ 828 public void setSupportsBackChannelLogout(final boolean backChannelLogoutSupported) { 829 830 this.backChannelLogoutSupported = backChannelLogoutSupported; 831 } 832 833 834 /** 835 * Gets the support for back-channel logout with a session ID. 836 * Corresponds to the {@code backchannel_logout_session_supported} 837 * metadata field. 838 * 839 * @return {@code true} if back-channel logout with a session ID is 840 * supported, else {@code false}. 841 */ 842 public boolean supportsBackChannelLogoutSession() { 843 844 return backChannelLogoutSessionSupported; 845 } 846 847 848 /** 849 * Sets the support for back-channel logout with a session ID. 850 * Corresponds to the {@code backchannel_logout_session_supported} 851 * metadata field. 852 * 853 * @param backChannelLogoutSessionSupported {@code true} if 854 * back-channel logout with a 855 * session ID is supported, 856 * else {@code false}. 857 */ 858 public void setSupportsBackChannelLogoutSession(final boolean backChannelLogoutSessionSupported) { 859 860 this.backChannelLogoutSessionSupported = backChannelLogoutSessionSupported; 861 } 862 863 864 /** 865 * Gets support for verified claims. Corresponds to the 866 * {@code verified_claims_supported} metadata field. 867 * 868 * @return {@code true} if verified claims are supported, else 869 * {@code false}. 870 */ 871 public boolean supportsVerifiedClaims() { 872 873 return verifiedClaimsSupported; 874 } 875 876 877 /** 878 * Sets support for verified claims. Corresponds to the 879 * {@code verified_claims_supported} metadata field. 880 * 881 * @param verifiedClaimsSupported {@code true} if verified claims are 882 * supported, else {@code false}. 883 */ 884 public void setSupportsVerifiedClaims(final boolean verifiedClaimsSupported) { 885 886 this.verifiedClaimsSupported = verifiedClaimsSupported; 887 } 888 889 890 /** 891 * Gets the supported identity trust frameworks. Corresponds to the 892 * {@code trust_frameworks_supported} metadata field. 893 * 894 * @return The supported identity trust frameworks, {@code null} if not 895 * specified. 896 */ 897 public List<IdentityTrustFramework> getIdentityTrustFrameworks() { 898 return trustFrameworks; 899 } 900 901 902 /** 903 * Sets the supported identity trust frameworks. Corresponds to the 904 * {@code trust_frameworks_supported} metadata field. 905 * 906 * @param trustFrameworks The supported identity trust frameworks, 907 * {@code null} if not specified. 908 */ 909 public void setIdentityTrustFrameworks(final List<IdentityTrustFramework> trustFrameworks) { 910 this.trustFrameworks = trustFrameworks; 911 } 912 913 914 /** 915 * Gets the supported identity evidence types. Corresponds to the 916 * {@code evidence_supported} metadata field. 917 * 918 * @return The supported identity evidence types, {@code null} if not 919 * specified. 920 */ 921 public List<IdentityEvidenceType> getIdentityEvidenceTypes() { 922 return evidenceTypes; 923 } 924 925 926 /** 927 * Sets the supported identity evidence types. Corresponds to the 928 * {@code evidence_supported} metadata field. 929 * 930 * @param evidenceTypes The supported identity evidence types, 931 * {@code null} if not specified. 932 */ 933 public void setIdentityEvidenceTypes(final List<IdentityEvidenceType> evidenceTypes) { 934 this.evidenceTypes = evidenceTypes; 935 } 936 937 938 /** 939 * Gets the supported identity document types. Corresponds to the 940 * {@code id_documents_supported} metadata field. 941 * 942 * @return The supported identity documents types, {@code null} 943 * if not specified. 944 */ 945 public List<IDDocumentType> getIdentityDocumentTypes() { 946 return idDocuments; 947 } 948 949 950 /** 951 * Sets the supported identity document types. Corresponds to the 952 * {@code id_documents_supported} metadata field. 953 * 954 * @param idDocuments The supported identity document types, 955 * {@code null} if not specified. 956 */ 957 public void setIdentityDocumentTypes(List<IDDocumentType> idDocuments) { 958 this.idDocuments = idDocuments; 959 } 960 961 962 /** 963 * Gets the supported identity verification methods. Corresponds to the 964 * {@code id_documents_verification_methods_supported} metadata field. 965 * 966 * @return The supported identity verification methods, {@code null} 967 * if not specified. 968 */ 969 public List<IdentityVerificationMethod> getIdentityVerificationMethods() { 970 return idVerificationMethods; 971 } 972 973 974 /** 975 * Sets the supported identity verification methods. Corresponds to the 976 * {@code id_documents_verification_methods_supported} metadata field. 977 * 978 * @param idVerificationMethods The supported identity verification 979 * methods, {@code null} if not specified. 980 */ 981 public void setIdentityVerificationMethods(final List<IdentityVerificationMethod> idVerificationMethods) { 982 this.idVerificationMethods = idVerificationMethods; 983 } 984 985 986 /** 987 * Gets the supported verified claims names. Corresponds to the 988 * {@code claims_in_verified_claims_supported} metadata field. 989 * 990 * @return The supported verified claims names, {@code null} if not 991 * specified. 992 */ 993 public List<String> getVerifiedClaims() { 994 return verifiedClaims; 995 } 996 997 998 /** 999 * Sets the supported verified claims names. Corresponds to the 1000 * {@code claims_in_verified_claims_supported} metadata field. 1001 * 1002 * @param verifiedClaims The supported verified claims names, 1003 * {@code null} if not specified. 1004 */ 1005 public void setVerifiedClaims(final List<String> verifiedClaims) { 1006 this.verifiedClaims = verifiedClaims; 1007 } 1008 1009 1010 /** 1011 * Gets the supported federation types. Corresponds to the 1012 * {@code federation_types_supported} metadata field. 1013 * 1014 * @return The supported federation types, {@code null} if not 1015 * specified. 1016 */ 1017 public List<FederationType> getFederationTypes() { 1018 return federationTypes; 1019 } 1020 1021 1022 /** 1023 * Sets the supported federation types. Corresponds to the 1024 * {@code federation_types_supported} metadata field. 1025 * 1026 * @param federationTypes The supported federation types, {@code null} 1027 * if not specified. 1028 */ 1029 public void setFederationTypes(final List<FederationType> federationTypes) { 1030 this.federationTypes = federationTypes; 1031 } 1032 1033 1034 /** 1035 * Gets the organisation name (in federation). Corresponds to the 1036 * {@code organization_name} metadata field. 1037 * 1038 * @return The organisation name, {@code null} if not specified. 1039 */ 1040 public String getOrganizationName() { 1041 return organizationName; 1042 } 1043 1044 1045 /** 1046 * Sets the organisation name (in federation). Corresponds to the 1047 * {@code organization_name} metadata field. 1048 * 1049 * @param organizationName The organisation name, {@code null} if not 1050 * specified. 1051 */ 1052 public void setOrganizationName(final String organizationName) { 1053 this.organizationName = organizationName; 1054 } 1055 1056 1057 /** 1058 * Gets the federation registration endpoint URI. Corresponds to the 1059 * {@code federation_registration_endpoint} metadata field. 1060 * 1061 * @return The federation registration endpoint URI, {@code null} if 1062 * not specified. 1063 */ 1064 public URI getFederationRegistrationEndpointURI() { 1065 1066 return federationRegistrationEndpoint; 1067 } 1068 1069 1070 /** 1071 * Sets the federation registration endpoint URI. Corresponds to the 1072 * {@code federation_registration_endpoint} metadata field. 1073 * 1074 * @param federationRegistrationEndpoint The federation registration 1075 * endpoint URI, {@code null} if 1076 * not specified. 1077 */ 1078 public void setFederationRegistrationEndpointURI(final URI federationRegistrationEndpoint) { 1079 1080 this.federationRegistrationEndpoint = federationRegistrationEndpoint; 1081 } 1082 1083 1084 /** 1085 * Applies the OpenID Provider metadata defaults where no values have 1086 * been specified. 1087 * 1088 * <ul> 1089 * <li>The response modes default to {@code ["query", "fragment"]}. 1090 * <li>The grant types default to {@code ["authorization_code", 1091 * "implicit"]}. 1092 * <li>The token endpoint authentication methods default to 1093 * {@code ["client_secret_basic"]}. 1094 * <li>The claim types default to {@code ["normal]}. 1095 * </ul> 1096 */ 1097 public void applyDefaults() { 1098 1099 super.applyDefaults(); 1100 1101 if (claimTypes == null) { 1102 claimTypes = new ArrayList<>(1); 1103 claimTypes.add(ClaimType.NORMAL); 1104 } 1105 } 1106 1107 1108 /** 1109 * Returns the JSON object representation of this OpenID Connect 1110 * provider metadata. 1111 * 1112 * @return The JSON object representation. 1113 */ 1114 public JSONObject toJSONObject() { 1115 1116 JSONObject o = super.toJSONObject(); 1117 1118 // Mandatory fields 1119 1120 List<String> stringList = new ArrayList<>(subjectTypes.size()); 1121 1122 for (SubjectType st: subjectTypes) 1123 stringList.add(st.toString()); 1124 1125 o.put("subject_types_supported", stringList); 1126 1127 // Optional fields 1128 1129 if (userInfoEndpoint != null) 1130 o.put("userinfo_endpoint", userInfoEndpoint.toString()); 1131 1132 if (checkSessionIframe != null) 1133 o.put("check_session_iframe", checkSessionIframe.toString()); 1134 1135 if (endSessionEndpoint != null) 1136 o.put("end_session_endpoint", endSessionEndpoint.toString()); 1137 1138 if (acrValues != null) { 1139 o.put("acr_values_supported", Identifier.toStringList(acrValues)); 1140 } 1141 1142 if (idTokenJWSAlgs != null) { 1143 1144 stringList = new ArrayList<>(idTokenJWSAlgs.size()); 1145 1146 for (JWSAlgorithm alg: idTokenJWSAlgs) 1147 stringList.add(alg.getName()); 1148 1149 o.put("id_token_signing_alg_values_supported", stringList); 1150 } 1151 1152 if (idTokenJWEAlgs != null) { 1153 1154 stringList = new ArrayList<>(idTokenJWEAlgs.size()); 1155 1156 for (JWEAlgorithm alg: idTokenJWEAlgs) 1157 stringList.add(alg.getName()); 1158 1159 o.put("id_token_encryption_alg_values_supported", stringList); 1160 } 1161 1162 if (idTokenJWEEncs != null) { 1163 1164 stringList = new ArrayList<>(idTokenJWEEncs.size()); 1165 1166 for (EncryptionMethod m: idTokenJWEEncs) 1167 stringList.add(m.getName()); 1168 1169 o.put("id_token_encryption_enc_values_supported", stringList); 1170 } 1171 1172 if (userInfoJWSAlgs != null) { 1173 1174 stringList = new ArrayList<>(userInfoJWSAlgs.size()); 1175 1176 for (JWSAlgorithm alg: userInfoJWSAlgs) 1177 stringList.add(alg.getName()); 1178 1179 o.put("userinfo_signing_alg_values_supported", stringList); 1180 } 1181 1182 if (userInfoJWEAlgs != null) { 1183 1184 stringList = new ArrayList<>(userInfoJWEAlgs.size()); 1185 1186 for (JWEAlgorithm alg: userInfoJWEAlgs) 1187 stringList.add(alg.getName()); 1188 1189 o.put("userinfo_encryption_alg_values_supported", stringList); 1190 } 1191 1192 if (userInfoJWEEncs != null) { 1193 1194 stringList = new ArrayList<>(userInfoJWEEncs.size()); 1195 1196 for (EncryptionMethod m: userInfoJWEEncs) 1197 stringList.add(m.getName()); 1198 1199 o.put("userinfo_encryption_enc_values_supported", stringList); 1200 } 1201 1202 if (displays != null) { 1203 1204 stringList = new ArrayList<>(displays.size()); 1205 1206 for (Display d: displays) 1207 stringList.add(d.toString()); 1208 1209 o.put("display_values_supported", stringList); 1210 } 1211 1212 if (claimTypes != null) { 1213 1214 stringList = new ArrayList<>(claimTypes.size()); 1215 1216 for (ClaimType ct: claimTypes) 1217 stringList.add(ct.toString()); 1218 1219 o.put("claim_types_supported", stringList); 1220 } 1221 1222 if (claims != null) 1223 o.put("claims_supported", claims); 1224 1225 if (claimsLocales != null) { 1226 1227 stringList = new ArrayList<>(claimsLocales.size()); 1228 1229 for (LangTag l: claimsLocales) 1230 stringList.add(l.toString()); 1231 1232 o.put("claims_locales_supported", stringList); 1233 } 1234 1235 if (claimsParamSupported) { 1236 o.put("claims_parameter_supported", true); 1237 } 1238 1239 if (supportsRequestURIParam()) { 1240 // default true 1241 o.remove("request_uri_parameter_supported"); 1242 } else { 1243 o.put("request_uri_parameter_supported", false); 1244 } 1245 1246 // optional front and back-channel logout 1247 if (frontChannelLogoutSupported) { 1248 o.put("frontchannel_logout_supported", true); 1249 } 1250 1251 if (frontChannelLogoutSupported) { 1252 o.put("frontchannel_logout_session_supported", frontChannelLogoutSessionSupported); 1253 } 1254 1255 if (backChannelLogoutSupported) { 1256 o.put("backchannel_logout_supported", true); 1257 } 1258 1259 if (backChannelLogoutSupported) { 1260 o.put("backchannel_logout_session_supported", backChannelLogoutSessionSupported); 1261 } 1262 1263 // identity assurance 1264 1265 if (verifiedClaimsSupported) { 1266 o.put("verified_claims_supported", true); 1267 if (trustFrameworks != null) { 1268 o.put("trust_frameworks_supported", Identifier.toStringList(trustFrameworks)); 1269 } 1270 if (evidenceTypes != null) { 1271 o.put("evidence_supported", Identifier.toStringList(evidenceTypes)); 1272 } 1273 if (idDocuments != null) { 1274 o.put("id_documents_supported", Identifier.toStringList(idDocuments)); 1275 } 1276 if (idVerificationMethods != null) { 1277 o.put("id_documents_verification_methods_supported", Identifier.toStringList(idVerificationMethods)); 1278 } 1279 if (verifiedClaims != null) { 1280 o.put("claims_in_verified_claims_supported", verifiedClaims); 1281 } 1282 } 1283 1284 // federation 1285 1286 if (CollectionUtils.isNotEmpty(federationTypes)) { 1287 o.put("federation_types_supported", Identifier.toStringList(federationTypes)); 1288 } 1289 if (organizationName != null) { 1290 o.put("organization_name", organizationName); 1291 } 1292 if (federationRegistrationEndpoint != null) { 1293 o.put("federation_registration_endpoint", federationRegistrationEndpoint.toString()); 1294 } 1295 1296 return o; 1297 } 1298 1299 1300 /** 1301 * Parses an OpenID Provider metadata from the specified JSON object. 1302 * 1303 * @param jsonObject The JSON object to parse. Must not be 1304 * {@code null}. 1305 * 1306 * @return The OpenID Provider metadata. 1307 * 1308 * @throws ParseException If the JSON object couldn't be parsed to an 1309 * OpenID Provider metadata. 1310 */ 1311 public static OIDCProviderMetadata parse(final JSONObject jsonObject) 1312 throws ParseException { 1313 1314 AuthorizationServerMetadata as = AuthorizationServerMetadata.parse(jsonObject); 1315 1316 List<SubjectType> subjectTypes = new ArrayList<>(); 1317 for (String v: JSONObjectUtils.getStringArray(jsonObject, "subject_types_supported")) { 1318 subjectTypes.add(SubjectType.parse(v)); 1319 } 1320 1321 OIDCProviderMetadata op = new OIDCProviderMetadata( 1322 as.getIssuer(), 1323 Collections.unmodifiableList(subjectTypes), 1324 as.getJWKSetURI()); 1325 1326 // Endpoints 1327 op.setAuthorizationEndpointURI(as.getAuthorizationEndpointURI()); 1328 op.setTokenEndpointURI(as.getTokenEndpointURI()); 1329 op.setRegistrationEndpointURI(as.getRegistrationEndpointURI()); 1330 op.setIntrospectionEndpointURI(as.getIntrospectionEndpointURI()); 1331 op.setRevocationEndpointURI(as.getRevocationEndpointURI()); 1332 op.setRequestObjectEndpoint(as.getRequestObjectEndpoint()); 1333 op.setPushedAuthorizationRequestEndpointURI(as.getPushedAuthorizationRequestEndpointURI()); 1334 op.userInfoEndpoint = JSONObjectUtils.getURI(jsonObject, "userinfo_endpoint", null); 1335 op.checkSessionIframe = JSONObjectUtils.getURI(jsonObject, "check_session_iframe", null); 1336 op.endSessionEndpoint = JSONObjectUtils.getURI(jsonObject, "end_session_endpoint", null); 1337 1338 // Capabilities 1339 op.setScopes(as.getScopes()); 1340 op.setResponseTypes(as.getResponseTypes()); 1341 op.setResponseModes(as.getResponseModes()); 1342 op.setGrantTypes(as.getGrantTypes()); 1343 1344 op.setTokenEndpointAuthMethods(as.getTokenEndpointAuthMethods()); 1345 op.setTokenEndpointJWSAlgs(as.getTokenEndpointJWSAlgs()); 1346 1347 op.setIntrospectionEndpointAuthMethods(as.getIntrospectionEndpointAuthMethods()); 1348 op.setIntrospectionEndpointJWSAlgs(as.getIntrospectionEndpointJWSAlgs()); 1349 1350 op.setRevocationEndpointAuthMethods(as.getRevocationEndpointAuthMethods()); 1351 op.setRevocationEndpointJWSAlgs(as.getRevocationEndpointJWSAlgs()); 1352 1353 op.setRequestObjectJWSAlgs(as.getRequestObjectJWSAlgs()); 1354 op.setRequestObjectJWEAlgs(as.getRequestObjectJWEAlgs()); 1355 op.setRequestObjectJWEEncs(as.getRequestObjectJWEEncs()); 1356 1357 op.setSupportsRequestParam(as.supportsRequestParam()); 1358 op.setSupportsRequestURIParam(as.supportsRequestURIParam()); 1359 op.setRequiresRequestURIRegistration(as.requiresRequestURIRegistration()); 1360 1361 op.setCodeChallengeMethods(as.getCodeChallengeMethods()); 1362 1363 if (jsonObject.get("acr_values_supported") != null) { 1364 1365 op.acrValues = new ArrayList<>(); 1366 1367 for (String v: JSONObjectUtils.getStringArray(jsonObject, "acr_values_supported")) { 1368 1369 if (v != null) 1370 op.acrValues.add(new ACR(v)); 1371 } 1372 } 1373 1374 // ID token 1375 1376 if (jsonObject.get("id_token_signing_alg_values_supported") != null) { 1377 1378 op.idTokenJWSAlgs = new ArrayList<>(); 1379 1380 for (String v: JSONObjectUtils.getStringArray(jsonObject, "id_token_signing_alg_values_supported")) { 1381 1382 if (v != null) 1383 op.idTokenJWSAlgs.add(JWSAlgorithm.parse(v)); 1384 } 1385 } 1386 1387 1388 if (jsonObject.get("id_token_encryption_alg_values_supported") != null) { 1389 1390 op.idTokenJWEAlgs = new ArrayList<>(); 1391 1392 for (String v: JSONObjectUtils.getStringArray(jsonObject, "id_token_encryption_alg_values_supported")) { 1393 1394 if (v != null) 1395 op.idTokenJWEAlgs.add(JWEAlgorithm.parse(v)); 1396 } 1397 } 1398 1399 1400 if (jsonObject.get("id_token_encryption_enc_values_supported") != null) { 1401 1402 op.idTokenJWEEncs = new ArrayList<>(); 1403 1404 for (String v: JSONObjectUtils.getStringArray(jsonObject, "id_token_encryption_enc_values_supported")) { 1405 1406 if (v != null) 1407 op.idTokenJWEEncs.add(EncryptionMethod.parse(v)); 1408 } 1409 } 1410 1411 // UserInfo 1412 1413 if (jsonObject.get("userinfo_signing_alg_values_supported") != null) { 1414 1415 op.userInfoJWSAlgs = new ArrayList<>(); 1416 1417 for (String v: JSONObjectUtils.getStringArray(jsonObject, "userinfo_signing_alg_values_supported")) { 1418 1419 if (v != null) 1420 op.userInfoJWSAlgs.add(JWSAlgorithm.parse(v)); 1421 } 1422 } 1423 1424 1425 if (jsonObject.get("userinfo_encryption_alg_values_supported") != null) { 1426 1427 op.userInfoJWEAlgs = new ArrayList<>(); 1428 1429 for (String v: JSONObjectUtils.getStringArray(jsonObject, "userinfo_encryption_alg_values_supported")) { 1430 1431 if (v != null) 1432 op.userInfoJWEAlgs.add(JWEAlgorithm.parse(v)); 1433 } 1434 } 1435 1436 1437 if (jsonObject.get("userinfo_encryption_enc_values_supported") != null) { 1438 1439 op.userInfoJWEEncs = new ArrayList<>(); 1440 1441 for (String v: JSONObjectUtils.getStringArray(jsonObject, "userinfo_encryption_enc_values_supported")) { 1442 1443 if (v != null) 1444 op.userInfoJWEEncs.add(EncryptionMethod.parse(v)); 1445 } 1446 } 1447 1448 1449 // Misc 1450 1451 if (jsonObject.get("display_values_supported") != null) { 1452 1453 op.displays = new ArrayList<>(); 1454 1455 for (String v: JSONObjectUtils.getStringArray(jsonObject, "display_values_supported")) { 1456 1457 if (v != null) 1458 op.displays.add(Display.parse(v)); 1459 } 1460 } 1461 1462 if (jsonObject.get("claim_types_supported") != null) { 1463 1464 op.claimTypes = new ArrayList<>(); 1465 1466 for (String v: JSONObjectUtils.getStringArray(jsonObject, "claim_types_supported")) { 1467 1468 if (v != null) 1469 op.claimTypes.add(ClaimType.parse(v)); 1470 } 1471 } 1472 1473 1474 if (jsonObject.get("claims_supported") != null) { 1475 1476 op.claims = new ArrayList<>(); 1477 1478 for (String v: JSONObjectUtils.getStringArray(jsonObject, "claims_supported")) { 1479 1480 if (v != null) 1481 op.claims.add(v); 1482 } 1483 } 1484 1485 if (jsonObject.get("claims_locales_supported") != null) { 1486 1487 op.claimsLocales = new ArrayList<>(); 1488 1489 for (String v : JSONObjectUtils.getStringArray(jsonObject, "claims_locales_supported")) { 1490 1491 if (v != null) { 1492 1493 try { 1494 op.claimsLocales.add(LangTag.parse(v)); 1495 1496 } catch (LangTagException e) { 1497 1498 throw new ParseException("Invalid claims_locales_supported field: " + e.getMessage(), e); 1499 } 1500 } 1501 } 1502 } 1503 1504 op.setUILocales(as.getUILocales()); 1505 op.setServiceDocsURI(as.getServiceDocsURI()); 1506 op.setPolicyURI(as.getPolicyURI()); 1507 op.setTermsOfServiceURI(as.getTermsOfServiceURI()); 1508 1509 if (jsonObject.get("claims_parameter_supported") != null) 1510 op.claimsParamSupported = JSONObjectUtils.getBoolean(jsonObject, "claims_parameter_supported"); 1511 1512 if (jsonObject.get("request_uri_parameter_supported") == null) { 1513 op.setSupportsRequestURIParam(true); 1514 } 1515 1516 // Optional front and back-channel logout 1517 if (jsonObject.get("frontchannel_logout_supported") != null) 1518 op.frontChannelLogoutSupported = JSONObjectUtils.getBoolean(jsonObject, "frontchannel_logout_supported"); 1519 1520 if (op.frontChannelLogoutSupported && jsonObject.get("frontchannel_logout_session_supported") != null) 1521 op.frontChannelLogoutSessionSupported = JSONObjectUtils.getBoolean(jsonObject, "frontchannel_logout_session_supported"); 1522 1523 if (jsonObject.get("backchannel_logout_supported") != null) 1524 op.backChannelLogoutSupported = JSONObjectUtils.getBoolean(jsonObject, "backchannel_logout_supported"); 1525 1526 if (op.frontChannelLogoutSupported && jsonObject.get("backchannel_logout_session_supported") != null) 1527 op.backChannelLogoutSessionSupported = JSONObjectUtils.getBoolean(jsonObject, "backchannel_logout_session_supported"); 1528 1529 if (jsonObject.get("mtls_endpoint_aliases") != null) 1530 op.setMtlsEndpointAliases(OIDCProviderEndpointMetadata.parse(JSONObjectUtils.getJSONObject(jsonObject, "mtls_endpoint_aliases"))); 1531 1532 op.setSupportsTLSClientCertificateBoundAccessTokens(as.supportsTLSClientCertificateBoundAccessTokens()); 1533 1534 // JARM 1535 op.setAuthorizationJWSAlgs(as.getAuthorizationJWSAlgs()); 1536 op.setAuthorizationJWEAlgs(as.getAuthorizationJWEAlgs()); 1537 op.setAuthorizationJWEEncs(as.getAuthorizationJWEEncs()); 1538 1539 // OpenID Connect for Identity Assurance 1.0 1540 if (jsonObject.get("verified_claims_supported") != null) { 1541 op.verifiedClaimsSupported = JSONObjectUtils.getBoolean(jsonObject, "verified_claims_supported"); 1542 if (op.verifiedClaimsSupported) { 1543 if (jsonObject.get("trust_frameworks_supported") != null) { 1544 op.trustFrameworks = new LinkedList<>(); 1545 for (String v : JSONObjectUtils.getStringList(jsonObject, "trust_frameworks_supported")) { 1546 op.trustFrameworks.add(new IdentityTrustFramework(v)); 1547 } 1548 } 1549 if (jsonObject.get("evidence_supported") != null) { 1550 op.evidenceTypes = new LinkedList<>(); 1551 for (String v: JSONObjectUtils.getStringList(jsonObject, "evidence_supported")) { 1552 op.evidenceTypes.add(new IdentityEvidenceType(v)); 1553 } 1554 } 1555 if (jsonObject.get("id_documents_supported") != null) { 1556 op.idDocuments = new LinkedList<>(); 1557 for (String v: JSONObjectUtils.getStringList(jsonObject, "id_documents_supported")) { 1558 op.idDocuments.add(new IDDocumentType(v)); 1559 } 1560 } 1561 if (jsonObject.get("id_documents_verification_methods_supported") != null) { 1562 op.idVerificationMethods = new LinkedList<>(); 1563 for (String v: JSONObjectUtils.getStringList(jsonObject, "id_documents_verification_methods_supported")) { 1564 op.idVerificationMethods.add(new IdentityVerificationMethod(v)); 1565 } 1566 } 1567 if (jsonObject.get("claims_in_verified_claims_supported") != null) { 1568 op.verifiedClaims = JSONObjectUtils.getStringList(jsonObject, "claims_in_verified_claims_supported"); 1569 } 1570 } 1571 } 1572 1573 // Federation 1574 1575 if (jsonObject.get("federation_types_supported") != null) { 1576 op.federationTypes = new LinkedList<>(); 1577 for (String v: JSONObjectUtils.getStringList(jsonObject, "federation_types_supported")) { 1578 op.federationTypes.add(new FederationType(v)); 1579 } 1580 } 1581 1582 op.organizationName = JSONObjectUtils.getString(jsonObject, "organization_name", null); 1583 1584 op.federationRegistrationEndpoint = JSONObjectUtils.getURI(jsonObject, "federation_registration_endpoint", null); 1585 1586 // Parse custom (not registered) parameters 1587 for (Map.Entry<String,?> entry: as.getCustomParameters().entrySet()) { 1588 if (REGISTERED_PARAMETER_NAMES.contains(entry.getKey())) 1589 continue; // skip 1590 op.setCustomParameter(entry.getKey(), entry.getValue()); 1591 } 1592 1593 return op; 1594 } 1595 1596 1597 /** 1598 * Parses an OpenID Provider metadata from the specified JSON object 1599 * string. 1600 * 1601 * @param s The JSON object sting to parse. Must not be {@code null}. 1602 * 1603 * @return The OpenID Provider metadata. 1604 * 1605 * @throws ParseException If the JSON object string couldn't be parsed 1606 * to an OpenID Provider metadata. 1607 */ 1608 public static OIDCProviderMetadata parse(final String s) 1609 throws ParseException { 1610 1611 return parse(JSONObjectUtils.parse(s)); 1612 } 1613 1614 1615 /** 1616 * Resolves OpenID Provider metadata URL from the specified issuer 1617 * identifier. 1618 * 1619 * @param issuer The OpenID Provider issuer identifier. Must represent 1620 * a valid HTTPS or HTTP URL. Must not be {@code null}. 1621 * 1622 * @return The OpenID Provider metadata URL. 1623 * 1624 * @throws GeneralException If the issuer identifier is invalid. 1625 */ 1626 public static URL resolveURL(final Issuer issuer) 1627 throws GeneralException { 1628 1629 try { 1630 URL issuerURL = new URL(issuer.getValue()); 1631 1632 // Validate but don't insist on HTTPS, see 1633 // http://openid.net/specs/openid-connect-core-1_0.html#Terminology 1634 if (issuerURL.getQuery() != null && ! issuerURL.getQuery().trim().isEmpty()) { 1635 throw new GeneralException("The issuer identifier must not contain a query component"); 1636 } 1637 1638 if (issuerURL.getPath() != null && issuerURL.getPath().endsWith("/")) { 1639 return new URL(issuerURL + ".well-known/openid-configuration"); 1640 } else { 1641 return new URL(issuerURL + "/.well-known/openid-configuration"); 1642 } 1643 1644 } catch (MalformedURLException e) { 1645 throw new GeneralException("The issuer identifier doesn't represent a valid URL: " + e.getMessage(), e); 1646 } 1647 } 1648 1649 1650 /** 1651 * Resolves OpenID Provider metadata from the specified issuer 1652 * identifier. The metadata is downloaded by HTTP GET from 1653 * {@code [issuer-url]/.well-known/openid-configuration}. 1654 * 1655 * @param issuer The OpenID Provider issuer identifier. Must represent 1656 * a valid HTTPS or HTTP URL. Must not be {@code null}. 1657 * 1658 * @return The OpenID Provider metadata. 1659 * 1660 * @throws GeneralException If the issuer identifier or the downloaded 1661 * metadata are invalid. 1662 * @throws IOException On a HTTP exception. 1663 */ 1664 public static OIDCProviderMetadata resolve(final Issuer issuer) 1665 throws GeneralException, IOException { 1666 1667 return resolve(issuer, 0, 0); 1668 } 1669 1670 1671 /** 1672 * Resolves OpenID Provider metadata from the specified issuer 1673 * identifier. The metadata is downloaded by HTTP GET from 1674 * {@code [issuer-url]/.well-known/openid-configuration}, using the 1675 * specified HTTP timeouts. 1676 * 1677 * @param issuer The issuer identifier. Must represent a valid 1678 * HTTPS or HTTP URL. Must not be {@code null}. 1679 * @param connectTimeout The HTTP connect timeout, in milliseconds. 1680 * Zero implies no timeout. Must not be negative. 1681 * @param readTimeout The HTTP response read timeout, in 1682 * milliseconds. Zero implies no timeout. Must 1683 * not be negative. 1684 * 1685 * @return The OpenID Provider metadata. 1686 * 1687 * @throws GeneralException If the issuer identifier or the downloaded 1688 * metadata are invalid. 1689 * @throws IOException On a HTTP exception. 1690 */ 1691 public static OIDCProviderMetadata resolve(final Issuer issuer, 1692 final int connectTimeout, 1693 final int readTimeout) 1694 throws GeneralException, IOException { 1695 1696 URL configURL = resolveURL(issuer); 1697 1698 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.GET, configURL); 1699 httpRequest.setConnectTimeout(connectTimeout); 1700 httpRequest.setReadTimeout(readTimeout); 1701 1702 HTTPResponse httpResponse = httpRequest.send(); 1703 1704 if (httpResponse.getStatusCode() != 200) { 1705 throw new IOException("Couldn't download OpenID Provider metadata from " + configURL + 1706 ": Status code " + httpResponse.getStatusCode()); 1707 } 1708 1709 JSONObject jsonObject = httpResponse.getContentAsJSONObject(); 1710 1711 OIDCProviderMetadata op = OIDCProviderMetadata.parse(jsonObject); 1712 1713 if (! issuer.equals(op.getIssuer())) { 1714 throw new GeneralException("The returned issuer doesn't match the expected: " + op.getIssuer()); 1715 } 1716 1717 return op; 1718 } 1719}