从 Azure 密钥保管库获取秘密的 Azure Java 服务。

huangapple 未分类评论54阅读模式
英文:

Get secret from azure keyvault azure Java servlet

问题

public class KeyVaultTest {

    private static AuthenticationResult getAccessToken(String authorization, String resource) throws InterruptedException, ExecutionException, MalformedURLException {

        String clientId = "XXX"; // Client ID
        String clientSecret = "XXX";  // Client Secret

        AuthenticationResult result = null;

        // Starts a service to fetch access token.
        ExecutorService service = null;
        try {
            service = Executors.newFixedThreadPool(1);
            AuthenticationContext context = new AuthenticationContext(authorization, false, service);

            Future<AuthenticationResult> future = null;

            // Acquires token based on client ID and client secret.
            if (clientSecret != null && clientSecret != null) {
                ClientCredential credentials = new ClientCredential(clientId, clientSecret);
                future = context.acquireToken(resource, credentials, null);
            }

            result = future.get();
        } finally {
            service.shutdown();
        }

        if (result == null) {
            throw new RuntimeException("Authentication results were null.");
        }
        return result;
    }

    public static void main(String[] args) {
        String vaultBase = "https://myapp-keyvault.vault.azure.net/";

        KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultCredentials(){
            @Override
            public String doAuthenticate(String authorization, String resource, String scope) {
                String token = null;
                try {
                    AuthenticationResult authResult = getAccessToken(authorization, resource);
                    token = authResult.getAccessToken();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(token);
                return token;
            }
        });

        SecretBundle secretBundle = keyVaultClient.getSecret(vaultBase, "abc");
        System.out.println(secretBundle.value());
    }
}
英文:

I am trying to get secret from azure keyvault. When i run class independently from main method it returns secret but when i integrated this same code in servlet application at code line future.get(); here it gets blocks it do not proceed further like a deadlock it keeps waiting and sometime get
java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.List and
com.microsoft.azure.keyvault.models.KeyVaultErrorException: Status code 401, {"error":{"code":"Unauthorized","message":"AKV10001: Unable to parse JWT token: expected 3 compact JSON elements, found 1."}}
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
.Please help me on this.

public class KeyVaultTest {

private static AuthenticationResult getAccessToken(String authorization, String resource) throws InterruptedException, ExecutionException, MalformedURLException {

    String clientId = &quot;XXX&quot;; // Client ID
    String clientSecret = &quot;XXX&quot;;  //Client Secret

    AuthenticationResult result = null;

    //Starts a service to fetch access token.
    ExecutorService service = null;
    try {
        service = Executors.newFixedThreadPool(1);
        AuthenticationContext context = new AuthenticationContext(authorization, false, service);

        Future&lt;AuthenticationResult&gt; future = null;

        //Acquires token based on client ID and client secret.
        if (clientSecret != null &amp;&amp; clientSecret != null) {
            ClientCredential credentials = new ClientCredential(clientId, clientSecret);
            future = context.acquireToken(resource, credentials, null);
        }

        result = future.get();
    } finally {
        service.shutdown();
    }

    if (result == null) {
        throw new RuntimeException(&quot;Authentication results were null.&quot;);
    }
    return result;
}

public static void main(String[] args) {
	String vaultBase = &quot;https://myapp-keyvault.vault.azure.net/&quot;;
	
    

    KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultCredentials(){
        @Override
        public String doAuthenticate(String authorization, String resource, String scope) {
            String token = null;
            try {
                AuthenticationResult authResult = getAccessToken(authorization, resource);
                token = authResult.getAccessToken();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(token);
            return token;
        }
    });

    SecretBundle secretBundle = keyVaultClient.getSecret(vaultBase, &quot;abc&quot;);
    System.out.println(secretBundle.value());
           
     
   
}

}从 Azure 密钥保管库获取秘密的 Azure Java 服务。

答案1

得分: 0

如果您想在您的Servlet应用程序中访问Azure密钥保管库,请参考以下步骤:

  1. 配置Azure密钥保管库
# 创建服务主体
az ad sp create-for-rbac -n "MyApp" --password "hVFkk965BuUv" --skip-assignment --sdk-auth
# 设置访问策略
az keyvault set-policy -n <your-unique-keyvault-name> --spn <clientId-of-your-service-principal> --secret-permissions list get set delete purge
  1. 应用程序

    a. SDK依赖

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>adal4j</artifactId>
    <version>1.6.5</version>
</dependency>

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-keyvault</artifactId>
    <version>1.2.4</version>
</dependency>

b. Servlet类

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public HelloServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String appId = "42e0d080-b1f3-40cf-8db6-c4c522d988c4";
        String appSecret = "Gbx2eK64iqq_g_3NCA.ClJDfQpIjoae:";
        KeyVaultClient keyVaultClient = new KeyVaultClient(new AzureKeyVaultCredential(appId, appSecret));
        String vaultBaseUrl = "https://testsql08.vault.azure.net/";
        String secretName = "sql";
        SecretBundle secret = keyVaultClient.getSecret(vaultBaseUrl, secretName);
        System.out.println(secret.value());
        PrintWriter writer = response.getWriter();
        writer.println("<h1>Hello " + secret.value() + "</h1>");
        writer.close();
    }
}

class AzureKeyVaultCredential extends KeyVaultCredentials {
    private String appId;
    private String appSecret;

    public AzureKeyVaultCredential(String appId, String appSecret) {
        this.appId = appId;
        this.appSecret = appSecret;
    }

    @Override
    public String doAuthenticate(String authorization, String resource, String scope) {
        AuthenticationContext context = null;
        AuthenticationResult result = null;
        String token = "";

        try {
            context = new AuthenticationContext(authorization, false, Executors.newSingleThreadExecutor());

            ClientCredential credential = new ClientCredential(this.appId, this.appSecret);

            Future<AuthenticationResult> future = context.acquireToken(resource, credential, null);
            result = future.get(3, TimeUnit.MINUTES);
            token = result.getAccessToken();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return token;
    }
}
  1. 测试(我使用Tomcat 9.0.22.0运行应用程序)
    从 Azure 密钥保管库获取秘密的 Azure Java 服务。
英文:

If you want to access Azure key vault in your servlet application, please refer to the following steps

  1. Configure Azure key vault
#create service pricipal
az ad sp create-for-rbac -n &quot;MyApp&quot; --password &quot;hVFkk965BuUv&quot; --skip-assignment --sdk-auth
#set access policy
az keyvault set-policy -n &lt;your-unique-keyvault-name&gt; --spn &lt;clientId-of-your-service-principal&gt; --secret-permissions list get set delete purge
  1. Application

    a. SDK

     &lt;dependency&gt;
      &lt;groupId&gt;com.microsoft.azure&lt;/groupId&gt;
      &lt;artifactId&gt;adal4j&lt;/artifactId&gt;
      &lt;version&gt;1.6.5&lt;/version&gt;
    lt;/dependency&gt;
    
    
    lt;dependency&gt;
      &lt;groupId&gt;com.microsoft.azure&lt;/groupId&gt;
      &lt;artifactId&gt;azure-keyvault&lt;/artifactId&gt;
      &lt;version&gt;1.2.4&lt;/version&gt;
    lt;/dependency&gt;
    

    b. Servlet Class

        @WebServlet(&quot;/HelloServlet&quot;)
        public class HelloServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
        public HelloServlet() {
            super();
        }

    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String appId=&quot;42e0d080-b1f3-40cf-8db6-c4c522d988c4&quot;;
    		String appSecret=&quot;Gbx2eK64iqq_g_3NCA.ClJDfQpIjoae:&quot;;
    		KeyVaultClient keyVaultClient = new KeyVaultClient(new AzureKeyVaultCredential(appId,appSecret));
    		String vaultBaseUrl=&quot;https://testsql08.vault.azure.net/&quot;;
    		String secretName=&quot;sql&quot;;
    		SecretBundle secret =keyVaultClient.getSecret(vaultBaseUrl, secretName);
    		System.out.println(secret.value());
    		PrintWriter writer = response.getWriter();
    		writer.println(&quot;&lt;h1&gt;Hello &quot; + secret.value() + &quot;&lt;/h1&gt;&quot;);
    		writer.close();
    	}
    }
    
    class AzureKeyVaultCredential extends KeyVaultCredentials {
        private String appId;
        private String appSecret;
    
        public AzureKeyVaultCredential(String appId, String appSecret) {
            this.appId = appId;
            this.appSecret = appSecret;
        }
    
        @Override
        public String doAuthenticate(String authorization, String resource, String scope) {
            AuthenticationContext context = null;
            AuthenticationResult result = null;
            String token = &quot;&quot;;
    
            try {
                context = new AuthenticationContext(authorization, false, Executors.newSingleThreadExecutor());
    
                ClientCredential credential = new ClientCredential(this.appId, this.appSecret);
    
                Future&lt;AuthenticationResult&gt; future = context.acquireToken(resource, credential, null);
                result = future.get(3, TimeUnit.MINUTES);
                token = result.getAccessToken();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            return token;
        }
    }
  1. Test (I use Tomcat 9.0.22.0 to run the application )
    从 Azure 密钥保管库获取秘密的 Azure Java 服务。

答案2

得分: 0

你的密钥保管库很可能设置了IPv4/CIDR限制。检查你的IP地址,并确保其在限制列表中,或者确保通过批准的IP地址(VPN)路由流量。

英文:

your keyvault most likely has IPv4/CIDR restrictions. check your IP and make sure it's on that list OR make sure you route your traffic through an approved IP (VPN)

huangapple
  • 本文由 发表于 2020年6月29日 13:12:21
  • 转载请务必保留本文链接:https://java.coder-hub.com/62631614.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定