Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add persistence support for private_key_jwt client authentication #2449

Merged
merged 33 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5f72461
refactor: prepare for private_key_jwt in oauth_client_details
strehle Aug 7, 2023
bf61c5d
feature: add persistence support for private_key_jwt
strehle Aug 22, 2023
8530edc
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Aug 23, 2023
e72194a
more tests
strehle Aug 23, 2023
154589c
refactorings
strehle Aug 24, 2023
5376079
add tests
strehle Aug 24, 2023
a9cba87
Renamed
strehle Aug 24, 2023
c69b748
Renamed
strehle Aug 24, 2023
97c06aa
Renamed
strehle Aug 24, 2023
ea97594
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Aug 24, 2023
187dbb9
Add column client_jwt_config and do some refactoring for UaaClientDet…
strehle Aug 24, 2023
73599e8
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Aug 24, 2023
82a5857
Sonar findings
strehle Aug 24, 2023
bf6f7b2
cleanup
strehle Aug 24, 2023
127d570
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Aug 24, 2023
e4ea431
Merge
strehle Aug 24, 2023
415983b
Refactoring because of usage of client_jwt_config now from oauth_clie…
strehle Aug 24, 2023
62025d8
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Aug 25, 2023
aace8e0
remove not needed method.
strehle Aug 25, 2023
a7d62ac
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Sep 8, 2023
aecb645
review
strehle Sep 8, 2023
6a6403b
Merge branch 'feature/issue/2235/refactorClient' of github.com:cloudf…
strehle Sep 8, 2023
3dc5760
Merge branches 'feature/issue/2235/jwtTrustConfig' and 'develop' of g…
strehle Sep 14, 2023
4310cfd
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Sep 15, 2023
e7c0bc2
own events for jwt client configuration
strehle Sep 18, 2023
fe955c9
review
strehle Sep 18, 2023
4c1bf39
doc: Add documentation
strehle Sep 18, 2023
6650eb3
Add new scope clients.trust
strehle Sep 18, 2023
ae0654d
Merge branch 'develop' of github.com:cloudfoundry/uaa into feature/is…
strehle Sep 18, 2023
b3c3ea5
review
strehle Sep 18, 2023
2782dfa
more tests
strehle Sep 18, 2023
379fe73
sonar findings
strehle Sep 18, 2023
5a85e54
fix sonar issues
strehle Sep 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Renamed
  • Loading branch information
strehle committed Aug 24, 2023
commit a9cba87a83bc7281619d3aa105240e7dfbd22058
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import static org.cloudfoundry.identity.uaa.oauth.client.PrivateKeyChangeRequest.ChangeMode.ADD;
import static org.cloudfoundry.identity.uaa.oauth.client.ClientJwtChangeRequest.ChangeMode.ADD;

/**
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class PrivateKeyChangeRequest {
public class ClientJwtChangeRequest {

public enum ChangeMode {
UPDATE,
Expand All @@ -28,10 +28,10 @@ public enum ChangeMode {
private String clientId;
private ChangeMode changeMode = ADD;

public PrivateKeyChangeRequest() {
public ClientJwtChangeRequest() {
}

public PrivateKeyChangeRequest(String clientId, String keyUrl, String keyConfig) {
public ClientJwtChangeRequest(String clientId, String keyUrl, String keyConfig) {
this.keyUrl = keyUrl;
this.keyConfig = keyConfig;
this.clientId = clientId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@

import static org.junit.jupiter.api.Assertions.assertNotEquals;

class PrivateKeyChangeRequestTest {
class ClientJwtChangeRequestTest {

@Test
void testRequestSerialization() {
PrivateKeyChangeRequest def = new PrivateKeyChangeRequest(null, null, null);
ClientJwtChangeRequest def = new ClientJwtChangeRequest(null, null, null);
def.setKeyId("key-1");
def.setChangeMode(PrivateKeyChangeRequest.ChangeMode.DELETE);
def.setChangeMode(ClientJwtChangeRequest.ChangeMode.DELETE);
def.setKeyUrl("http://localhost:8080/uaa/token_key");
def.setKeyConfig("{}");
def.setClientId("admin");
String jsonRequest = JsonUtils.writeValueAsString(def);
PrivateKeyChangeRequest request = JsonUtils.readValue(jsonRequest, PrivateKeyChangeRequest.class);
ClientJwtChangeRequest request = JsonUtils.readValue(jsonRequest, ClientJwtChangeRequest.class);
assertNotEquals(def, request);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.cloudfoundry.identity.uaa.oauth.client.ClientConstants;
import org.cloudfoundry.identity.uaa.oauth.client.ClientDetailsCreation;
import org.cloudfoundry.identity.uaa.oauth.client.ClientDetailsModification;
import org.cloudfoundry.identity.uaa.oauth.client.PrivateKeyChangeRequest;
import org.cloudfoundry.identity.uaa.oauth.client.ClientJwtChangeRequest;
import org.cloudfoundry.identity.uaa.oauth.client.SecretChangeRequest;
import org.cloudfoundry.identity.uaa.resources.ActionResult;
import org.cloudfoundry.identity.uaa.resources.AttributeNameMapper;
Expand Down Expand Up @@ -536,9 +536,9 @@ public ActionResult changeSecret(@PathVariable String client_id, @RequestBody Se
return result;
}

@RequestMapping(value = "/oauth/clients/{client_id}/privatekey", method = RequestMethod.PUT)
@RequestMapping(value = "/oauth/clients/{client_id}/clientjwt", method = RequestMethod.PUT)
@ResponseBody
public ActionResult changePrivateKey(@PathVariable String client_id, @RequestBody PrivateKeyChangeRequest change) {
public ActionResult changeClientJwt(@PathVariable String client_id, @RequestBody ClientJwtChangeRequest change) {

ClientDetails clientDetails;
try {
Expand All @@ -560,7 +560,7 @@ public ActionResult changePrivateKey(@PathVariable String client_id, @RequestBod
case ADD :
if (change.getKey() != null) {
clientRegistrationService.addClientKeyConfig(client_id, change.getKey(), IdentityZoneHolder.get().getId(), false);
result = new ActionResult("ok", "Private key is added");
result = new ActionResult("ok", "Client jwt configuration is added");
} else {
result = new ActionResult("ok", "No key added");
}
Expand All @@ -571,12 +571,12 @@ public ActionResult changePrivateKey(@PathVariable String client_id, @RequestBod
if (clientKeyConfig != null && deleteString != null) {
clientRegistrationService.deleteClientKeyConfig(client_id, deleteString, IdentityZoneHolder.get().getId());
}
result = new ActionResult("ok", "Private key is deleted");
result = new ActionResult("ok", "Client jwt configuration is deleted");
break;

default:
clientRegistrationService.addClientKeyConfig(client_id, change.getKey(), IdentityZoneHolder.get().getId(), true);
result = new ActionResult("ok", "Private key updated");
result = new ActionResult("ok", "Client jwt configuration updated");
}
clientSecretChanges.incrementAndGet();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public String getCleanString() {
return JWKSet.parse(this.privateKeyJwt.getKeySetMap()).toString(true);
}
} catch (IllegalStateException | JsonUtils.JsonUtilException | ParseException e) {
throw new InvalidClientDetailsException("Private key configuration fails ", e);
throw new InvalidClientDetailsException("Client jwt configuration configuration fails ", e);
}
return null;
}
Expand Down Expand Up @@ -141,7 +141,7 @@ public static PrivateKeyJwtConfiguration parse(String privateKeyUrl, String priv
privateKeyJwtConfiguration = new PrivateKeyJwtConfiguration(null, JsonWebKeyHelper.deserialize(cleanJwtString));
privateKeyJwtConfiguration.validateJwkSet();
} catch (ParseException e) {
throw new InvalidClientDetailsException("Private key cannot be parsed", e);
throw new InvalidClientDetailsException("Client jwt configuration cannot be parsed", e);
}
}
return privateKeyJwtConfiguration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import org.cloudfoundry.identity.uaa.oauth.client.ClientConstants;
import org.cloudfoundry.identity.uaa.oauth.client.ClientDetailsCreation;
import org.cloudfoundry.identity.uaa.oauth.client.ClientDetailsModification;
import org.cloudfoundry.identity.uaa.oauth.client.PrivateKeyChangeRequest;
import org.cloudfoundry.identity.uaa.oauth.client.ClientJwtChangeRequest;
import org.cloudfoundry.identity.uaa.oauth.client.SecretChangeRequest;
import org.cloudfoundry.identity.uaa.resources.ActionResult;
import org.cloudfoundry.identity.uaa.resources.QueryableResourceManager;
Expand Down Expand Up @@ -1108,18 +1108,18 @@ void testAddPrivateKeyJwtConfigUri() {

when(clientDetailsService.retrieve(detail.getClientId(), IdentityZoneHolder.get().getId())).thenReturn(detail);

PrivateKeyChangeRequest change = new PrivateKeyChangeRequest();
ClientJwtChangeRequest change = new ClientJwtChangeRequest();
// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata, see jwks_uri
String jwksUri = "https://any.domain.net/openid/jwks-uri";
change.setKeyUrl(jwksUri);
change.setChangeMode(PrivateKeyChangeRequest.ChangeMode.ADD);
change.setChangeMode(ClientJwtChangeRequest.ChangeMode.ADD);

ActionResult result = endpoints.changePrivateKey(detail.getClientId(), change);
assertEquals("Private key is added", result.getMessage());
ActionResult result = endpoints.changeClientJwt(detail.getClientId(), change);
assertEquals("Client jwt configuration is added", result.getMessage());
verify(clientRegistrationService, times(1)).addClientKeyConfig(detail.getClientId(), jwksUri, IdentityZoneHolder.get().getId(), false);

change.setKeyUrl(null);
result = endpoints.changePrivateKey(detail.getClientId(), change);
result = endpoints.changeClientJwt(detail.getClientId(), change);
assertEquals("No key added", result.getMessage());
}

Expand All @@ -1131,28 +1131,28 @@ void testChangeDeletePrivateKeyJwtConfigUri() {

when(clientDetailsService.retrieve(detail.getClientId(), IdentityZoneHolder.get().getId())).thenReturn(detail);

PrivateKeyChangeRequest change = new PrivateKeyChangeRequest();
ClientJwtChangeRequest change = new ClientJwtChangeRequest();
// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata, see jwks_uri
String jwksUri = "https://any.domain.net/openid/jwks-uri";
change.setKeyUrl(jwksUri);
change.setChangeMode(PrivateKeyChangeRequest.ChangeMode.ADD);
change.setChangeMode(ClientJwtChangeRequest.ChangeMode.ADD);

ActionResult result = endpoints.changePrivateKey(detail.getClientId(), change);
assertEquals("Private key is added", result.getMessage());
ActionResult result = endpoints.changeClientJwt(detail.getClientId(), change);
assertEquals("Client jwt configuration is added", result.getMessage());
verify(clientRegistrationService, times(1)).addClientKeyConfig(detail.getClientId(), jwksUri, IdentityZoneHolder.get().getId(), false);

jwksUri = "https://any.new.domain.net/openid/jwks-uri";
change.setChangeMode(PrivateKeyChangeRequest.ChangeMode.UPDATE);
change.setChangeMode(ClientJwtChangeRequest.ChangeMode.UPDATE);
change.setKeyUrl(jwksUri);
result = endpoints.changePrivateKey(detail.getClientId(), change);
assertEquals("Private key updated", result.getMessage());
result = endpoints.changeClientJwt(detail.getClientId(), change);
assertEquals("Client jwt configuration updated", result.getMessage());
verify(clientRegistrationService, times(1)).addClientKeyConfig(detail.getClientId(), jwksUri, IdentityZoneHolder.get().getId(), true);

PrivateKeyJwtConfiguration.parse(jwksUri).writeValue(detail);
change.setChangeMode(PrivateKeyChangeRequest.ChangeMode.DELETE);
change.setChangeMode(ClientJwtChangeRequest.ChangeMode.DELETE);
change.setKeyUrl(jwksUri);
result = endpoints.changePrivateKey(detail.getClientId(), change);
assertEquals("Private key is deleted", result.getMessage());
result = endpoints.changeClientJwt(detail.getClientId(), change);
assertEquals("Client jwt configuration is deleted", result.getMessage());
verify(clientRegistrationService, times(1)).deleteClientKeyConfig(detail.getClientId(), jwksUri, IdentityZoneHolder.get().getId());
}

Expand Down