1818import com .nimbusds .jose .JOSEObjectType ;
1919import com .nimbusds .jose .JWSAlgorithm ;
2020import com .nimbusds .jose .JWSHeader ;
21- import com .nimbusds .jose .crypto .MACSigner ;
21+ import com .nimbusds .jose .crypto .RSASSASigner ;
22+ import com .nimbusds .jose .jwk .JWKSet ;
23+ import com .nimbusds .jose .jwk .RSAKey ;
24+ import com .nimbusds .jose .jwk .gen .RSAKeyGenerator ;
2225import com .nimbusds .jwt .JWTClaimsSet ;
2326import com .nimbusds .jwt .SignedJWT ;
2427import jakarta .ws .rs .Consumes ;
2528import jakarta .ws .rs .FormParam ;
29+ import jakarta .ws .rs .GET ;
2630import jakarta .ws .rs .POST ;
2731import jakarta .ws .rs .Path ;
2832import jakarta .ws .rs .Produces ;
5357public class AuthorizationOauth2Test {
5458
5559 private final HttpServer httpServer = new HttpServer ();
56- private final Oauth2ClientCredentialsAuthorization oauth2ClientCredentialsAuthorization = new Oauth2ClientCredentialsAuthorization () ;
60+ private Oauth2ClientCredentialsAuthorization oauth2ClientCredentialsAuthorization ;
5761 private ControlPlane controlPlane ;
58- private final Dataplane dataPlane = Dataplane .newInstance ()
59- .id ("data-plane" )
60- .registerAuthorization (oauth2ClientCredentialsAuthorization )
61- .onPrepare (dataFlow -> {
62- dataFlow .transitionToPreparing ();
63- return Result .success (dataFlow );
64- })
65- .build ();
62+ private Dataplane dataPlane ;
63+ private Oauth2TokenController tokenController ;
6664
6765 private final String clientId = UUID .randomUUID ().toString ();
6866 private final String clientSecret = UUID .randomUUID ().toString ();
6967
7068 @ BeforeEach
71- void setUp () {
69+ void setUp () throws JOSEException {
7270 httpServer .start ();
7371
72+ tokenController = new Oauth2TokenController (clientId , clientSecret );
73+ var jwksUri = "http://localhost:" + httpServer .port () + "/oauth2/jwks" ;
74+ oauth2ClientCredentialsAuthorization = new Oauth2ClientCredentialsAuthorization (jwksUri );
75+
76+ dataPlane = Dataplane .newInstance ()
77+ .id ("data-plane" )
78+ .registerAuthorization (oauth2ClientCredentialsAuthorization )
79+ .onPrepare (dataFlow -> {
80+ dataFlow .transitionToPreparing ();
81+ return Result .success (dataFlow );
82+ })
83+ .build ();
84+
7485 controlPlane = ControlPlane .newInstance ()
7586 .authorizationTokenGenerator (() -> oauth2ClientCredentialsAuthorization .authorizationHeader (oauth2AuthorizationProfile ()))
7687 .build ();
7788
7889 controlPlane .initialize (httpServer , "/data-plane" , "/data-plane" );
7990
8091 httpServer .deploy ("/data-plane" , new DataPlaneSignalingApiController (dataPlane ));
81- httpServer .deploy ("/oauth2" , new Oauth2TokenController ( clientId , clientSecret ) );
92+ httpServer .deploy ("/oauth2" , tokenController );
8293 }
8394
8495 @ AfterEach
@@ -126,13 +137,14 @@ private AuthorizationProfile oauth2AuthorizationProfile() {
126137 @ Path ("/" )
127138 public static class Oauth2TokenController {
128139
129-
130140 private final String clientId ;
131141 private final String clientSecret ;
142+ private final RSAKey rsaKey ;
132143
133- public Oauth2TokenController (String clientId , String clientSecret ) {
144+ public Oauth2TokenController (String clientId , String clientSecret ) throws JOSEException {
134145 this .clientId = clientId ;
135146 this .clientSecret = clientSecret ;
147+ this .rsaKey = new RSAKeyGenerator (2048 ).keyID ("key-1" ).generate ();
136148 }
137149
138150 @ POST
@@ -153,29 +165,35 @@ public Response token(
153165 return Response .ok (responseBody ).build ();
154166 }
155167
168+ @ GET
169+ @ Path ("/jwks" )
170+ @ Produces (APPLICATION_JSON )
171+ public Response jwks () {
172+ var jwkSet = new JWKSet (rsaKey .toPublicJWK ());
173+ return Response .ok (jwkSet .toJSONObject ()).build ();
174+ }
175+
156176 public String issueJwt (String sub ) {
157177 var now = new Date ();
158178
159179 var claimsSet = new JWTClaimsSet .Builder ()
160180 .subject (sub )
161181 .issuer ("https://your-app.com" )
162- .audience ("https://api.your-app.com" )
163- .expirationTime (new Date (now .getTime () + 1000 ))
182+ .expirationTime (new Date (now .getTime () + 60_000 ))
164183 .notBeforeTime (now )
165184 .issueTime (now )
166185 .jwtID (UUID .randomUUID ().toString ())
167186 .build ();
168187
169- var header = new JWSHeader .Builder (JWSAlgorithm .HS256 )
188+ var header = new JWSHeader .Builder (JWSAlgorithm .RS256 )
189+ .keyID (rsaKey .getKeyID ())
170190 .type (JOSEObjectType .JWT )
171191 .build ();
172192
173193 var signedJwt = new SignedJWT (header , claimsSet );
174194
175- var secret = "random-256-bit-secret-" + UUID .randomUUID ();
176195 try {
177- var signer = new MACSigner (secret .getBytes ());
178- signedJwt .sign (signer );
196+ signedJwt .sign (new RSASSASigner (rsaKey ));
179197 } catch (JOSEException e ) {
180198 throw new RuntimeException (e );
181199 }
0 commit comments