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