001 package com.nimbusds.oauth2.sdk.client; 002 003 004 import java.net.URL; 005 006 import org.apache.commons.lang3.StringUtils; 007 008 import net.jcip.annotations.Immutable; 009 010 import net.minidev.json.JSONObject; 011 012 import com.nimbusds.oauth2.sdk.ParseException; 013 import com.nimbusds.oauth2.sdk.ProtectedResourceRequest; 014 import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 015 import com.nimbusds.oauth2.sdk.http.HTTPRequest; 016 import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 017 018 019 /** 020 * Client registration request. This class is immutable. 021 * 022 * <p>Example HTTP request: 023 * 024 * <pre> 025 * POST /register HTTP/1.1 026 * Content-Type: application/json 027 * Accept: application/json 028 * Authorization: Bearer ey23f2.adfj230.af32-developer321 029 * Host: server.example.com 030 * 031 * { 032 * "redirect_uris" : ["https://client.example.org/callback", 033 * "https://client.example.org/callback2"] 034 * "client_name" : "My Example Client", 035 * "client_name#ja-Jpan-JP" : "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D", 036 * "token_endpoint_auth_method" : "client_secret_basic", 037 * "scope" : "read write dolphin", 038 * "logo_uri" : "https://client.example.org/logo.png", 039 * "jwks_uri" : "https://client.example.org/my_public_keys.jwks" 040 * } 041 * </pre> 042 * 043 * <p>Related specifications: 044 * 045 * <ul> 046 * <li>OAuth 2.0 Dynamic Client Registration Protocol 047 * (draft-ietf-oauth-dyn-reg-12), section 3.1. 048 * </ul> 049 * 050 * @author Vladimir Dzhuvinov 051 */ 052 @Immutable 053 public class ClientRegistrationRequest extends ProtectedResourceRequest { 054 055 056 /** 057 * The client metadata. 058 */ 059 private final ClientMetadata metadata; 060 061 062 /** 063 * Creates a new client registration request. 064 * 065 * @param metadata The client metadata. Must not be {@code null} and 066 * must specify one or more redirect URIs. 067 * @param accessToken An OAuth 2.0 Bearer access token for the request, 068 * {@code null} if none. 069 */ 070 public ClientRegistrationRequest(final ClientMetadata metadata, 071 final BearerAccessToken accessToken) { 072 073 super(accessToken); 074 075 if (metadata == null) 076 throw new IllegalArgumentException("The client metadata must not be null"); 077 078 this.metadata = metadata; 079 } 080 081 082 /** 083 * Gets the associated client metadata. 084 * 085 * @return The client metadata. 086 */ 087 public ClientMetadata getClientMetadata() { 088 089 return metadata; 090 } 091 092 093 @Override 094 public HTTPRequest toHTTPRequest(final URL url) { 095 096 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, url); 097 098 if (getAccessToken() != null) 099 httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader()); 100 101 httpRequest.setContentType(CommonContentTypes.APPLICATION_JSON); 102 103 httpRequest.setQuery(metadata.toJSONObject().toString()); 104 105 return httpRequest; 106 } 107 108 109 /** 110 * Parses a client registration request from the specified HTTP POST 111 * request. 112 * 113 * @param httpRequest The HTTP request. Must not be {@code null}. 114 * 115 * @return The client add (register) request. 116 * 117 * @throws ParseException If the HTTP request couldn't be parsed to a 118 * client register request. 119 */ 120 public static ClientRegistrationRequest parse(final HTTPRequest httpRequest) 121 throws ParseException { 122 123 httpRequest.ensureMethod(HTTPRequest.Method.POST); 124 125 // Parse the client metadata 126 JSONObject jsonObject = httpRequest.getQueryAsJSONObject(); 127 128 ClientMetadata metadata = ClientMetadata.parse(jsonObject); 129 130 // Parse the optinal bearer access token 131 BearerAccessToken accessToken = null; 132 133 String authzHeaderValue = httpRequest.getAuthorization(); 134 135 if (StringUtils.isNotBlank(authzHeaderValue)) 136 accessToken = BearerAccessToken.parse(authzHeaderValue); 137 138 return new ClientRegistrationRequest(metadata, accessToken); 139 } 140 }