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