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