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