All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nimbusds.oauth2.sdk.client.ClientRegistrationRequest Maven / Gradle / Ivy

package com.nimbusds.oauth2.sdk.client;


import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import net.jcip.annotations.Immutable;

import org.apache.commons.lang3.StringUtils;

import net.minidev.json.JSONObject;

import com.nimbusds.jose.JWSObject;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.ProtectedResourceRequest;
import com.nimbusds.oauth2.sdk.SerializeException;
import com.nimbusds.oauth2.sdk.http.CommonContentTypes;
import com.nimbusds.oauth2.sdk.http.HTTPRequest;
import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;


/**
 * Client registration request.
 *
 * 

Example HTTP request: * *

 * POST /register HTTP/1.1
 * Content-Type: application/json
 * Accept: application/json
 * Authorization: Bearer ey23f2.adfj230.af32-developer321
 * Host: server.example.com
 *
 * {
 *   "redirect_uris"              : [ "https://client.example.org/callback",
 *                                    "https://client.example.org/callback2" ],
 *   "client_name"                : "My Example Client",
 *   "client_name#ja-Jpan-JP"     : "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D",
 *   "token_endpoint_auth_method" : "client_secret_basic",
 *   "scope"                      : "read write dolphin",
 *   "logo_uri"                   : "https://client.example.org/logo.png",
 *   "jwks_uri"                   : "https://client.example.org/my_public_keys.jwks"
 * }
 * 
* *

Example HTTP request with a software statement: * *

 * POST /register HTTP/1.1
 * Content-Type: application/json
 * Accept: application/json
 * Host: server.example.com
 *
 * {
 *   "redirect_uris"               : [ "https://client.example.org/callback",
 *                                     "https://client.example.org/callback2" ],
 *   "software_statement"          : "eyJhbGciOiJFUzI1NiJ9.eyJpc3Mi[...omitted for brevity...]",
 *   "scope"                       : "read write",
 *   "example_extension_parameter" : "example_value"
 * }
 *
 * 
* *

Related specifications: * *

    *
  • OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591), sections * 2 and 3.1. *
*/ @Immutable public class ClientRegistrationRequest extends ProtectedResourceRequest { /** * The client metadata. */ private final ClientMetadata metadata; /** * The optional software statement. */ private final SignedJWT softwareStatement; /** * Creates a new client registration request. * * @param uri The URI of the client registration endpoint. May * be {@code null} if the {@link #toHTTPRequest()} * method will not be used. * @param metadata The client metadata. Must not be {@code null} and * must specify one or more redirection URIs. * @param accessToken An OAuth 2.0 Bearer access token for the request, * {@code null} if none. */ public ClientRegistrationRequest(final URI uri, final ClientMetadata metadata, final BearerAccessToken accessToken) { this(uri, metadata, null, accessToken); } /** * Creates a new client registration request with an optional software * statement. * * @param uri The URI of the client registration * endpoint. May be {@code null} if the * {@link #toHTTPRequest()} method will not be * used. * @param metadata The client metadata. Must not be * {@code null} and must specify one or more * redirection URIs. * @param softwareStatement Optional software statement, as a signed * JWT with an {@code iss} claim; {@code null} * if not specified. * @param accessToken An OAuth 2.0 Bearer access token for the * request, {@code null} if none. */ public ClientRegistrationRequest(final URI uri, final ClientMetadata metadata, final SignedJWT softwareStatement, final BearerAccessToken accessToken) { super(uri, accessToken); if (metadata == null) throw new IllegalArgumentException("The client metadata must not be null"); this.metadata = metadata; if (softwareStatement != null) { if (softwareStatement.getState() == JWSObject.State.UNSIGNED) { throw new IllegalArgumentException("The software statement JWT must be signed"); } JWTClaimsSet claimsSet; try { claimsSet = softwareStatement.getJWTClaimsSet(); } catch (java.text.ParseException e) { throw new IllegalArgumentException("The software statement is not a valid signed JWT: " + e.getMessage()); } if (claimsSet.getIssuer() == null) { // http://tools.ietf.org/html/rfc7591#section-2.3 throw new IllegalArgumentException("The software statement JWT must contain an 'iss' claim"); } } this.softwareStatement = softwareStatement; } /** * Gets the associated client metadata. * * @return The client metadata. */ public ClientMetadata getClientMetadata() { return metadata; } /** * Gets the software statement. * * @return The software statement, as a signed JWT with an {@code iss} * claim; {@code null} if not specified. */ public SignedJWT getSoftwareStatement() { return softwareStatement; } @Override public HTTPRequest toHTTPRequest() { if (getEndpointURI() == null) throw new SerializeException("The endpoint URI is not specified"); URL endpointURL; try { endpointURL = getEndpointURI().toURL(); } catch (MalformedURLException e) { throw new SerializeException(e.getMessage(), e); } HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, endpointURL); if (getAccessToken() != null) { httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader()); } httpRequest.setContentType(CommonContentTypes.APPLICATION_JSON); JSONObject content = metadata.toJSONObject(); if (softwareStatement != null) { // Signed state check done in constructor content.put("software_statement", softwareStatement.serialize()); } httpRequest.setQuery(content.toString()); return httpRequest; } /** * Parses a client registration request from the specified HTTP POST * request. * * @param httpRequest The HTTP request. Must not be {@code null}. * * @return The client registration request. * * @throws ParseException If the HTTP request couldn't be parsed to a * client registration request. */ public static ClientRegistrationRequest parse(final HTTPRequest httpRequest) throws ParseException { httpRequest.ensureMethod(HTTPRequest.Method.POST); // Get the JSON object content JSONObject jsonObject = httpRequest.getQueryAsJSONObject(); // Extract the software statement if any SignedJWT stmt = null; if (jsonObject.containsKey("software_statement")) { try { stmt = SignedJWT.parse(JSONObjectUtils.getString(jsonObject, "software_statement")); } catch (java.text.ParseException e) { throw new ParseException("Invalid software statement JWT: " + e.getMessage()); } // Prevent the JWT from appearing in the metadata jsonObject.remove("software_statement"); } // Parse the client metadata ClientMetadata metadata = ClientMetadata.parse(jsonObject); // Parse the optional bearer access token BearerAccessToken accessToken = null; String authzHeaderValue = httpRequest.getAuthorization(); if (StringUtils.isNotBlank(authzHeaderValue)) accessToken = BearerAccessToken.parse(authzHeaderValue); try { URI endpointURI = httpRequest.getURL().toURI(); return new ClientRegistrationRequest(endpointURI, metadata, stmt, accessToken); } catch (URISyntaxException | IllegalArgumentException e) { throw new ParseException(e.getMessage(), e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy