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