【问题标题】:How do I find an Azure policy definition by name using the Java SDK?如何使用 Java SDK 按名称查找 Azure 策略定义?
【发布时间】:2025-12-21 17:00:07
【问题描述】:

Azure 的策略服务带有许多内置策略。可以使用 Azure 的 Java SDK 和 Azure 资源管理器访问它们。可以使用getByName()method in the SDK获取具体策略的定义。

代码如下所示:

AzureResourceManager azureResourceManager = AzureResourceManager
        .authenticate(credential, profile)
        .withSubscription("<my-subscription-id>");       
PolicyDefinition policyDefinition = azureResourceManager.policyDefinitions().getByName("<name>");

为了测试这段代码,我去控制台找到了一个预建策略的名称。我找到了两个不同的名字,一个在文中:

和定义中的不同:

但是,尝试使用这些名称中的任何一个来检索策略定义都会导致相同的错误:

Status code 404, The policy definition 'Audit VMs that do not use managed disks' could not be found.

Status code 404, The policy definition '06a78e20-9358-41c9-923c-fb736d382a4d' could not be found

问题:这个方法要找什么名字?或者有没有更好的方法来检索策略定义?

【问题讨论】:

  • 名称是“06a78e20-9358-41c9-923c-fb736d382a4d”,您应该在代码中使用它。另一个名称是显示名称。但是我对java不熟悉,你应该打开fiddler查看详细错误,也可以选择使用相关apiPolicy Definitions - Get Built In
  • 感谢您的评论,但正如我在问题中解释的那样,该名称会导致上述错误。您提供的链接适用于 REST API,而不是 Java API。
  • 是的,它不是 java api。我的意思是你可以通过使用 REST API 来尝试它,然后打开 fiddler 来检查请求的详细信息。然后在使用您的 java 代码时也使用 fiddler 检查请求详细信息。最后,您可以比较这 2 个请求,看看是否有任何差异。

标签: java azure azure-resource-manager azure-policy


【解决方案1】:

如果你想在java应用程序中获得一个build_in策略,你可以使用com.azure.resourcemanager.resources包中的PolicyClientImpl.getPolicyDefinitions().getBuiltIn()方法。此外,请注意内置策略的名称是指南。

例如

  1. 安装 SDK
<dependency>
    <groupId>com.azure.resourcemanager</groupId>
    <artifactId>azure-resourcemanager-resources</artifactId>
    <version>2.1.0</version>
</dependency>
  1. 代码
String clientId="";
        String clientSecret="";
        String tenant="";
        String subId="";
        AzureProfile profile = new AzureProfile(tenant,subId, AzureEnvironment.AZURE);
        TokenCredential credential = new ClientSecretCredentialBuilder()
                .clientId(clientId)
                .clientSecret(clientSecret)
                .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint())
                .tenantId(tenant)
                .build();
        PolicyClientImpl policyClient= new PolicyClientBuilder()
                .pipeline(HttpPipelineProvider.buildHttpPipeline(credential,profile))
                .endpoint(profile.getEnvironment().getResourceManagerEndpoint())
                .subscriptionId(profile.getSubscriptionId())
                .buildClient();

        PolicyDefinitionInner policy = policyClient.getPolicyDefinitions().getBuiltIn("04d53d87-841c-4f23-8a5b-21564380b55e");
        System.out.println(policy.policyType());
        System.out.println(policy.description());

【讨论】:

    【解决方案2】:

    最后,当我知道是策略定义名称时,我最终使用 REST API 来获取策略定义。请注意,我必须使用一个调用来获取内置策略,而另一个调用来获取自定义策略,这很痛苦,因为我事先不知道我拥有哪种类型。我使用OkHttpClient 来处理繁重的工作。这是我的解决方案:

    Boolean itMightBeACustomPolicy = false;
    OkHttpClient builtinPolicyDefinitionHttpClient = new OkHttpClient();
    
    String builtinPolicyDefinitionUrl = "https://management.azure.com/providers/Microsoft.Authorization/policyDefinitions/" 
            + policyState.getString("policyDefinitionName") // This is what I know
            + "?api-version=2020-09-01";
    
    Request builtinPolicyDefinitionRequest = new Request.Builder()
        .url(builtinPolicyDefinitionUrl)
        .addHeader("Authorization", "Bearer " + token)
        .get()
        .build();
    
    String policyDefinitionJson = "";
    try
    {
        Response builtinPolicyDefinitionResponse = builtinPolicyDefinitionHttpClient.newCall(builtinPolicyDefinitionRequest).execute();
        if(builtinPolicyDefinitionResponse.isSuccessful())
        {
            // It's a built-in policy definition
            policyDefinitionJson = builtinPolicyDefinitionResponse.body().string();
        }
        else
        {
            // Let's try for a custom definition
            // I do this separately to keep the try..catch unique.
            itMightBeACustomPolicy = true;
        }
    }
    catch (IOException e)
    {
        e.printStackTrace(); // TODO Handle this...
    }  
    
    if(itMightBeACustomPolicy)
    {
        OkHttpClient customPolicyDefinitionHttpClient = new OkHttpClient();
    
        String customPolicyDefinitionUrl = "https://management.azure.com/subscriptions/" 
                + subscriptionId 
                + "/providers/Microsoft.Authorization/policyDefinitions/" 
                + policyState.getString("policyDefinitionName") // This is what I know
                + "?api-version=2020-09-01";
    
        Request customPolicyDefinitionRequest = new Request.Builder()
            .url(customPolicyDefinitionUrl)
            .addHeader("Authorization", "Bearer " + token)
            .get()
            .build();
        try
        {
            Response customPolicyDefinitionResponse = customPolicyDefinitionHttpClient.newCall(customPolicyDefinitionRequest).execute();
            if(customPolicyDefinitionResponse.isSuccessful())
            {
                policyDefinitionJson = customPolicyDefinitionResponse.body().string();
            }
            else
            {
                // Not sure what it is.  Let's assume there are no policy definitions available.
                // So do nothing here for now.
            }
        }
        catch (IOException e)
        {
            e.printStackTrace(); // TODO Handle this...
        }  
    }
    // Wherever we got the policy definition from, let's parse it and gather data.
    // NOTE:  This design assumes that the JSON for built-in and custom are (nearly) identical.
    //        That might be wrong.
    if(!policyDefinitionJson.isEmpty())
    {
        JSONObject policyDefinitionRootObject = new JSONObject(policyDefinitionJson);
        // Do something with the resulting JSON
        System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("policyType"));
        System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("description"));
        System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("displayName"));
    }
    

    注意:“当您创建单个 OkHttpClient 实例并将其重用于所有 HTTP 调用时,OkHttp 性能最佳。”所以我仍然需要做一些重构以避免创建多个客户端。

    【讨论】: