22
33import static io .quarkus .jsonp .JsonProviderHolder .jsonProvider ;
44
5+ import java .security .PublicKey ;
6+ import java .security .interfaces .ECPublicKey ;
7+ import java .security .interfaces .EdECPublicKey ;
8+ import java .security .interfaces .RSAPublicKey ;
59import java .util .List ;
610import java .util .Map ;
11+ import java .util .Set ;
712
13+ import jakarta .json .JsonArrayBuilder ;
814import jakarta .json .JsonObject ;
915import jakarta .json .JsonObjectBuilder ;
1016
17+ import org .jose4j .jwk .JsonWebKey .OutputControlLevel ;
18+ import org .jose4j .jwk .PublicJsonWebKey ;
19+ import org .jose4j .lang .JoseException ;
20+
21+ import io .quarkus .oidc .client .registration .runtime .OidcClientRegistrationException ;
1122import io .quarkus .oidc .common .runtime .AbstractJsonObject ;
1223import io .quarkus .oidc .common .runtime .OidcConstants ;
24+ import io .smallrye .jwt .algorithm .SignatureAlgorithm ;
1325
1426public class ClientMetadata extends AbstractJsonObject {
1527
@@ -100,6 +112,70 @@ public Builder postLogoutUri(String postLogoutUri) {
100112 return this ;
101113 }
102114
115+ public Builder grantType (String grantType ) {
116+ return grantTypes (Set .of (grantType ));
117+ }
118+
119+ public Builder grantTypes (Set <String > grantTypes ) {
120+ if (built ) {
121+ throw new IllegalStateException ();
122+ }
123+ JsonArrayBuilder arrayBuilder = jsonProvider ().createArrayBuilder ();
124+ for (String grantType : grantTypes ) {
125+ arrayBuilder .add (grantType );
126+ }
127+ builder .add (OidcConstants .CLIENT_METADATA_GRANT_TYPES , arrayBuilder .build ());
128+ return this ;
129+ }
130+
131+ public Builder tokenEndpointAuthMethod (String tokenEndpointAuthMethod ) {
132+ if (built ) {
133+ throw new IllegalStateException ();
134+ }
135+ builder .add (OidcConstants .CLIENT_METADATA_TOKEN_ENDPOINT_AUTH_METHOD , tokenEndpointAuthMethod );
136+ return this ;
137+ }
138+
139+ public Builder jwk (PublicKey publicKey ) {
140+ return jwks (Set .of (publicKey ));
141+ }
142+
143+ public Builder jwks (Set <PublicKey > publicKeys ) {
144+ if (built ) {
145+ throw new IllegalStateException ();
146+ }
147+ JsonArrayBuilder keysBuilder = jsonProvider ().createArrayBuilder ();
148+ for (PublicKey publicKey : publicKeys ) {
149+ JsonObjectBuilder jwkBuilder = jsonProvider ().createObjectBuilder ();
150+ for (Map .Entry <String , Object > entry : convertPublicKeyToJwk (publicKey ).entrySet ()) {
151+ jwkBuilder .add (entry .getKey (), entry .getValue ().toString ());
152+ }
153+ jwkBuilder .add ("use" , "sig" );
154+ jwkBuilder .add ("alg" , getAlgorithm (publicKey ));
155+ keysBuilder .add (jwkBuilder );
156+ }
157+ JsonObjectBuilder jwksBuilder = jsonProvider ().createObjectBuilder ();
158+ jwksBuilder .add ("keys" , keysBuilder );
159+ builder .add (OidcConstants .CLIENT_METADATA_JWKS , jwksBuilder );
160+ return this ;
161+ }
162+
163+ public Builder jwk (Map <String , String > keyProperties ) {
164+ if (built ) {
165+ throw new IllegalStateException ();
166+ }
167+ JsonArrayBuilder keysBuilder = jsonProvider ().createArrayBuilder ();
168+ JsonObjectBuilder jwkBuilder = jsonProvider ().createObjectBuilder ();
169+ for (Map .Entry <String , String > entry : keyProperties .entrySet ()) {
170+ jwkBuilder .add (entry .getKey (), entry .getValue ());
171+ }
172+ keysBuilder .add (jwkBuilder );
173+ JsonObjectBuilder jwksBuilder = jsonProvider ().createObjectBuilder ();
174+ jwksBuilder .add ("keys" , keysBuilder );
175+ builder .add (OidcConstants .CLIENT_METADATA_JWKS , jwksBuilder );
176+ return this ;
177+ }
178+
103179 public Builder extraProps (Map <String , String > extraProps ) {
104180 if (built ) {
105181 throw new IllegalStateException ();
@@ -108,6 +184,26 @@ public Builder extraProps(Map<String, String> extraProps) {
108184 return this ;
109185 }
110186
187+ private static Map <String , Object > convertPublicKeyToJwk (PublicKey key ) {
188+ try {
189+ return PublicJsonWebKey .Factory .newPublicJwk (key ).toParams (OutputControlLevel .PUBLIC_ONLY );
190+ } catch (JoseException ex ) {
191+ throw new OidcClientRegistrationException (ex );
192+ }
193+ }
194+
195+ private static String getAlgorithm (PublicKey publicKey ) {
196+ if (publicKey instanceof RSAPublicKey ) {
197+ return SignatureAlgorithm .RS256 .getAlgorithm ();
198+ } else if (publicKey instanceof ECPublicKey ) {
199+ return SignatureAlgorithm .ES256 .getAlgorithm ();
200+ } else if (publicKey instanceof EdECPublicKey ) {
201+ return SignatureAlgorithm .EDDSA .getAlgorithm ();
202+ } else {
203+ throw new OidcClientRegistrationException ("Unrecognized public key algorithm: " + publicKey .getAlgorithm ());
204+ }
205+ }
206+
111207 public ClientMetadata build () {
112208 built = true ;
113209 return new ClientMetadata (builder .build ());
0 commit comments