/** * Copyright Microsoft Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.microsoft.azure.storage.util; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.apache.http.Header; import org.apache.http.message.BasicHeader; import com.microsoft.aad.adal4j.AuthenticationContext; import com.microsoft.aad.adal4j.AuthenticationResult; import com.microsoft.aad.adal4j.ClientCredential; import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials; import com.microsoft.windowsazure.core.pipeline.filter.ServiceRequestContext; /** * A class that stores KeyVault credentials and knows how to respond to * authentication challenges. See KeyVaultCredentials for more information. */ public class KVCredentials extends KeyVaultCredentials { private String authClientID; // Note: It's very important, in a real application, to keep this secure. private String authClientSecret; /** * Constructs a new KVCredentials object. * * @param clientID * The ClientID for this application * @param clientSecret * The client secret for this application */ public KVCredentials(String clientID, String clientSecret) { this.authClientID = clientID; this.authClientSecret = clientSecret; } /** * Actually do the authentication. This method will be called by the super * class. * * @param request * The request being sent * @param challenge * Information about the challenge from the service. */ @Override public Header doAuthenticate(ServiceRequestContext request, Map<String, String> challenge) { String authorization = challenge.get("authorization"); String resource = challenge.get("resource"); String clientId = this.authClientID; String clientKey = this.authClientSecret; AuthenticationResult token = getAccessTokenFromClientCredentials( authorization, resource, clientId, clientKey); return new BasicHeader("Authorization", token.getAccessTokenType() + " " + token.getAccessToken()); } /** * Creates the access token * * @param authorization * The authorization from the service * @param resource * The resource being accessed * @param clientId * The ClientID for this application * @param clientKey * The Client Secret for this application * @return The access token to use to authenticate to the service */ 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; } }