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.oauth2.sdk.client; 019 020 021import java.net.URI; 022import java.util.Collections; 023import java.util.Date; 024import java.util.HashSet; 025import java.util.Set; 026 027import net.jcip.annotations.Immutable; 028import net.minidev.json.JSONObject; 029 030import com.nimbusds.oauth2.sdk.ParseException; 031import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod; 032import com.nimbusds.oauth2.sdk.auth.Secret; 033import com.nimbusds.oauth2.sdk.id.ClientID; 034import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 035 036 037/** 038 * Client information. Encapsulates the registration and metadata details of 039 * an OAuth 2.0 client: 040 * 041 * <ul> 042 * <li>The client identifier. 043 * <li>The client metadata. 044 * <li>The optional client secret for a confidential client. 045 * <li>The optional registration URI and access token if dynamic client 046 * registration is permitted. 047 * </ul> 048 * 049 * <p>Related specifications: 050 * 051 * <ul> 052 * <li>OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591), section 053 * 3.2.1. 054 * <li>OAuth 2.0 Dynamic Client Registration Management Protocol (RFC 055 * 7592), section 3. 056 * </ul> 057 */ 058@Immutable 059public class ClientInformation { 060 061 062 /** 063 * The registered parameter names. 064 */ 065 private static final Set<String> REGISTERED_PARAMETER_NAMES; 066 067 068 static { 069 Set<String> p = new HashSet<>(ClientMetadata.getRegisteredParameterNames()); 070 071 p.add("client_id"); 072 p.add("client_id_issued_at"); 073 p.add("client_secret"); 074 p.add("client_secret_expires_at"); 075 p.add("registration_access_token"); 076 p.add("registration_client_uri"); 077 078 REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p); 079 } 080 081 082 /** 083 * The registered client ID. 084 */ 085 private final ClientID id; 086 087 088 /** 089 * The date the client ID was issued at. 090 */ 091 private final Date issueDate; 092 093 094 /** 095 * The client metadata. 096 */ 097 private final ClientMetadata metadata; 098 099 100 /** 101 * The optional client secret. 102 */ 103 private final Secret secret; 104 105 106 /** 107 * The client registration URI. 108 */ 109 private final URI registrationURI; 110 111 112 /** 113 * The client registration access token. 114 */ 115 private final BearerAccessToken accessToken; 116 117 118 /** 119 * Creates a new minimal client information instance without a client 120 * secret. 121 * 122 * @param id The client identifier. Must not be {@code null}. 123 * @param metadata The client metadata. Must not be {@code null}. 124 */ 125 public ClientInformation(final ClientID id, final ClientMetadata metadata) { 126 this(id, null, metadata, null); 127 } 128 129 130 /** 131 * Creates a new client information instance. 132 * 133 * @param id The client identifier. Must not be {@code null}. 134 * @param issueDate The issue date of the client identifier, 135 * {@code null} if not specified. 136 * @param metadata The client metadata. Must not be {@code null}. 137 * @param secret The optional client secret, {@code null} if not 138 * specified. 139 */ 140 public ClientInformation(final ClientID id, 141 final Date issueDate, 142 final ClientMetadata metadata, 143 final Secret secret) { 144 145 this(id, issueDate, metadata, secret, null, null); 146 } 147 148 149 /** 150 * Creates a new client information instance permitting dynamic client 151 * registration management. 152 * 153 * @param id The client identifier. Must not be 154 * {@code null}. 155 * @param issueDate The issue date of the client identifier, 156 * {@code null} if not specified. 157 * @param metadata The client metadata. Must not be 158 * {@code null}. 159 * @param secret The optional client secret, {@code null} if 160 * not specified. 161 * @param registrationURI The client registration URI, {@code null} if 162 * not specified. 163 * @param accessToken The client registration access token, 164 * {@code null} if not specified. 165 */ 166 public ClientInformation(final ClientID id, 167 final Date issueDate, 168 final ClientMetadata metadata, 169 final Secret secret, 170 final URI registrationURI, 171 final BearerAccessToken accessToken) { 172 173 if (id == null) 174 throw new IllegalArgumentException("The client identifier must not be null"); 175 176 this.id = id; 177 178 this.issueDate = issueDate; 179 180 if (metadata == null) 181 throw new IllegalArgumentException("The client metadata must not be null"); 182 183 this.metadata = metadata; 184 185 this.secret = secret; 186 187 this.registrationURI = registrationURI; 188 189 this.accessToken = accessToken; 190 } 191 192 193 /** 194 * Gets the registered client metadata parameter names. 195 * 196 * @return The registered parameter names, as an unmodifiable set. 197 */ 198 public static Set<String> getRegisteredParameterNames() { 199 200 return REGISTERED_PARAMETER_NAMES; 201 } 202 203 204 /** 205 * Gets the client identifier. Corresponds to the {@code client_id} 206 * client registration parameter. 207 * 208 * @return The client ID. 209 */ 210 public ClientID getID() { 211 212 return id; 213 } 214 215 216 /** 217 * Gets the issue date of the client identifier. Corresponds to the 218 * {@code client_id_issued_at} client registration parameter. 219 * 220 * @return The issue date, {@code null} if not specified. 221 */ 222 public Date getIDIssueDate() { 223 224 return issueDate; 225 } 226 227 228 /** 229 * Gets the client metadata. 230 * 231 * @return The client metadata. 232 */ 233 public ClientMetadata getMetadata() { 234 235 return metadata; 236 } 237 238 239 /** 240 * Gets the client secret. Corresponds to the {@code client_secret} and 241 * {@code client_secret_expires_at} client registration parameters. 242 * 243 * @return The client secret, {@code null} if not specified. 244 */ 245 public Secret getSecret() { 246 247 return secret; 248 } 249 250 251 /** 252 * Infers the client type. 253 * 254 * @return The client type. 255 */ 256 public ClientType inferClientType() { 257 258 // The client must by unambiguously public, else it is marked as confidential 259 260 return secret == null 261 && ClientAuthenticationMethod.NONE.equals(getMetadata().getTokenEndpointAuthMethod()) 262 && getMetadata().getJWKSetURI() == null 263 && getMetadata().getJWKSet() == null 264 ? ClientType.PUBLIC : ClientType.CONFIDENTIAL; 265 } 266 267 268 /** 269 * Gets the URI of the client registration. Corresponds to the 270 * {@code registration_client_uri} client registration parameter. 271 * 272 * @return The registration URI, {@code null} if not specified. 273 */ 274 public URI getRegistrationURI() { 275 276 return registrationURI; 277 } 278 279 280 /** 281 * Gets the registration access token. Corresponds to the 282 * {@code registration_access_token} client registration parameter. 283 * 284 * @return The registration access token, {@code null} if not 285 * specified. 286 */ 287 public BearerAccessToken getRegistrationAccessToken() { 288 289 return accessToken; 290 } 291 292 293 /** 294 * Returns the JSON object representation of this client information 295 * instance. 296 * 297 * @return The JSON object. 298 */ 299 public JSONObject toJSONObject() { 300 301 JSONObject o = metadata.toJSONObject(); 302 303 o.put("client_id", id.getValue()); 304 305 if (issueDate != null) { 306 307 o.put("client_id_issued_at", issueDate.getTime() / 1000); 308 } 309 310 if (secret != null) { 311 o.put("client_secret", secret.getValue()); 312 313 if (secret.getExpirationDate() != null) { 314 o.put("client_secret_expires_at", secret.getExpirationDate().getTime() / 1000); 315 } else { 316 o.put("client_secret_expires_at", 0L); 317 } 318 } 319 320 if (registrationURI != null) { 321 322 o.put("registration_client_uri", registrationURI.toString()); 323 } 324 325 if (accessToken != null) { 326 327 o.put("registration_access_token", accessToken.getValue()); 328 } 329 330 return o; 331 } 332 333 334 /** 335 * Parses a client information instance from the specified JSON object. 336 * 337 * @param jsonObject The JSON object to parse. Must not be 338 * {@code null}. 339 * 340 * @return The client information. 341 * 342 * @throws ParseException If the JSON object couldn't be parsed to a 343 * client information instance. 344 */ 345 public static ClientInformation parse(final JSONObject jsonObject) 346 throws ParseException { 347 348 return new ClientInformation( 349 ClientCredentialsParser.parseID(jsonObject), 350 ClientCredentialsParser.parseIDIssueDate(jsonObject), 351 ClientMetadata.parse(jsonObject), 352 ClientCredentialsParser.parseSecret(jsonObject), 353 ClientCredentialsParser.parseRegistrationURI(jsonObject), 354 ClientCredentialsParser.parseRegistrationAccessToken(jsonObject)); 355 } 356}