Class KeyVaultCredentials

  • All Implemented Interfaces:
    com.microsoft.rest.credentials.ServiceClientCredentials

    public abstract class KeyVaultCredentials
    extends Object
    implements com.microsoft.rest.credentials.ServiceClientCredentials
    An implementation of ServiceClientCredentials that supports automatic bearer token refresh.
    • Constructor Detail

      • KeyVaultCredentials

        public KeyVaultCredentials()
    • Method Detail

      • applyCredentialsFilter

        public void applyCredentialsFilter​(okhttp3.OkHttpClient.Builder clientBuilder)
        Specified by:
        applyCredentialsFilter in interface com.microsoft.rest.credentials.ServiceClientCredentials
      • doAuthenticate

        public String doAuthenticate​(String authorization,
                                     String resource,
                                     String scope)
        Abstract method to be implemented.
        Parameters:
        authorization - Identifier of the authority, a URL.
        resource - Identifier of the target resource that is the recipient of the requested token, a URL.
        scope - The scope of the authentication request.
        Returns:
        AuthenticationResult with authorization token and PoP key. Answers a server challenge with a token header.

        Implementations typically use ADAL to get a token, as performed in the sample below:

         @Override
         public String doAuthenticate(String authorization, String resource, String scope) {
             String clientId = ...; // client GUID as shown in Azure portal.
             String clientKey = ...; // client key as provided by Azure portal.
             AuthenticationResult token = getAccessTokenFromClientCredentials(authorization, resource, clientId, clientKey);
             return token.getAccessToken();;
         }
        
         private static AuthenticationResult getAccessTokenFromClientCredentials(String authorization, String resource, String clientId, String clientKey) {
             AuthenticationContext context = null;
             AuthenticationResult result = null;
             ExecutorService service = null;
             try {
                 service = Executors.newFixedThreadPool(1);
                 context = new AuthenticationContext(authorization, false, service);
                 ClientCredential credentials = new ClientCredential(clientId, clientKey);
                 Future<AuthenticationResult> future = context.acquireToken(resource, credentials, null);
                 result = future.get();
             } catch (Exception e) {
                 throw new RuntimeException(e);
             } finally {
                 service.shutdown();
             }
        
             if (result == null) {
                 throw new RuntimeException("authentication result was null");
             }
             return result;
         }
                 

        Note: The client key must be securely stored. It's advised to use two client applications - one for development and other for production - managed by separate parties.

      • doAuthenticate

        public AuthenticationResult doAuthenticate​(String authorization,
                                                   String resource,
                                                   String scope,
                                                   String schema)
        Method to be implemented.
        Parameters:
        authorization - Identifier of the authority, a URL.
        resource - Identifier of the target resource that is the recipient of the requested token, a URL.
        scope - The scope of the authentication request.
        schema - Authentication schema. Can be 'pop' or 'bearer'.
        Returns:
        AuthenticationResult with authorization token and PoP key. Answers a server challenge with a token header.

        Implementations sends POST request to receive authentication token like in example below. ADAL currently doesn't support POP authentication.

                 public AuthenticationResult doAuthenticate(String authorization, String resource, String scope, String schema) {
                     JsonWebKey clientJwk = GenerateJsonWebKey();
                     JsonWebKey clientPublicJwk = GetJwkWithPublicKeyOnly(clientJwk);
                     String token = GetAccessToken(authorization, resource, "pop".equals(schema), clientPublicJwk);
        
                     return new AuthenticationResult(token, clientJwk.toString());
                 }
        
                 private JsonWebKey GenerateJsonWebKey() {
                     final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
                     generator.initialize(2048);
                     KeyPair clientRsaKeyPair = generator.generateKeyPair();
                     JsonWebKey result = JsonWebKey.fromRSA(clientRsaKeyPair);
                     result.withKid(UUID.randomUUID().toString());
                     return result;
                 }
        
                 public static JsonWebKey GetJwkWithPublicKeyOnly(JsonWebKey jwk) {
                     KeyPair publicOnly = jwk.toRSA(false);
                     JsonWebKey jsonkeyPublic = JsonWebKey.fromRSA(publicOnly);
                     jsonkeyPublic.withKid(jwk.kid());
                     jsonkeyPublic.withKeyOps(Arrays.asList(JsonWebKeyOperation.ENCRYPT, JsonWebKeyOperation.WRAP_KEY,
                             JsonWebKeyOperation.VERIFY));
                     return jsonkeyPublic;
                 }
        
                 private String GetAccessToken(String authorization, String resource, boolean supportspop, JsonWebKey jwkPublic) {
                     CloseableHttpClient httpclient = HttpClients.createDefault();
                     HttpPost httppost = new HttpPost(authorization + "/oauth2/token");
         
                     // Request parameters and other properties.
                     List<NameValuePair> params = new ArrayList<NameValuePair>(2);
                     params.add(new BasicNameValuePair("resource", resource));
                     params.add(new BasicNameValuePair("response_type", "token"));
                     params.add(new BasicNameValuePair("grant_type", "client_credentials"));
                     params.add(new BasicNameValuePair("client_id", this.getApplicationId()));
                     params.add(new BasicNameValuePair("client_secret", this.getApplicationSecret()));
        
                     if (supportspop) {
                         params.add(new BasicNameValuePair("pop_jwk", jwkPublic.toString()));
                     }
        
                     httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        
                     HttpResponse response = httpclient.execute(httppost);
                     HttpEntity entity = response.getEntity();
        
                     // Read the contents of an entity and return it as a String.
                     String content = EntityUtils.toString(entity);
        
                     ObjectMapper mapper = new ObjectMapper();
                     authreply reply = mapper.readValue(content, authreply.class);
        
                     return reply.access_token;
                 }
                 

        Note: The client key must be securely stored. It's advised to use two client applications - one for development and other for production - managed by separate parties.