added client dynamic registration service, extracted clientdetails<->json processing into its own static class
parent
0b0e52b7a3
commit
fb859fc39a
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.openid.connect.ClientDetailsEntityJsonProcessor;
|
||||
import org.mitre.openid.connect.client.service.ClientConfigurationService;
|
||||
import org.mitre.openid.connect.config.ServerConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
public class DynamicRegistrationClientConfigurationService implements ClientConfigurationService {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(DynamicServerConfigurationService.class);
|
||||
|
||||
private LoadingCache<ServerConfiguration, ClientDetailsEntity> clients;
|
||||
|
||||
private ClientDetailsEntity template;
|
||||
|
||||
public DynamicRegistrationClientConfigurationService() {
|
||||
clients = CacheBuilder.newBuilder().build(new DynamicClientRegistrationLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientDetails getClientConfiguration(ServerConfiguration issuer) {
|
||||
try {
|
||||
return clients.get(issuer);
|
||||
} catch (ExecutionException e) {
|
||||
logger.warn("Unable to get client configuration", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the template
|
||||
*/
|
||||
public ClientDetailsEntity getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template the template to set
|
||||
*/
|
||||
public void setTemplate(ClientDetailsEntity template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public class DynamicClientRegistrationLoader extends CacheLoader<ServerConfiguration, ClientDetailsEntity> {
|
||||
private HttpClient httpClient = new DefaultHttpClient();
|
||||
private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||
private JsonParser parser = new JsonParser();
|
||||
|
||||
@Override
|
||||
public ClientDetailsEntity load(ServerConfiguration serverConfig) throws Exception {
|
||||
RestTemplate restTemplate = new RestTemplate(httpFactory);
|
||||
|
||||
// dynamically register this client
|
||||
JsonObject jsonRequest = ClientDetailsEntityJsonProcessor.serialize(template, null, null);
|
||||
|
||||
/*
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Content-type", "application/json");
|
||||
headers.add("Accept", "application/json");
|
||||
*/
|
||||
|
||||
String registered = restTemplate.postForObject(serverConfig.getRegistrationEndpointUri(), jsonRequest.toString(), String.class);
|
||||
// TODO: handle HTTP errors
|
||||
|
||||
// TODO: save registration token and other important bits
|
||||
ClientDetailsEntity client = ClientDetailsEntityJsonProcessor.parse(registered);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.mitre.openid.connect;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.mitre.jose.JWEAlgorithmEmbed;
|
||||
import org.mitre.jose.JWEEncryptionMethodEmbed;
|
||||
import org.mitre.jose.JWSAlgorithmEmbed;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType;
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
public class ClientDetailsEntityJsonProcessor {
|
||||
|
||||
private static Gson gson = new Gson();
|
||||
private static JsonParser parser = new JsonParser();
|
||||
|
||||
/**
|
||||
*
|
||||
* Create an unbound ClientDetailsEntity from the given JSON string.
|
||||
*
|
||||
* @param jsonString
|
||||
* @return the entity if successful, null otherwise
|
||||
*/
|
||||
public static ClientDetailsEntity parse(String jsonString) {
|
||||
JsonElement jsonEl = parser.parse(jsonString);
|
||||
if (jsonEl.isJsonObject()) {
|
||||
|
||||
JsonObject o = jsonEl.getAsJsonObject();
|
||||
ClientDetailsEntity c = new ClientDetailsEntity();
|
||||
|
||||
// TODO: make these field names into constants
|
||||
|
||||
// these two fields should only be sent in the update request, and MUST match existing values
|
||||
c.setClientId(getAsString(o, "client_id"));
|
||||
c.setClientSecret(getAsString(o, "client_secret"));
|
||||
|
||||
// OAuth DynReg
|
||||
c.setRedirectUris(getAsStringSet(o, "redirect_uris"));
|
||||
c.setClientName(getAsString(o, "client_name"));
|
||||
c.setClientUri(getAsString(o, "client_uri"));
|
||||
c.setLogoUri(getAsString(o, "logo_uri"));
|
||||
c.setContacts(getAsStringSet(o, "contacts"));
|
||||
c.setTosUri(getAsString(o, "tos_uri"));
|
||||
|
||||
String authMethod = getAsString(o, "token_endpoint_auth_method");
|
||||
if (authMethod != null) {
|
||||
c.setTokenEndpointAuthMethod(AuthMethod.getByValue(authMethod));
|
||||
}
|
||||
|
||||
// scope is a space-separated string
|
||||
String scope = getAsString(o, "scope");
|
||||
if (scope != null) {
|
||||
c.setScope(Sets.newHashSet(Splitter.on(" ").split(scope)));
|
||||
}
|
||||
|
||||
c.setGrantTypes(getAsStringSet(o, "grant_types"));
|
||||
c.setPolicyUri(getAsString(o, "policy_uri"));
|
||||
c.setJwksUri(getAsString(o, "jwks_uri"));
|
||||
|
||||
|
||||
// OIDC Additions
|
||||
String appType = getAsString(o, "application_type");
|
||||
if (appType != null) {
|
||||
c.setApplicationType(AppType.getByValue(appType));
|
||||
}
|
||||
|
||||
c.setSectorIdentifierUri(getAsString(o, "sector_identifier_uri"));
|
||||
|
||||
String subjectType = getAsString(o, "subject_type");
|
||||
if (subjectType != null) {
|
||||
c.setSubjectType(SubjectType.getByValue(subjectType));
|
||||
}
|
||||
|
||||
c.setRequestObjectSigningAlg(getAsJwsAlgorithm(o, "request_object_signing_alg"));
|
||||
|
||||
c.setUserInfoSignedResponseAlg(getAsJwsAlgorithm(o, "userinfo_signed_response_alg"));
|
||||
c.setUserInfoEncryptedResponseAlg(getAsJweAlgorithm(o, "userinfo_encrypted_response_alg"));
|
||||
c.setUserInfoEncryptedResponseEnc(getAsJweEncryptionMethod(o, "userinfo_encrypted_response_enc"));
|
||||
|
||||
c.setIdTokenSignedResponseAlg(getAsJwsAlgorithm(o, "id_token_signed_response_alg"));
|
||||
c.setIdTokenEncryptedResponseAlg(getAsJweAlgorithm(o, "id_token_encrypted_response_alg"));
|
||||
c.setIdTokenEncryptedResponseEnc(getAsJweEncryptionMethod(o, "id_token_encrypted_response_enc"));
|
||||
|
||||
if (o.has("default_max_age")) {
|
||||
if (o.get("default_max_age").isJsonPrimitive()) {
|
||||
c.setDefaultMaxAge(o.get("default_max_age").getAsInt());
|
||||
}
|
||||
}
|
||||
|
||||
if (o.has("require_auth_time")) {
|
||||
if (o.get("require_auth_time").isJsonPrimitive()) {
|
||||
c.setRequireAuthTime(o.get("require_auth_time").getAsBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
c.setDefaultACRvalues(getAsStringSet(o, "default_acr_values"));
|
||||
c.setInitiateLoginUri(getAsString(o, "initiate_login_uri"));
|
||||
c.setPostLogoutRedirectUri(getAsString(o, "post_logout_redirect_uri"));
|
||||
c.setRequestUris(getAsStringSet(o, "request_uris"));
|
||||
|
||||
return c;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonElement getAsArray(Set<String> value) {
|
||||
return gson.toJsonTree(value, new TypeToken<Set<String>>(){}.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param c
|
||||
* @param token
|
||||
* @param registrationUri
|
||||
* @return
|
||||
*/
|
||||
public static JsonObject serialize(ClientDetailsEntity c, OAuth2AccessTokenEntity token, String registrationUri) {
|
||||
JsonObject o = new JsonObject();
|
||||
|
||||
o.addProperty("client_id", c.getClientId());
|
||||
if (c.getClientSecret() != null) {
|
||||
o.addProperty("client_secret", c.getClientSecret());
|
||||
o.addProperty("expires_at", 0); // TODO: do we want to let secrets expire?
|
||||
}
|
||||
|
||||
if (c.getCreatedAt() != null) {
|
||||
o.addProperty("issued_at", c.getCreatedAt().getTime());
|
||||
}
|
||||
if (token != null) {
|
||||
o.addProperty("registration_access_token", token.getValue());
|
||||
}
|
||||
|
||||
if (registrationUri != null) {
|
||||
o.addProperty("registration_client_uri", registrationUri);
|
||||
}
|
||||
|
||||
|
||||
// add in all other client properties
|
||||
|
||||
// OAuth DynReg
|
||||
o.add("redirect_uris", getAsArray(c.getRedirectUris()));
|
||||
o.addProperty("client_name", c.getClientName());
|
||||
o.addProperty("client_uri", c.getClientUri());
|
||||
o.addProperty("logo_uri", c.getLogoUri());
|
||||
o.add("contacts", getAsArray(c.getContacts()));
|
||||
o.addProperty("tos_uri", c.getTosUri());
|
||||
o.addProperty("token_endpoint_auth_method", c.getTokenEndpointAuthMethod() != null ? c.getTokenEndpointAuthMethod().getValue() : null);
|
||||
o.addProperty("scope", c.getScope() != null ? Joiner.on(" ").join(c.getScope()) : null);
|
||||
o.add("grant_types", getAsArray(c.getGrantTypes()));
|
||||
o.addProperty("policy_uri", c.getPolicyUri());
|
||||
o.addProperty("jwks_uri", c.getJwksUri());
|
||||
|
||||
// OIDC Registration
|
||||
o.addProperty("application_type", c.getApplicationType() != null ? c.getApplicationType().getValue() : null);
|
||||
o.addProperty("sector_identifier_uri", c.getSectorIdentifierUri());
|
||||
o.addProperty("subject_type", c.getSubjectType() != null ? c.getSubjectType().getValue() : null);
|
||||
o.addProperty("request_object_signing_alg", c.getRequestObjectSigningAlg() != null ? c.getRequestObjectSigningAlg().getAlgorithmName() : null);
|
||||
o.addProperty("userinfo_signed_response_alg", c.getUserInfoSignedResponseAlg() != null ? c.getUserInfoSignedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("userinfo_encrypted_response_alg", c.getUserInfoEncryptedResponseAlg() != null ? c.getUserInfoEncryptedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("userinfo_encrypted_response_enc", c.getUserInfoEncryptedResponseEnc() != null ? c.getUserInfoEncryptedResponseEnc().getAlgorithmName() : null);
|
||||
o.addProperty("id_token_signed_response_alg", c.getIdTokenSignedResponseAlg() != null ? c.getIdTokenSignedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("id_token_encrypted_response_alg", c.getIdTokenEncryptedResponseAlg() != null ? c.getIdTokenEncryptedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("id_token_encrypted_response_enc", c.getIdTokenEncryptedResponseEnc() != null ? c.getIdTokenEncryptedResponseEnc().getAlgorithmName() : null);
|
||||
o.addProperty("default_max_age", c.getDefaultMaxAge());
|
||||
o.addProperty("require_auth_time", c.getRequireAuthTime());
|
||||
o.add("default_acr_values", getAsArray(c.getDefaultACRvalues()));
|
||||
o.addProperty("initiate_login_uri", c.getInitiateLoginUri());
|
||||
o.addProperty("post_logout_redirect_uri", c.getPostLogoutRedirectUri());
|
||||
o.add("request_uris", getAsArray(c.getRequestUris()));
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a JWE Algorithm, null if it doesn't exist
|
||||
*/
|
||||
public static JWEAlgorithmEmbed getAsJweAlgorithm(JsonObject o, String member) {
|
||||
String s = getAsString(o, member);
|
||||
if (s != null) {
|
||||
return JWEAlgorithmEmbed.getForAlgorithmName(s);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a JWE Encryption Method, null if it doesn't exist
|
||||
*/
|
||||
public static JWEEncryptionMethodEmbed getAsJweEncryptionMethod(JsonObject o, String member) {
|
||||
String s = getAsString(o, member);
|
||||
if (s != null) {
|
||||
return JWEEncryptionMethodEmbed.getForAlgorithmName(s);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a JWS Algorithm, null if it doesn't exist
|
||||
*/
|
||||
public static JWSAlgorithmEmbed getAsJwsAlgorithm(JsonObject o, String member) {
|
||||
String s = getAsString(o, member);
|
||||
if (s != null) {
|
||||
return JWSAlgorithmEmbed.getForAlgorithmName(s);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a string, null if it doesn't exist
|
||||
*/
|
||||
public static String getAsString(JsonObject o, String member) {
|
||||
if (o.has(member)) {
|
||||
JsonElement e = o.get(member);
|
||||
if (e != null && e.isJsonPrimitive()) {
|
||||
return e.getAsString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given given member as a set of strings, null if it doesn't exist
|
||||
*/
|
||||
public static Set<String> getAsStringSet(JsonObject o, String member) throws JsonSyntaxException {
|
||||
if (o.has(member)) {
|
||||
return gson.fromJson(o.get(member), new TypeToken<Set<String>>(){}.getType());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -6,23 +6,20 @@ package org.mitre.openid.connect.view;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
import org.mitre.openid.connect.ClientDetailsEntityJsonProcessor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -53,57 +50,9 @@ public class ClientInformationResponseView extends AbstractView {
|
|||
code = HttpStatus.OK;
|
||||
}
|
||||
|
||||
JsonObject o = new JsonObject();
|
||||
|
||||
o.addProperty("client_id", c.getClientId());
|
||||
if (c.getClientSecret() != null) {
|
||||
o.addProperty("client_secret", c.getClientSecret());
|
||||
o.addProperty("expires_at", 0); // TODO: do we want to let secrets expire?
|
||||
}
|
||||
|
||||
if (c.getCreatedAt() != null) {
|
||||
o.addProperty("issued_at", c.getCreatedAt().getTime());
|
||||
}
|
||||
|
||||
o.addProperty("registration_access_token", token.getValue());
|
||||
|
||||
// TODO: urlencode the client id for safety?
|
||||
String uri = request.getRequestURL() + "/" + c.getClientId();
|
||||
o.addProperty("registration_client_uri", uri);
|
||||
|
||||
|
||||
// add in all other client properties
|
||||
|
||||
// OAuth DynReg
|
||||
o.add("redirect_uris", getAsArray(c.getRedirectUris()));
|
||||
o.addProperty("client_name", c.getClientName());
|
||||
o.addProperty("client_uri", c.getClientUri());
|
||||
o.addProperty("logo_uri", c.getLogoUri());
|
||||
o.add("contacts", getAsArray(c.getContacts()));
|
||||
o.addProperty("tos_uri", c.getTosUri());
|
||||
o.addProperty("token_endpoint_auth_method", c.getTokenEndpointAuthMethod() != null ? c.getTokenEndpointAuthMethod().getValue() : null);
|
||||
o.addProperty("scope", c.getScope() != null ? Joiner.on(" ").join(c.getScope()) : null);
|
||||
o.add("grant_types", getAsArray(c.getGrantTypes()));
|
||||
o.addProperty("policy_uri", c.getPolicyUri());
|
||||
o.addProperty("jwks_uri", c.getJwksUri());
|
||||
|
||||
// OIDC Registration
|
||||
o.addProperty("application_type", c.getApplicationType() != null ? c.getApplicationType().getValue() : null);
|
||||
o.addProperty("sector_identifier_uri", c.getSectorIdentifierUri());
|
||||
o.addProperty("subject_type", c.getSubjectType() != null ? c.getSubjectType().getValue() : null);
|
||||
o.addProperty("request_object_signing_alg", c.getRequestObjectSigningAlg() != null ? c.getRequestObjectSigningAlg().getAlgorithmName() : null);
|
||||
o.addProperty("userinfo_signed_response_alg", c.getUserInfoSignedResponseAlg() != null ? c.getUserInfoSignedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("userinfo_encrypted_response_alg", c.getUserInfoEncryptedResponseAlg() != null ? c.getUserInfoEncryptedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("userinfo_encrypted_response_enc", c.getUserInfoEncryptedResponseEnc() != null ? c.getUserInfoEncryptedResponseEnc().getAlgorithmName() : null);
|
||||
o.addProperty("id_token_signed_response_alg", c.getIdTokenSignedResponseAlg() != null ? c.getIdTokenSignedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("id_token_encrypted_response_alg", c.getIdTokenEncryptedResponseAlg() != null ? c.getIdTokenEncryptedResponseAlg().getAlgorithmName() : null);
|
||||
o.addProperty("id_token_encrypted_response_enc", c.getIdTokenEncryptedResponseEnc() != null ? c.getIdTokenEncryptedResponseEnc().getAlgorithmName() : null);
|
||||
o.addProperty("default_max_age", c.getDefaultMaxAge());
|
||||
o.addProperty("require_auth_time", c.getRequireAuthTime());
|
||||
o.add("default_acr_values", getAsArray(c.getDefaultACRvalues()));
|
||||
o.addProperty("initiate_login_uri", c.getInitiateLoginUri());
|
||||
o.addProperty("post_logout_redirect_uri", c.getPostLogoutRedirectUri());
|
||||
o.add("request_uris", getAsArray(c.getRequestUris()));
|
||||
JsonObject o = ClientDetailsEntityJsonProcessor.serialize(c, token, uri);
|
||||
|
||||
try {
|
||||
Writer out = response.getWriter();
|
||||
|
@ -117,9 +66,5 @@ public class ClientInformationResponseView extends AbstractView {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
private JsonElement getAsArray(Set<String> value) {
|
||||
return gson.toJsonTree(value, new TypeToken<Set<String>>(){}.getType());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,18 +5,14 @@ package org.mitre.openid.connect.web;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.mitre.jose.JWEAlgorithmEmbed;
|
||||
import org.mitre.jose.JWEEncryptionMethodEmbed;
|
||||
import org.mitre.jose.JWSAlgorithmEmbed;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType;
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
import org.mitre.oauth2.model.SystemScope;
|
||||
import org.mitre.oauth2.service.ClientDetailsEntityService;
|
||||
import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
||||
import org.mitre.oauth2.service.SystemScopeService;
|
||||
import org.mitre.openid.connect.ClientDetailsEntityJsonProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -34,14 +30,9 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = "register")
|
||||
|
@ -57,8 +48,6 @@ public class ClientDynamicRegistrationEndpoint {
|
|||
private SystemScopeService scopeService;
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ClientDynamicRegistrationEndpoint.class);
|
||||
private JsonParser parser = new JsonParser();
|
||||
private Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* Create a new Client, issue a client ID, and create a registration access token.
|
||||
|
@ -70,7 +59,7 @@ public class ClientDynamicRegistrationEndpoint {
|
|||
@RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
|
||||
public String registerNewClient(@RequestBody String jsonString, Model m) {
|
||||
|
||||
ClientDetailsEntity newClient = parse(jsonString);
|
||||
ClientDetailsEntity newClient = ClientDetailsEntityJsonProcessor.parse(jsonString);
|
||||
|
||||
if (newClient != null) {
|
||||
// it parsed!
|
||||
|
@ -203,7 +192,7 @@ public class ClientDynamicRegistrationEndpoint {
|
|||
public String updateClient(@PathVariable("id") String clientId, @RequestBody String jsonString, Model m, OAuth2Authentication auth) {
|
||||
|
||||
|
||||
ClientDetailsEntity newClient = parse(jsonString);
|
||||
ClientDetailsEntity newClient = ClientDetailsEntityJsonProcessor.parse(jsonString);
|
||||
ClientDetailsEntity oldClient = clientService.loadClientByClientId(clientId);
|
||||
|
||||
if (newClient != null && oldClient != null // we have an existing client and the new one parsed
|
||||
|
@ -301,159 +290,6 @@ public class ClientDynamicRegistrationEndpoint {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Create an unbound ClientDetailsEntity from the given JSON string.
|
||||
*
|
||||
* @param jsonString
|
||||
* @return the entity if successful, null otherwise
|
||||
*/
|
||||
private ClientDetailsEntity parse(String jsonString) {
|
||||
JsonElement jsonEl = parser.parse(jsonString);
|
||||
if (jsonEl.isJsonObject()) {
|
||||
|
||||
JsonObject o = jsonEl.getAsJsonObject();
|
||||
ClientDetailsEntity c = new ClientDetailsEntity();
|
||||
|
||||
// TODO: make these field names into constants
|
||||
|
||||
// these two fields should only be sent in the update request, and MUST match existing values
|
||||
c.setClientId(getAsString(o, "client_id"));
|
||||
c.setClientSecret(getAsString(o, "client_secret"));
|
||||
|
||||
// OAuth DynReg
|
||||
c.setRedirectUris(getAsStringSet(o, "redirect_uris"));
|
||||
c.setClientName(getAsString(o, "client_name"));
|
||||
c.setClientUri(getAsString(o, "client_uri"));
|
||||
c.setLogoUri(getAsString(o, "logo_uri"));
|
||||
c.setContacts(getAsStringSet(o, "contacts"));
|
||||
c.setTosUri(getAsString(o, "tos_uri"));
|
||||
|
||||
String authMethod = getAsString(o, "token_endpoint_auth_method");
|
||||
if (authMethod != null) {
|
||||
c.setTokenEndpointAuthMethod(AuthMethod.getByValue(authMethod));
|
||||
}
|
||||
|
||||
// scope is a space-separated string
|
||||
String scope = getAsString(o, "scope");
|
||||
if (scope != null) {
|
||||
c.setScope(Sets.newHashSet(Splitter.on(" ").split(scope)));
|
||||
}
|
||||
|
||||
c.setGrantTypes(getAsStringSet(o, "grant_types"));
|
||||
c.setPolicyUri(getAsString(o, "policy_uri"));
|
||||
c.setJwksUri(getAsString(o, "jwks_uri"));
|
||||
|
||||
|
||||
// OIDC Additions
|
||||
String appType = getAsString(o, "application_type");
|
||||
if (appType != null) {
|
||||
c.setApplicationType(AppType.getByValue(appType));
|
||||
}
|
||||
|
||||
c.setSectorIdentifierUri(getAsString(o, "sector_identifier_uri"));
|
||||
|
||||
String subjectType = getAsString(o, "subject_type");
|
||||
if (subjectType != null) {
|
||||
c.setSubjectType(SubjectType.getByValue(subjectType));
|
||||
}
|
||||
|
||||
c.setRequestObjectSigningAlg(getAsJwsAlgorithm(o, "request_object_signing_alg"));
|
||||
|
||||
c.setUserInfoSignedResponseAlg(getAsJwsAlgorithm(o, "userinfo_signed_response_alg"));
|
||||
c.setUserInfoEncryptedResponseAlg(getAsJweAlgorithm(o, "userinfo_encrypted_response_alg"));
|
||||
c.setUserInfoEncryptedResponseEnc(getAsJweEncryptionMethod(o, "userinfo_encrypted_response_enc"));
|
||||
|
||||
c.setIdTokenSignedResponseAlg(getAsJwsAlgorithm(o, "id_token_signed_response_alg"));
|
||||
c.setIdTokenEncryptedResponseAlg(getAsJweAlgorithm(o, "id_token_encrypted_response_alg"));
|
||||
c.setIdTokenEncryptedResponseEnc(getAsJweEncryptionMethod(o, "id_token_encrypted_response_enc"));
|
||||
|
||||
if (o.has("default_max_age")) {
|
||||
if (o.get("default_max_age").isJsonPrimitive()) {
|
||||
c.setDefaultMaxAge(o.get("default_max_age").getAsInt());
|
||||
}
|
||||
}
|
||||
|
||||
if (o.has("require_auth_time")) {
|
||||
if (o.get("require_auth_time").isJsonPrimitive()) {
|
||||
c.setRequireAuthTime(o.get("require_auth_time").getAsBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
c.setDefaultACRvalues(getAsStringSet(o, "default_acr_values"));
|
||||
c.setInitiateLoginUri(getAsString(o, "initiate_login_uri"));
|
||||
c.setPostLogoutRedirectUri(getAsString(o, "post_logout_redirect_uri"));
|
||||
c.setRequestUris(getAsStringSet(o, "request_uris"));
|
||||
|
||||
return c;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given given member as a set of strings, null if it doesn't exist
|
||||
*/
|
||||
private Set<String> getAsStringSet(JsonObject o, String member) throws JsonSyntaxException {
|
||||
if (o.has(member)) {
|
||||
return gson.fromJson(o.get(member), new TypeToken<Set<String>>(){}.getType());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a string, null if it doesn't exist
|
||||
*/
|
||||
private String getAsString(JsonObject o, String member) {
|
||||
if (o.has(member)) {
|
||||
JsonElement e = o.get(member);
|
||||
if (e != null && e.isJsonPrimitive()) {
|
||||
return e.getAsString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a JWS Algorithm, null if it doesn't exist
|
||||
*/
|
||||
private JWSAlgorithmEmbed getAsJwsAlgorithm(JsonObject o, String member) {
|
||||
String s = getAsString(o, member);
|
||||
if (s != null) {
|
||||
return JWSAlgorithmEmbed.getForAlgorithmName(s);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a JWE Algorithm, null if it doesn't exist
|
||||
*/
|
||||
private JWEAlgorithmEmbed getAsJweAlgorithm(JsonObject o, String member) {
|
||||
String s = getAsString(o, member);
|
||||
if (s != null) {
|
||||
return JWEAlgorithmEmbed.getForAlgorithmName(s);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of the given member as a JWE Encryption Method, null if it doesn't exist
|
||||
*/
|
||||
private JWEEncryptionMethodEmbed getAsJweEncryptionMethod(JsonObject o, String member) {
|
||||
String s = getAsString(o, member);
|
||||
if (s != null) {
|
||||
return JWEEncryptionMethodEmbed.getForAlgorithmName(s);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param client
|
||||
* @return
|
||||
|
|
Loading…
Reference in New Issue