001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2021, 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.federation.api; 019 020 021import java.util.*; 022 023import net.minidev.json.JSONObject; 024 025import com.nimbusds.jwt.JWTClaimsSet; 026import com.nimbusds.oauth2.sdk.ParseException; 027import com.nimbusds.oauth2.sdk.id.Issuer; 028import com.nimbusds.oauth2.sdk.id.Subject; 029import com.nimbusds.oauth2.sdk.util.CollectionUtils; 030import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 031import com.nimbusds.oauth2.sdk.util.MapUtils; 032import com.nimbusds.openid.connect.sdk.federation.entities.CommonFederationClaimsSet; 033import com.nimbusds.openid.connect.sdk.federation.entities.EntityID; 034import com.nimbusds.openid.connect.sdk.federation.trust.TrustChain; 035 036 037/** 038 * Resolve response claims set. 039 * 040 * <p>Related specifications: 041 * 042 * <ul> 043 * <li>OpenID Connect Federation 1.0, section 7.2.2. 044 * </ul> 045 */ 046public class ResolveClaimsSet extends CommonFederationClaimsSet { 047 048 049 /** 050 * The trust chain claim name. 051 */ 052 public static final String TRUST_CHAIN_CLAIM_NAME = "trust_chain"; 053 054 055 /** 056 * The names of the standard top-level claims. 057 */ 058 private static final Set<String> STD_CLAIM_NAMES; 059 060 static { 061 Set<String> claimNames = new HashSet<>(); 062 claimNames.add(ISS_CLAIM_NAME); 063 claimNames.add(SUB_CLAIM_NAME); 064 claimNames.add(IAT_CLAIM_NAME); 065 claimNames.add(EXP_CLAIM_NAME); 066 claimNames.add(METADATA_CLAIM_NAME); 067 claimNames.add(TRUST_MARKS_CLAIM_NAME); 068 claimNames.add(TRUST_CHAIN_CLAIM_NAME); 069 STD_CLAIM_NAMES = Collections.unmodifiableSet(claimNames); 070 } 071 072 073 /** 074 * Gets the names of the standard top-level claims. 075 * 076 * @return The names of the standard top-level claims (read-only set). 077 */ 078 public static Set<String> getStandardClaimNames() { 079 080 return STD_CLAIM_NAMES; 081 } 082 083 084 /** 085 * Creates a new resolve response claims set with the minimum required 086 * claims. 087 * 088 * @param iss The issuer. Must not be {@code null}. 089 * @param sub The subject. Must not be {@code null}. 090 * @param iat The issue time. Must not be {@code null}. 091 * @param exp The expiration time. Must not be {@code null}. 092 * @param metadata The metadata JSON object. Must not be {@code null}. 093 */ 094 public ResolveClaimsSet(final Issuer iss, 095 final Subject sub, 096 final Date iat, 097 final Date exp, 098 final JSONObject metadata) { 099 100 this(new EntityID(iss.getValue()), new EntityID(sub.getValue()), iat, exp, metadata); 101 } 102 103 104 /** 105 * Creates a new resolve response claims set with the minimum required 106 * claims. 107 * 108 * @param iss The issuer. Must not be {@code null}. 109 * @param sub The subject. Must not be {@code null}. 110 * @param iat The issue time. Must not be {@code null}. 111 * @param exp The expiration time. Must not be {@code null}. 112 * @param metadata The metadata JSON object. Must not be {@code null}. 113 */ 114 public ResolveClaimsSet(final EntityID iss, 115 final EntityID sub, 116 final Date iat, 117 final Date exp, 118 final JSONObject metadata) { 119 120 setClaim(ISS_CLAIM_NAME, iss.getValue()); 121 setClaim(SUB_CLAIM_NAME, sub.getValue()); 122 123 if (iat == null) { 124 throw new IllegalArgumentException("The iat (issued-at) claim must not be null"); 125 } 126 setDateClaim(IAT_CLAIM_NAME, iat); 127 128 if (exp == null) { 129 throw new IllegalArgumentException("The exp (expiration) claim must not be null"); 130 } 131 setDateClaim(EXP_CLAIM_NAME, exp); 132 133 if (metadata == null || metadata.isEmpty()) { 134 throw new IllegalArgumentException("The metadata claim must not be null"); 135 } 136 setClaim(METADATA_CLAIM_NAME, metadata); 137 } 138 139 140 /** 141 * Creates a new resolve response claims set from the specified JWT 142 * claims set. 143 * 144 * @param jwtClaimsSet The JWT claims set. Must not be {@code null}. 145 * 146 * @throws ParseException If the JWT claims set doesn't represent a 147 * valid resolve response claims set. 148 */ 149 public ResolveClaimsSet(final JWTClaimsSet jwtClaimsSet) 150 throws ParseException { 151 152 super(JSONObjectUtils.toJSONObject(jwtClaimsSet)); 153 154 validateRequiredClaimsPresence(); 155 } 156 157 158 /** 159 * Validates this claims set for having all minimum required claims for 160 * a resolve response. 161 * 162 * @throws ParseException If the validation failed and a required claim 163 * is missing. 164 */ 165 public void validateRequiredClaimsPresence() 166 throws ParseException { 167 168 super.validateRequiredClaimsPresence(); 169 170 if (MapUtils.isEmpty(getJSONObjectClaim(METADATA_CLAIM_NAME))) { 171 throw new ParseException("Missing metadata claim"); 172 } 173 } 174 175 176 /** 177 * Gets the trust chain. Corresponds to the {@code trust_chain} claim. 178 * 179 * @return The trust chain, {@code null} if not specified or parsing 180 * failed. 181 */ 182 public TrustChain getTrustChain() { 183 184 List<String> chainJWTs = getStringListClaim(TRUST_CHAIN_CLAIM_NAME); 185 186 if (CollectionUtils.isEmpty(chainJWTs)) { 187 return null; 188 } 189 190 try { 191 return TrustChain.parseSerialized(chainJWTs); 192 } catch (ParseException e) { 193 return null; 194 } 195 } 196 197 198 /** 199 * Sets the trust chain. Corresponds to the {@code trust_chain} claim. 200 * 201 * @param trustChain The trust chain, {@code null} if not specified. 202 */ 203 public void setTrustChain(final TrustChain trustChain) { 204 205 if (trustChain != null) { 206 setClaim(TRUST_CHAIN_CLAIM_NAME, trustChain.toSerializedJWTs()); 207 } else { 208 setClaim(TRUST_CHAIN_CLAIM_NAME, null); 209 } 210 } 211}