001package com.nimbusds.openid.connect.provider.spi.grants; 002 003 004import java.util.List; 005import java.util.Set; 006 007import net.jcip.annotations.Immutable; 008import net.minidev.json.JSONObject; 009 010import com.nimbusds.langtag.LangTag; 011import com.nimbusds.langtag.LangTagException; 012import com.nimbusds.langtag.LangTagUtils; 013import com.nimbusds.oauth2.sdk.ParseException; 014import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 015import com.nimbusds.openid.connect.sdk.claims.ClaimsTransport; 016 017 018/** 019 * OpenID Connect claims specification. 020 */ 021@Immutable 022public class ClaimsSpec extends BasicClaimsSpec { 023 024 025 /** 026 * None (empty) claims specification. 027 */ 028 public static final ClaimsSpec NONE = new ClaimsSpec(); 029 030 031 /** 032 * The preferred claims locales, {@code null} if not specified. 033 */ 034 private final List<LangTag> locales; 035 036 037 /** 038 * The preferred claims transport. 039 */ 040 private final ClaimsTransport transport; 041 042 043 /** 044 * Creates a new default OpenID Connect claims specification (empty). 045 */ 046 public ClaimsSpec() { 047 048 this(null, null, null, null, ClaimsTransport.getDefault()); 049 } 050 051 052 /** 053 * Creates a new OpenID Connect claims specification. 054 * 055 * @param names The names of the authorised OpenID Connect claims, 056 * {@code null} if none. 057 */ 058 public ClaimsSpec(final Set<String> names) { 059 060 this(names, null, null, null, ClaimsTransport.getDefault()); 061 } 062 063 064 /** 065 * Creates a new OpenID Connect claims specification. 066 * 067 * @param names The names of the authorised OpenID 068 * Connect claims, {@code null} if none. 069 * @param locales The preferred claims locales, 070 * {@code null} if not specified. 071 * @param presetIDTokenClaims Additional or preset claims to be 072 * included in the ID token, {@code null} 073 * if none. 074 * @param presetUserInfoClaims Additional or preset claims to be 075 * included in the UserInfo response, 076 * {@code null} if none. 077 * @param transport The preferred claims transport. Must not 078 * be {@code null}. 079 */ 080 public ClaimsSpec(final Set<String> names, 081 final List<LangTag> locales, 082 final JSONObject presetIDTokenClaims, 083 final JSONObject presetUserInfoClaims, 084 final ClaimsTransport transport) { 085 086 this(names, locales, null, presetIDTokenClaims, presetUserInfoClaims, transport); 087 } 088 089 090 /** 091 * Creates a new OpenID Connect claims specification. 092 * 093 * @param names The names of the authorised OpenID 094 * Connect claims, {@code null} if none. 095 * @param locales The preferred claims locales, 096 * @param data Optional claims fulfillment data, 097 * {@code null} if not specified. 098 * {@code null} if not specified. 099 * @param presetIDTokenClaims Additional or preset claims to be 100 * included in the ID token, {@code null} 101 * if none. 102 * @param presetUserInfoClaims Additional or preset claims to be 103 * included in the UserInfo response, 104 * {@code null} if none. 105 * @param transport The preferred claims transport. Must not 106 * be {@code null}. 107 */ 108 public ClaimsSpec(final Set<String> names, 109 final List<LangTag> locales, 110 final JSONObject data, 111 final JSONObject presetIDTokenClaims, 112 final JSONObject presetUserInfoClaims, 113 final ClaimsTransport transport) { 114 115 super(names, data, new PresetClaims(presetIDTokenClaims, presetUserInfoClaims)); 116 117 this.locales = locales; 118 this.transport = transport; 119 } 120 121 122 /** 123 * Returns the preferred OpenID Connect claims locales. 124 * 125 * @return The preferred OpenID Connect claims locales, {@code null} if 126 * not specified. 127 */ 128 public List<LangTag> getLocales() { 129 130 return locales; 131 } 132 133 134 /** 135 * Returns the preferred claims transport. 136 * 137 * @return The preferred claims transport. 138 */ 139 public ClaimsTransport getTransport() { 140 141 return transport; 142 } 143 144 145 /** 146 * Returns a JSON object representation of this claims specification. 147 * 148 * @return The JSON object. 149 */ 150 public JSONObject toJSONObject() { 151 152 JSONObject o = super.toJSONObject(); 153 154 if (locales != null) { 155 o.put("claims_locales", LangTagUtils.toStringList(locales)); 156 } 157 158 o.put("claims_transport", transport.toString()); 159 160 return o; 161 } 162 163 164 /** 165 * Parses an OpenID Connect claims specification from the specified 166 * JSON object. 167 * 168 * @param o The JSON object. Must not be {@code null}. 169 * 170 * @return The OpenID Connect claims specification. 171 * 172 * @throws ParseException If parsing failed. 173 */ 174 public static ClaimsSpec parse(final JSONObject o) 175 throws ParseException { 176 177 BasicClaimsSpec basicSpec = BasicClaimsSpec.parse(o); 178 179 List<LangTag> claimsLocales = null; 180 181 if (JSONObjectUtils.containsKey(o, "claims_locales")) { 182 183 try { 184 claimsLocales = LangTagUtils.parseLangTagList(JSONObjectUtils.getStringArray(o, "claims_locales")); 185 186 } catch (LangTagException e) { 187 188 throw new ParseException("Invalid claims locales value: " + e.getMessage(), e); 189 } 190 } 191 192 ClaimsTransport claimsTransport; 193 194 if (o.containsKey("claims_transport")) { 195 String c = JSONObjectUtils.getString(o, "claims_transport"); 196 197 try { 198 claimsTransport = ClaimsTransport.valueOf(c.toUpperCase()); 199 } catch (IllegalArgumentException e) { 200 throw new ParseException("Invalid claims transport"); 201 } 202 } else { 203 // Defaults to UserInfo if not specified 204 claimsTransport = ClaimsTransport.getDefault(); 205 } 206 207 return new ClaimsSpec( 208 basicSpec.getNames(), 209 claimsLocales, 210 basicSpec.getData(), 211 basicSpec.getPresetIDTokenClaims(), 212 basicSpec.getPresetUserInfoClaims(), 213 claimsTransport); 214 } 215}