Skip to content

Commit bb325c4

Browse files
feat: adds token exchange and general auth (#176)
Java SDK only does token exchange with client credentials. This PR allows token exchange or general authentication using the Nimbus Authorization Grant.
1 parent 864e9ce commit bb325c4

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

sdk/src/main/java/io/opentdf/platform/sdk/GRPCAuthInterceptor.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.nimbusds.jose.jwk.RSAKey;
66
import com.nimbusds.jwt.SignedJWT;
77
import com.nimbusds.oauth2.sdk.AuthorizationGrant;
8-
import com.nimbusds.oauth2.sdk.ClientCredentialsGrant;
98
import com.nimbusds.oauth2.sdk.ErrorObject;
109
import com.nimbusds.oauth2.sdk.TokenRequest;
1110
import com.nimbusds.oauth2.sdk.TokenResponse;
@@ -41,6 +40,7 @@ class GRPCAuthInterceptor implements ClientInterceptor {
4140
private final ClientAuthentication clientAuth;
4241
private final RSAKey rsaKey;
4342
private final URI tokenEndpointURI;
43+
private final AuthorizationGrant authzGrant;
4444
private SSLFactory sslFactory;
4545
private static final Logger logger = LoggerFactory.getLogger(GRPCAuthInterceptor.class);
4646

@@ -52,11 +52,12 @@ class GRPCAuthInterceptor implements ClientInterceptor {
5252
* @param rsaKey the RSA key to be used by the interceptor
5353
* @param sslFactory Optional SSLFactory for Requests
5454
*/
55-
public GRPCAuthInterceptor(ClientAuthentication clientAuth, RSAKey rsaKey, URI tokenEndpointURI, SSLFactory sslFactory) {
55+
public GRPCAuthInterceptor(ClientAuthentication clientAuth, RSAKey rsaKey, URI tokenEndpointURI, AuthorizationGrant authzGrant, SSLFactory sslFactory) {
5656
this.clientAuth = clientAuth;
5757
this.rsaKey = rsaKey;
5858
this.tokenEndpointURI = tokenEndpointURI;
5959
this.sslFactory = sslFactory;
60+
this.authzGrant = authzGrant;
6061
}
6162

6263
/**
@@ -110,12 +111,9 @@ private synchronized AccessToken getToken() {
110111

111112
logger.trace("The current access token is expired or empty, getting a new one");
112113

113-
// Construct the client credentials grant
114-
AuthorizationGrant clientGrant = new ClientCredentialsGrant();
115-
116114
// Make the token request
117115
TokenRequest tokenRequest = new TokenRequest(this.tokenEndpointURI,
118-
clientAuth, clientGrant, null);
116+
clientAuth, authzGrant, null);
119117
HTTPRequest httpRequest = tokenRequest.toHTTPRequest();
120118
if(sslFactory!=null){
121119
httpRequest.setSSLSocketFactory(sslFactory.getSslSocketFactory());

sdk/src/main/java/io/opentdf/platform/sdk/SDKBuilder.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
import com.nimbusds.jose.jwk.KeyUse;
55
import com.nimbusds.jose.jwk.RSAKey;
66
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
7+
import com.nimbusds.oauth2.sdk.AuthorizationGrant;
8+
import com.nimbusds.oauth2.sdk.ClientCredentialsGrant;
79
import com.nimbusds.oauth2.sdk.GeneralException;
810
import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
911
import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
1012
import com.nimbusds.oauth2.sdk.auth.Secret;
1113
import com.nimbusds.oauth2.sdk.id.ClientID;
1214
import com.nimbusds.oauth2.sdk.id.Issuer;
15+
import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
16+
import com.nimbusds.oauth2.sdk.token.TokenTypeURI;
17+
import com.nimbusds.oauth2.sdk.tokenexchange.TokenExchangeGrant;
1318
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
1419
import io.grpc.*;
1520
import io.opentdf.platform.wellknownconfiguration.GetWellKnownConfigurationRequest;
@@ -41,6 +46,7 @@ public class SDKBuilder {
4146
private ClientAuthentication clientAuth = null;
4247
private Boolean usePlainText;
4348
private SSLFactory sslFactory;
49+
private AuthorizationGrant authzGrant;
4450

4551
private static final Logger logger = LoggerFactory.getLogger(SDKBuilder.class);
4652

@@ -49,6 +55,7 @@ public static SDKBuilder newBuilder() {
4955
builder.usePlainText = false;
5056
builder.clientAuth = null;
5157
builder.platformEndpoint = null;
58+
builder.authzGrant = null;
5259

5360
return builder;
5461
}
@@ -99,6 +106,24 @@ public SDKBuilder platformEndpoint(String platformEndpoint) {
99106
return this;
100107
}
101108

109+
public SDKBuilder authorizationGrant(AuthorizationGrant authzGrant) {
110+
if (this.authzGrant != null) {
111+
throw new RuntimeException("Authorization grant can't be specified twice");
112+
}
113+
this.authzGrant = authzGrant;
114+
return this;
115+
}
116+
117+
public SDKBuilder tokenExchange(String jwt) {
118+
if (this.authzGrant != null) {
119+
throw new RuntimeException("Authorization grant can't be specified twice");
120+
}
121+
122+
BearerAccessToken token = new BearerAccessToken(jwt);
123+
this.authzGrant = new TokenExchangeGrant(token, TokenTypeURI.ACCESS_TOKEN);
124+
return this;
125+
}
126+
102127
public SDKBuilder clientSecret(String clientID, String clientSecret) {
103128
ClientID cid = new ClientID(clientID);
104129
Secret cs = new Secret(clientSecret);
@@ -168,7 +193,11 @@ private GRPCAuthInterceptor getGrpcAuthInterceptor(RSAKey rsaKey) {
168193
throw new SDKException("Error resolving the OIDC provider metadata", e);
169194
}
170195

171-
return new GRPCAuthInterceptor(clientAuth, rsaKey, providerMetadata.getTokenEndpointURI(), sslFactory);
196+
if (this.authzGrant == null) {
197+
this.authzGrant = new ClientCredentialsGrant();
198+
}
199+
200+
return new GRPCAuthInterceptor(clientAuth, rsaKey, providerMetadata.getTokenEndpointURI(), this.authzGrant, sslFactory);
172201
}
173202

174203
static class ServicesAndInternals {

0 commit comments

Comments
 (0)