001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.auth.oauth.oidc;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import java.net.*;
022import java.util.*;
023
024/**
025 * Immutable record produced by {@link OidcDiscoveryClient} carrying the metadata fields a Juneau OAuth /
026 * OIDC consumer typically needs.
027 *
028 * <p>
029 * Unknown fields (IdP-specific extensions) are preserved in {@link #extras()} as a read-only
030 * {@code Map<String,Object>}.
031 *
032 * @param issuer The {@code issuer} URI.  Never {@code null}.
033 * @param tokenEndpoint The {@code token_endpoint} URI.
034 * @param authorizationEndpoint The {@code authorization_endpoint} URI.  May be {@code null} for pure
035 *    machine-to-machine IdPs.
036 * @param introspectionEndpoint The RFC 7662 introspection endpoint URI.  May be {@code null}.
037 * @param jwksUri The {@code jwks_uri} URI.
038 * @param userinfoEndpoint The OIDC {@code userinfo_endpoint} URI.  May be {@code null}.
039 * @param endSessionEndpoint The OIDC end-session endpoint URI.  May be {@code null}.
040 * @param supportedScopes Scopes the IdP advertises support for.  May be empty.
041 * @param extras Unknown / IdP-specific fields.  Read-only map.
042 * @since 10.0.0
043 */
044public record OidcMetadata(
045      URI issuer,
046      URI tokenEndpoint,
047      URI authorizationEndpoint,
048      URI introspectionEndpoint,
049      URI jwksUri,
050      URI userinfoEndpoint,
051      URI endSessionEndpoint,
052      Set<String> supportedScopes,
053      Map<String,Object> extras) {
054
055   /**
056    * Compact constructor that defensively copies the collections.
057    */
058   public OidcMetadata {
059      Objects.requireNonNull(issuer, "issuer");
060      supportedScopes = supportedScopes == null
061         ? Collections.emptySet()
062         : u(cp(supportedScopes));
063      extras = extras == null
064         ? Collections.emptyMap()
065         : u(cp(extras));
066   }
067
068   /**
069    * Returns whether the authorization server advertises {@code authorization_response_iss_parameter_supported}
070    * (RFC 9207).
071    *
072    * <p>
073    * When {@code true}, a compliant client MUST reject an authorization response that omits the {@code iss}
074    * parameter.
075    *
076    * @return <jk>true</jk> if the {@code authorization_response_iss_parameter_supported} extra is present and set to
077    *    {@code true}.
078    */
079   public boolean authorizationResponseIssParameterSupported() {
080      return Boolean.TRUE.equals(extras.get("authorization_response_iss_parameter_supported"));
081   }
082}