001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.openid.connect.sdk.rp; 019 020 021import com.nimbusds.jwt.SignedJWT; 022import com.nimbusds.oauth2.sdk.ParseException; 023import com.nimbusds.oauth2.sdk.client.ClientRegistrationRequest; 024import com.nimbusds.oauth2.sdk.http.HTTPRequest; 025import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 026import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 027import com.nimbusds.oauth2.sdk.util.StringUtils; 028import net.jcip.annotations.Immutable; 029import net.minidev.json.JSONObject; 030 031import java.net.URI; 032 033 034/** 035 * OpenID Connect client registration request. 036 * 037 * <p>Example HTTP request: 038 * 039 * <pre> 040 * POST /connect/register HTTP/1.1 041 * Content-Type: application/json 042 * Accept: application/json 043 * Host: server.example.com 044 * Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJ ... 045 * 046 * { 047 * "application_type" : "web", 048 * "redirect_uris" : [ "https://client.example.org/callback", 049 * "https://client.example.org/callback2" ], 050 * "client_name" : "My Example", 051 * "client_name#ja-Jpan-JP" : "クライアント名", 052 * "logo_uri" : "https://client.example.org/logo.png", 053 * "subject_type" : "pairwise", 054 * "sector_identifier_uri" : "https://other.example.net/file_of_redirect_uris.json", 055 * "token_endpoint_auth_method" : "client_secret_basic", 056 * "jwks_uri" : "https://client.example.org/my_public_keys.jwks", 057 * "userinfo_encrypted_response_alg" : "RSA1_5", 058 * "userinfo_encrypted_response_enc" : "A128CBC-HS256", 059 * "contacts" : [ "[email protected]", "[email protected]" ], 060 * "request_uris" : [ "https://client.example.org/rf.txt#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA" ] 061 * } 062 * </pre> 063 * 064 * <p>Related specifications: 065 * 066 * <ul> 067 * <li>OpenID Connect Dynamic Client Registration 1.0 068 * <li>OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591) 069 * </ul> 070 */ 071@Immutable 072public class OIDCClientRegistrationRequest extends ClientRegistrationRequest { 073 074 075 /** 076 * Creates a new OpenID Connect client registration request. 077 * 078 * @param endpoint The URI of the client registration endpoint. May 079 * be {@code null} if the {@link #toHTTPRequest()} 080 * method is not going to be used. 081 * @param metadata The OpenID Connect client metadata. Must not be 082 * {@code null} and must specify one or more 083 * redirection URIs. 084 * @param accessToken An OAuth 2.0 Bearer access token for the request, 085 * {@code null} if none. 086 */ 087 public OIDCClientRegistrationRequest(final URI endpoint, 088 final OIDCClientMetadata metadata, 089 final BearerAccessToken accessToken) { 090 091 super(endpoint, metadata, accessToken); 092 } 093 094 095 /** 096 * Creates a new OpenID Connect client registration request with an 097 * optional software statement. 098 * 099 * @param endpoint The URI of the client registration 100 * endpoint. May be {@code null} if the 101 * {@link #toHTTPRequest()} method is not 102 * going to be used. 103 * @param metadata The OpenID Connect client metadata. Must 104 * not be {@code null} and must specify one or 105 * more redirection URIs. 106 * @param softwareStatement Optional software statement, as a signed 107 * JWT with an {@code iss} claim; {@code null} 108 * if not specified. 109 * @param accessToken An OAuth 2.0 Bearer access token for the 110 * request, {@code null} if none. 111 */ 112 public OIDCClientRegistrationRequest(final URI endpoint, 113 final OIDCClientMetadata metadata, 114 final SignedJWT softwareStatement, 115 final BearerAccessToken accessToken) { 116 117 super(endpoint, metadata, softwareStatement, accessToken); 118 } 119 120 121 /** 122 * Gets the associated OpenID Connect client metadata. 123 * 124 * @return The OpenID Connect client metadata. 125 */ 126 public OIDCClientMetadata getOIDCClientMetadata() { 127 128 return (OIDCClientMetadata)getClientMetadata(); 129 } 130 131 132 /** 133 * Parses an OpenID Connect client registration request from the 134 * specified HTTP POST request. 135 * 136 * @param httpRequest The HTTP request. Must not be {@code null}. 137 * 138 * @return The OpenID Connect client registration request. 139 * 140 * @throws ParseException If the HTTP request couldn't be parsed to an 141 * OpenID Connect client registration request. 142 */ 143 public static OIDCClientRegistrationRequest parse(final HTTPRequest httpRequest) 144 throws ParseException { 145 146 httpRequest.ensureMethod(HTTPRequest.Method.POST); 147 148 // Get the JSON object content 149 JSONObject jsonObject = httpRequest.getBodyAsJSONObject(); 150 151 // Extract the software statement if any 152 SignedJWT stmt = null; 153 154 if (jsonObject.containsKey("software_statement")) { 155 156 try { 157 stmt = SignedJWT.parse(JSONObjectUtils.getNonBlankString(jsonObject, "software_statement")); 158 159 } catch (java.text.ParseException e) { 160 161 throw new ParseException("Invalid software statement JWT: " + e.getMessage()); 162 } 163 164 // Prevent the JWT from appearing in the metadata 165 jsonObject.remove("software_statement"); 166 } 167 168 // Parse the client metadata 169 OIDCClientMetadata metadata = OIDCClientMetadata.parse(jsonObject); 170 171 // Parse the optional bearer access token 172 BearerAccessToken accessToken = null; 173 174 String authzHeaderValue = httpRequest.getAuthorization(); 175 176 if (StringUtils.isNotBlank(authzHeaderValue)) 177 accessToken = BearerAccessToken.parse(authzHeaderValue); 178 179 URI endpointURI = httpRequest.getURI(); 180 181 try { 182 return new OIDCClientRegistrationRequest(endpointURI, metadata, stmt, accessToken); 183 } catch (IllegalArgumentException e) { 184 throw new ParseException(e.getMessage(), e); 185 } 186 } 187}