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.SerializeException; 015 import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 016 import com.nimbusds.oauth2.sdk.http.HTTPRequest; 017 import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 018 019 020 /** 021 * Client registration request. This class is immutable. 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-12), section 3.1. 049 * </ul> 050 * 051 * @author Vladimir Dzhuvinov 052 */ 053 @Immutable 054 public class ClientRegistrationRequest extends ProtectedResourceRequest { 055 056 057 /** 058 * The client metadata. 059 */ 060 private final ClientMetadata metadata; 061 062 063 /** 064 * Creates a new client registration request. 065 * 066 * @param uri The URI of the client registration endpoint. May 067 * be {@code null} if the {@link #toHTTPRequest()} 068 * method will not be used. 069 * @param metadata The client metadata. Must not be {@code null} and 070 * must specify one or more redirect URIs. 071 * @param accessToken An OAuth 2.0 Bearer access token for the request, 072 * {@code null} if none. 073 */ 074 public ClientRegistrationRequest(final URL uri, 075 final ClientMetadata metadata, 076 final BearerAccessToken accessToken) { 077 078 super(uri, accessToken); 079 080 if (metadata == null) 081 throw new IllegalArgumentException("The client metadata must not be null"); 082 083 this.metadata = metadata; 084 } 085 086 087 /** 088 * Gets the associated client metadata. 089 * 090 * @return The client metadata. 091 */ 092 public ClientMetadata getClientMetadata() { 093 094 return metadata; 095 } 096 097 098 @Override 099 public HTTPRequest toHTTPRequest() 100 throws SerializeException{ 101 102 if (getURI() == null) 103 throw new SerializeException("The endpoint URI is not specified"); 104 105 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, getURI()); 106 107 if (getAccessToken() != null) 108 httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader()); 109 110 httpRequest.setContentType(CommonContentTypes.APPLICATION_JSON); 111 112 httpRequest.setQuery(metadata.toJSONObject().toString()); 113 114 return httpRequest; 115 } 116 117 118 /** 119 * Parses a client registration request from the specified HTTP POST 120 * request. 121 * 122 * @param httpRequest The HTTP request. Must not be {@code null}. 123 * 124 * @return The client registration request. 125 * 126 * @throws ParseException If the HTTP request couldn't be parsed to a 127 * client registration request. 128 */ 129 public static ClientRegistrationRequest parse(final HTTPRequest httpRequest) 130 throws ParseException { 131 132 httpRequest.ensureMethod(HTTPRequest.Method.POST); 133 134 // Parse the client metadata 135 JSONObject jsonObject = httpRequest.getQueryAsJSONObject(); 136 137 ClientMetadata metadata = ClientMetadata.parse(jsonObject); 138 139 // Parse the optinal bearer access token 140 BearerAccessToken accessToken = null; 141 142 String authzHeaderValue = httpRequest.getAuthorization(); 143 144 if (StringUtils.isNotBlank(authzHeaderValue)) 145 accessToken = BearerAccessToken.parse(authzHeaderValue); 146 147 return new ClientRegistrationRequest(httpRequest.getURL(), metadata, accessToken); 148 } 149 }