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