簡體   English   中英

使用托管標識在 python 中使用 azure 函數應用程序

[英]Stuck with azure function app in python using managed identity

我正在嘗試編寫函數應用程序,該應用程序將從日志分析工作區獲取數據並使用 python3 推送到事件中心。 函數應用程序使用托管身份。我正在使用 azure sdk for python。 我當前的代碼如下所示:

def getAzureEventData():
    """
    if "MSI_ENDPOINT" in os.environ:
        print("GeTTING MSI Authentication")
        creds = MSIAuthentication()
    else:
        creds, *_ = get_azure_cli_credentials()         
    """

   ## want to find out which one is correct tested each one.
    creds = DefaultAzureCredential()
    creds=CredentialWrapper()
    creds = MSIAuthentication()
    #creds, _ = get_azure_cli_credentials(resource="https://api.loganalytics.io")

    log_client = LogAnalyticsDataClient(creds)
    
    laQuery = 'ActivityLog | where TimeGenerated > ago(1d)'
    result = log_client.query(cisalog_workspace_id, QueryBody(query=laQuery))

根據我見過的例子,

creds, _ = get_azure_cli_credentials(resource="https://api.loganalytics.io")

使用過,但是當我在沒有任何DefaultCredential()情況下使用該函數時,我收到 404 錯誤,表示未啟用系統管理標識。 當我使用DefualtCrednetial我收到access_token 錯誤,並且根據建議,我使用了在互聯網上找到的包裝器。 當我使用它時,我得到 Exception: ErrorResponseException: (InvalidTokenError) The provided authentication is not valid for this resource 所以我很困惑如何使用 Loganalytics SDK 客戶端。 我正在本地和門戶中進行測試。 我的最終目標是使用具有 IAM 角色的系統托管身份來訪問 LA 工作區的函數應用程序。 我已將工作區上的監視讀者角色授予 SMI。 仍然面臨問題。

如果要使用 AzureMSI 在 Azure 函數中調用 Azure Log Analytics Rest API,則需要將 Azure RABC 角色Log Analytics Reader分配給 MSI。 有關詳細信息,請參閱此處

例如

  1. 啟用 Azure 函數 MSI

  2. 分配角色

New-AzRoleAssignment -ObjectId "<the objectId of Azure function MSI>" -RoleDefinitionName "Log Analytics Reader" -Scope "/subscriptions/{subId}"
  1. 代碼

我的cred_wrapper.py

from msrest.authentication import BasicTokenAuthentication
from azure.core.pipeline.policies import BearerTokenCredentialPolicy
from azure.core.pipeline import PipelineRequest, PipelineContext
from azure.core.pipeline.transport import HttpRequest

from azure.identity import DefaultAzureCredential


class CredentialWrapper(BasicTokenAuthentication):
    def __init__(self, credential=None, resource_id="https://westus2.api.loganalytics.io/.default", **kwargs):
        """Wrap any azure-identity credential to work with SDK that needs azure.common.credentials/msrestazure.
        Default resource is ARM (syntax of endpoint v2)
        :param credential: Any azure-identity credential (DefaultAzureCredential by default)
        :param str resource_id: The scope to use to get the token (default ARM)
        """
        super(CredentialWrapper, self).__init__(None)
        if credential is None:
            #credential = DefaultAzureCredential()
            credential = DefaultAzureCredential()
        self._policy = BearerTokenCredentialPolicy(
            credential, resource_id, **kwargs)

    def _make_request(self):
        return PipelineRequest(
            HttpRequest(
                "CredentialWrapper",
                "https://fakeurl"
            ),
            PipelineContext(None)
        )

    def set_token(self):
        """Ask the azure-core BearerTokenCredentialPolicy policy to get a token.
        Using the policy gives us for free the caching system of azure-core.
        We could make this code simpler by using private method, but by definition
        I can't assure they will be there forever, so mocking a fake call to the policy
        to extract the token, using 100% public API."""
        request = self._make_request()
        self._policy.on_request(request)
        # Read Authorization, and get the second part after Bearer
        token = request.http_request.headers["Authorization"].split(" ", 1)[1]
        self.token = {"access_token": token}

    def signed_session(self, session=None):
        self.set_token()
        return super(CredentialWrapper, self).signed_session(session)

我的功能碼

import logging
from azure.loganalytics import LogAnalyticsDataClient
from .cred_wrapper import CredentialWrapper
import azure.functions as func
from azure.loganalytics.models import QueryBody
import json


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    creds = CredentialWrapper()
    client = LogAnalyticsDataClient(creds)
    result = client.query(workspace_id='',
                          body=QueryBody(query='Heartbeat | take 10'))
    return func.HttpResponse(
        json.dumps(result.tables[0].rows),
        status_code=200
    )

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM