Skip to content

Commit 7191f47

Browse files
committed
UY-1488 support Key ID in oAuth tokens
1 parent 57d80df commit 7191f47

File tree

5 files changed

+43
-1
lines changed

5 files changed

+43
-1
lines changed

oauth/src/main/java/pl/edu/icm/unity/oauth/as/TokenSigner.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import pl.edu.icm.unity.base.exceptions.EngineException;
3232
import pl.edu.icm.unity.base.exceptions.InternalException;
3333
import pl.edu.icm.unity.engine.api.PKIManagement;
34+
import pl.edu.icm.unity.oauth.as.token.KeyIdExtractor;
3435

3536
/**
3637
* Wrapper for {@link JWSSigner}. Can signs token using RSA, EC or HMAC algorithm.
@@ -192,6 +193,10 @@ public SignedJWT sign(JWTClaimsSet claims, String type) throws JOSEException
192193
if (!isPKIEnabled())
193194
throw new InternalException("Token signer is not initialized");
194195
JWSHeader.Builder jwsHeaderBuilder = new JWSHeader.Builder(algorithm);
196+
if (credential != null)
197+
{
198+
jwsHeaderBuilder.keyID(KeyIdExtractor.getKeyId(getCredentialCertificate()));
199+
}
195200
if (type != null)
196201
jwsHeaderBuilder.type(new JOSEObjectType(type));
197202
SignedJWT ret = new SignedJWT(jwsHeaderBuilder.build(), claims);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) 2021 Bixbit - Krzysztof Benedyczak. All rights reserved.
3+
* See LICENCE.txt file for licensing information.
4+
*/
5+
6+
package pl.edu.icm.unity.oauth.as.token;
7+
8+
import java.security.cert.X509Certificate;
9+
10+
public class KeyIdExtractor
11+
{
12+
public static String getKeyId(X509Certificate cert)
13+
{
14+
return cert.getSerialNumber()
15+
.toString(10);
16+
}
17+
18+
}

oauth/src/main/java/pl/edu/icm/unity/oauth/as/token/KeysResource.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ public String getKeys()
5656
{
5757
set = new JWKSet(new RSAKey.Builder((RSAPublicKey) config.getTokenSigner().getCredentialCertificate().getPublicKey())
5858
.keyUse(KeyUse.SIGNATURE)
59+
.keyID(KeyIdExtractor.getKeyId(config.getTokenSigner().getCredentialCertificate()))
5960
.x509CertChain(getCertAsX5CAttribute(config.getTokenSigner().getCredentialCertificateChain()))
6061
.build());
6162
} else if (Family.EC.contains(signAlg))
6263
{
6364
set = new JWKSet(new ECKey.Builder(Curve.forJWSAlgorithm(signAlg).iterator().next(),
6465
(ECPublicKey) config.getTokenSigner().getCredentialCertificate().getPublicKey())
66+
.keyID(KeyIdExtractor.getKeyId(config.getTokenSigner().getCredentialCertificate()))
6567
.keyUse(KeyUse.SIGNATURE)
6668
.x509CertChain(getCertAsX5CAttribute(config.getTokenSigner().getCredentialCertificateChain()))
6769
.build());

oauth/src/test/java/pl/edu/icm/unity/oauth/as/DiscoveryResourceTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import static org.junit.jupiter.api.Assertions.assertEquals;
99
import static org.junit.jupiter.api.Assertions.assertTrue;
10+
import static org.assertj.core.api.Assertions.assertThat;
1011
import static org.mockito.Mockito.mock;
1112

1213
import java.util.HashSet;
@@ -22,6 +23,7 @@
2223
import com.nimbusds.oauth2.sdk.ParseException;
2324
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
2425

26+
import pl.edu.icm.unity.oauth.as.OAuthASProperties.AccessTokenFormat;
2527
import pl.edu.icm.unity.oauth.as.token.DiscoveryResource;
2628
import pl.edu.icm.unity.oauth.as.token.KeysResource;
2729

@@ -49,15 +51,18 @@ public void testDiscovery() throws ParseException
4951
assertEquals(7, parsed.getResponseTypes().size());
5052
}
5153

54+
@Test
5255
public void testJWK() throws java.text.ParseException
5356
{
54-
OAuthASProperties config = OAuthTestUtils.getConfig();
57+
OAuthASProperties config = OAuthTestUtils.getOIDCConfig();
58+
config.setProperty(OAuthASProperties.ACCESS_TOKEN_FORMAT, AccessTokenFormat.JWT.name());
5559
KeysResource keysResource = new KeysResource(config);
5660
String keys = keysResource.getKeys();
5761
JWKSet parsedKeys = JWKSet.parse(keys);
5862
assertEquals(1, parsedKeys.getKeys().size());
5963
JWK key = parsedKeys.getKeys().get(0);
6064
assertEquals(KeyType.RSA, key.getKeyType());
65+
assertThat(key.getKeyID()).isNotEmpty();
6166
}
6267

6368
}

oauth/src/test/java/pl/edu/icm/unity/oauth/as/token/access/AccessTokenFactoryTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ public void shouldVerifySignatureOfJWT() throws Exception
146146
jwt.verify(verifier);
147147
}
148148

149+
@Test
150+
public void shouldAddKidToJWTToken() throws OAuthErrorException, ParseException
151+
{
152+
AccessTokenFactory factory = getFactory(AccessTokenFormat.JWT);
153+
154+
AccessToken accessToken = factory.create(getFakeToken(), new Date(1000));
155+
156+
assertThat(isJWTToken(accessToken)).isTrue();
157+
SignedJWT jwt = SignedJWT.parse(accessToken.getValue());
158+
assertThat(jwt.getHeader().getKeyID()).isNotEmpty();
159+
160+
}
149161

150162
private boolean isJWTToken(AccessToken accessToken)
151163
{

0 commit comments

Comments
 (0)