当前位置: 首页 > 知识库问答 >
问题:

从Azure keyvault AzureJavaservlet获取秘密

仉成益
2023-03-14

我想从天蓝色密钥库获取秘密。当我独立于主方法运行类时,它返回秘密,但当我在代码行future.get()处集成了这个相同的代码在servlet应用程序中;在这里它得到块,它不会像死锁一样继续前进,它一直在等待,有时会得到java.util.concurrent.执行异常:java.lang.ClassCastExctive:java.lang.字符串不能被强制转换为java.util.列表和com.microsoft.azure.keyvault.models.KeyVaultError异常:状态代码401,{"错误":{"代码":"未授权","消息":"AKV10001:无法解析JWT令牌:预期3个紧凑型JSON元素,找到1."}}在sun.reflect.NativeConstrtorAccessorImpl.newInstance0(本机方法)。请帮我做这件事。

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());
           
     
   
}

共有2个答案

公西季
2023-03-14

您的keyvault很可能有IPv4/CIDR限制。检查你的IP,确保它在列表中,或者确保你的流量通过一个经批准的IP(VPN)路由

蔚和风
2023-03-14

如果要在servlet应用程序中访问Azure key vault,请参考以下步骤

  1. 配置Azure密钥保管库
#create service pricipal
az ad sp create-for-rbac -n "MyApp" --password "hVFkk965BuUv" --skip-assignment --sdk-auth
#set access policy
az keyvault set-policy -n <your-unique-keyvault-name> --spn <clientId-of-your-service-principal> --secret-permissions list get set delete purge

应用

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;
        }
    }
 类似资料:
  • 我需要阅读Azure active directory中的用户列表。客户已经创建了一个Graph API应用程序,但他们不想共享应用程序的客户机密,而是要求我们使用密钥库。如何从节点访问。js应用程序检索用户列表的密钥是什么? 我尝试了下面的一个,但给出了错误,我不知道如何验证。

  • 在图表部署CI/CD管道期间,有没有办法从GCP机密管理器中检索掌舵图表的机密?还是最好使用CI/CD secret manager,然后为图表部署获取凭据?

  • 我正在尝试将https://docs.microsoft.com/en-us/Azure/key-vault/tutorial-net-create-vault-azure-web-app中的示例代码转换为VB.net,并使用它访问我存储在Azure密钥库中的秘密。我在http://converter.telerik.com/使用了转换器。 转换后的代码出现一个错误:“委托'KeyVaultCli

  • 问题内容: 我的集群服务器坏了(Linux系统错误),可惜它只是一个节点。 我阅读了https://docs.docker.com/v17.09/engine/swarm/admin_guide/#back-up-the- swarm 所以我尝试在新设置的docker服务器上备份和还原它,如下所示: 新的docker守护程序可以在没有任何群集功能的情况下正常运行,但是群集功能不能像以下那样工作:

  • 我想知道是否可以通过前缀获得所有Azure密钥库的秘密。 假设我有3个秘密。 我希望得到所有的秘密与前缀pre,并序列化到JSON。在未来,我将有更多的秘密与前缀,所以我不想阅读的秘密手动。因此,当我添加一个带有前缀的新秘密时,我的函数也将返回一个新值的JSON。 问题是:是否可以通过前缀从Azure密钥库获取秘密并动态序列化到JSON? 更新:我想在ASP.NET Core3.1和C#中使用它。