001 package com.nimbusds.openid.connect.sdk.rp; 002 003 import com.nimbusds.oauth2.sdk.ParseException; 004 import com.nimbusds.oauth2.sdk.auth.Secret; 005 import com.nimbusds.oauth2.sdk.client.ClientUpdateRequest; 006 import com.nimbusds.oauth2.sdk.http.HTTPRequest; 007 import com.nimbusds.oauth2.sdk.id.ClientID; 008 import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 009 import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 010 import java.net.URL; 011 import net.jcip.annotations.Immutable; 012 import net.minidev.json.JSONObject; 013 import org.apache.commons.lang3.StringUtils; 014 015 016 /** 017 * OpenID Connect client registration request. This class is immutable. 018 * 019 * Note that the update operation is not specified in OpenID Connect Dynamic 020 * Client Registration. 021 * 022 * <p>Example HTTP request: 023 * 024 * <pre> 025 * PUT /register/s6BhdRkqt3 HTTP/1.1 026 * Accept: application/json 027 * Host: server.example.com 028 * Authorization: Bearer reg-23410913-abewfq.123483 029 * 030 * { 031 * "client_id" :"s6BhdRkqt3", 032 * "client_secret" : "cf136dc3c1fc93f31185e5885805d", 033 * "redirect_uris" : ["https://client.example.org/callback", "https://client.example.org/alt"], 034 * "scope" : "read write dolphin", 035 * "grant_types" : ["authorization_code", "refresh_token"] 036 * "token_endpoint_auth_method" : "client_secret_basic", 037 * "jwks_uri" : "https://client.example.org/my_public_keys.jwks" 038 * "client_name" : "My New Example", 039 * "client_name#fr" : "Mon Nouvel Exemple", 040 * "logo_uri" : "https://client.example.org/newlogo.png" 041 * "logo_uri#fr" : "https://client.example.org/fr/newlogo.png" 042 * } 043 * 044 * </pre> 045 * 046 * <p>Related specifications: 047 * 048 * <ul> 049 * <li>OAuth 2.0 Dynamic Client Registration Protocol 050 * (draft-ietf-oauth-dyn-reg-12), section 4.3. 051 * </ul> 052 * 053 * @author Vladimir Dzhuvinov 054 */ 055 @Immutable 056 public final class OIDCClientUpdateRequest extends ClientUpdateRequest { 057 058 059 /** 060 * Creates a new OpenID Connect client update request. 061 * 062 * @param uri The URI of the client update endpoint. May be 063 * {@code null} if the {@link #toHTTPRequest()} 064 * method will not be used. 065 * @param accessToken The client registration access token. Must not be 066 * {@code null}. 067 * @param metadata The client metadata. Must not be {@code null} and 068 * must specify one or more redirect URIs. 069 * @param secret The optional client secret, {@code null} if not 070 * specified. 071 */ 072 public OIDCClientUpdateRequest(final URL uri, 073 final ClientID id, 074 final BearerAccessToken accessToken, 075 final OIDCClientMetadata metadata, 076 final Secret secret) { 077 078 super(uri, id, accessToken, metadata, secret); 079 } 080 081 082 /** 083 * Gets the associated OpenID Connect client metadata. 084 * 085 * @return The OpenID Connect client metadata. 086 */ 087 public OIDCClientMetadata getOIDCClientMetadata() { 088 089 return (OIDCClientMetadata)getClientMetadata(); 090 } 091 092 093 /** 094 * Parses an OpenID Connect client update request from the specified 095 * HTTP PUT request. 096 * 097 * @param httpRequest The HTTP request. Must not be {@code null}. 098 * 099 * @return The OpenID Connect client update request. 100 * 101 * @throws ParseException If the HTTP request couldn't be parsed to an 102 * OpenID Connect client update request. 103 */ 104 public static ClientUpdateRequest parse(final HTTPRequest httpRequest) 105 throws ParseException { 106 107 httpRequest.ensureMethod(HTTPRequest.Method.PUT); 108 109 String authzHeaderValue = httpRequest.getAuthorization(); 110 111 if (StringUtils.isBlank(authzHeaderValue)) 112 throw new ParseException("Missing HTTP Authorization header"); 113 114 BearerAccessToken accessToken = BearerAccessToken.parse(authzHeaderValue); 115 116 JSONObject jsonObject = httpRequest.getQueryAsJSONObject(); 117 118 ClientID id = new ClientID(JSONObjectUtils.getString(jsonObject, "client_id")); 119 120 OIDCClientMetadata metadata = OIDCClientMetadata.parse(jsonObject); 121 122 Secret clientSecret = null; 123 124 if (jsonObject.get("client_secret") != null) 125 clientSecret = new Secret(JSONObjectUtils.getString(jsonObject, "client_secret")); 126 127 128 return new OIDCClientUpdateRequest(httpRequest.getURL(), id, accessToken, metadata, clientSecret); 129 } 130 }