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