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