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