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