Skip to content

Commit

Permalink
Refactor verification response into a JSON web key object.
Browse files Browse the repository at this point in the history
  • Loading branch information
fhanik committed Nov 17, 2016
1 parent 4aef986 commit c752a72
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 181 deletions.
Expand Up @@ -15,24 +15,32 @@

package org.cloudfoundry.identity.uaa.oauth.jwk;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.security.PublicKey;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public abstract class JsonWebKey {
/**
* See https://tools.ietf.org/html/rfc7517
*/

@JsonDeserialize(using = JsonWebKeyDeserializer.class)
@JsonSerialize(using = JsonWebKeySerializer.class)
public class JsonWebKey {

enum KeyUse {
public enum KeyUse {
sig,
enc
}

enum KeyType {
RSA
public enum KeyType {
RSA,
MAC
}

enum KeyOperation {
public enum KeyOperation {
sign,
verify,
encrypt,
Expand All @@ -45,7 +53,7 @@ enum KeyOperation {

private final Map<String, Object> json;

protected JsonWebKey(Map<String, Object> json) {
public JsonWebKey(Map<String, Object> json) {
if (json.get("kty")==null) {
throw new IllegalArgumentException("kty field is required");
}
Expand Down Expand Up @@ -91,6 +99,12 @@ public int hashCode() {
}
}

abstract PublicKey getPublicKey();
//helper methods
public String getAlgorithm() {
return (String) getKeyProperties().get("alg");
}

public String getValue() {
return (String) getKeyProperties().get("value");
}
}
Expand Up @@ -21,31 +21,22 @@
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.cloudfoundry.identity.uaa.util.JsonUtils;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.stream.Collectors;

public class KeySetDeserializer extends JsonDeserializer<KeySet> {

/**
* See https://tools.ietf.org/html/rfc7517
*/
public class JsonWebKeyDeserializer extends JsonDeserializer<JsonWebKey> {
@Override
public KeySet deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
public JsonWebKey deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = JsonUtils.readTree(p);
ArrayNode keys = (ArrayNode) node.get("keys");
if (keys==null) {
throw new JsonParseException(p, "keys attribute cannot be null");
Map<String, Object> map = JsonUtils.getNodeAsMap(node);
if (map.get("kty")==null) {
throw new JsonParseException(p, "kty is a required attribute on a JsonWebKey");
}
LinkedHashSet<JsonWebKey> result = new LinkedHashSet<>();
for (int i=0; i<keys.size(); i++) {
Map<String, Object> map = JsonUtils.getNodeAsMap(keys.get(i));
RsaJsonWebKey key = new RsaJsonWebKey(map);
result.remove(key);
result.add(key);
}
return new KeySet(result.stream().collect(Collectors.toList()));
return new JsonWebKey(map);
}

}
Expand Up @@ -21,16 +21,20 @@
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.util.Map;

public class KeySetSerializer extends JsonSerializer<KeySet> {
/**
* See https://tools.ietf.org/html/rfc7517
*/

public class JsonWebKeySerializer extends JsonSerializer<JsonWebKey> {
@Override
public void serialize(KeySet value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
public void serialize(JsonWebKey value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeStartObject();
gen.writeArrayFieldStart("keys");
for (JsonWebKey key : value.getKeys()) {
gen.writeObject(key.getKeyProperties());
for (Map.Entry<String, Object> entry : value.getKeyProperties().entrySet()) {
gen.writeFieldName(entry.getKey());
gen.writeObject(entry.getValue());
}
gen.writeEndArray();
gen.writeEndObject();
}
}
Expand Up @@ -15,23 +15,32 @@

package org.cloudfoundry.identity.uaa.oauth.jwk;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

@JsonDeserialize(using = KeySetDeserializer.class)
@JsonSerialize(using = KeySetSerializer.class)
public class KeySet {
/**
* See https://tools.ietf.org/html/rfc7517
*/
public class JsonWebKeySet<T extends JsonWebKey> {

private final List<JsonWebKey> keys;
private final List<T> keys;

public KeySet(List<JsonWebKey> keys) {
this.keys = Collections.unmodifiableList(keys);
public JsonWebKeySet(@JsonProperty("keys") List<T> keys) {
Set<T> set = new LinkedHashSet<>();
//rules for how to override duplicates
for (T t : keys) {
set.remove(t);
set.add(t);
}
this.keys = new LinkedList(set);
}

public List<JsonWebKey> getKeys() {
return keys;
public List<T> getKeys() {
return Collections.unmodifiableList(keys);
}
}
Expand Up @@ -14,95 +14,55 @@

package org.cloudfoundry.identity.uaa.oauth.token;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKey;

import java.util.Map;

@Deprecated
/**
* Created by pivotal on 11/18/15.
* Use {@link JsonWebKey}
*/
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class VerificationKeyResponse {

@JsonProperty("kid")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String kid;

@JsonProperty("alg")
private String algorithm;

@JsonProperty("value")
private String key;

@JsonProperty("kty")
private String type;

@JsonProperty("use")
private String use;
public class VerificationKeyResponse extends JsonWebKey{

@JsonProperty("n")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String modulus;

@JsonProperty("e")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String exponent;

public String getId() {
return kid;
public VerificationKeyResponse(Map<String, Object> json) {
super(json);
}

public void setId(String kid) {
this.kid = kid;
}

public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
@JsonIgnore
public String getId() {
return getKid();
}

@JsonIgnore
public String getAlgorithm() {
return algorithm;
}

public void setKey(String key) {
this.key = key;
return (String) getKeyProperties().get("alg");
}

@JsonIgnore
public String getKey() {
return key;
}

public void setType(String type) {
this.type = type;
return (String) getKeyProperties().get("value");
}

@JsonIgnore
public String getType() {
return type;
}

public void setUse(String use) {
this.use = use;
}

public String getUse() {
return use;
return getKty().name();
}

public void setModulus(String modulus) {
this.modulus = modulus;
@JsonIgnore
public String getKeyUse() {
return getUse().name();
}

@JsonIgnore
public String getModulus() {
return modulus;
}

public void setExponent(String exponent) {
this.exponent = exponent;
return (String) getKeyProperties().get("n");
}

@JsonIgnore
public String getExponent() {
return exponent;
return (String) getKeyProperties().get("e");
}

}
Expand Down
@@ -1,35 +1,30 @@
/*
* ******************************************************************************
* Cloud Foundry Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved.
* ****************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* ******************************************************************************
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* ****************************************************************************
*/

package org.cloudfoundry.identity.uaa.oauth.token;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKeySet;

import java.util.List;

@Deprecated
/**
* Created by pivotal on 11/18/15.
* Use {@link JsonWebKeySet}
*/
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class VerificationKeysListResponse {
private List<VerificationKeyResponse> keys;

public List<VerificationKeyResponse> getKeys() {
return keys;
}

public void setKeys(List<VerificationKeyResponse> keys) {
this.keys = keys;
public class VerificationKeysListResponse extends JsonWebKeySet<VerificationKeyResponse> {
public VerificationKeysListResponse(List<VerificationKeyResponse> keys) {
super(keys);
}
}

0 comments on commit c752a72

Please sign in to comment.