使用python的Azure函数应用程序:如何访问用户组进行授权

2024-05-29 04:24:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Azure函数应用程序和OAuth非常陌生,所以请容忍我

我的设置

我有一个Azure Function应用程序,它有一个简单的python函数,除了打印请求头之外,什么都不做:

import logging

import azure.functions as func

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

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        aadIdToken = req.headers.get('X-MS-TOKEN-AAD-ID-TOKEN')
        aadAccessToken = req.headers.get('X-MS-TOKEN-AAD-ACCESS-TOKEN')
        principalID = req.headers.get('X-MS-CLIENT-PRINCIPAL-ID')
        principalName = req.headers.get('X-MS-CLIENT-PRINCIPAL-NAME')
        idProviderId = req.headers.get('X-MS-CLIENT-PRINCIPAL-IDP')
        aadRefreshToken = req.headers.get('X-MS-TOKEN-AAD-REFRESH-TOKEN')

        clientPrincipal = req.headers.get('X-MS-CLIENT-PRINCIPAL')

        result = "\n"
        myDict = sorted(dict(req.headers))
        for key in myDict:
            result += f"{key} = {dict(req.headers)[key]}\n"

        return func.HttpResponse(
            f"Hello, {name}. How are you ? Doing well ?"\
            f"\n\nHere is some data concerning your Client principal:"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL-ID: {principalID}"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL-NAME: {principalName}"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL-IDP: {idProviderId}"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL: {clientPrincipal}"\
            f"\n\nHere is some data concerning your AAD-token:"\
            f"\nThis is your X-MS-TOKEN-AAD-ID-TOKEN: {aadIdToken}"\
            f"\nThis is your X-MS-TOKEN-AAD-ACCESS-TOKEN: {aadAccessToken}"\
            f"\nThis is your X-MS-TOKEN-AAD-REFRESH-TOKEN: {aadRefreshToken}"\
            f"\n\n\nresult: {result}"\
        )
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

我遵循这个guide让用户在调用函数之前通过EasyAuth进行身份验证。
这似乎很有效。当通过浏览器访问该功能时,我将被重定向以登录。成功登录后,我再次被重定向,HTTP响应将在浏览器中打印出来。由于我能够访问X-MS-CLIENT-PRINCIPAL-IDX-MS-CLIENT-PRINCIPAL-NAME,我认为身份验证是成功的。但是,在打印整个请求头时,我没有找到X-MS-TOKEN-AAD-REFRESH-TOKENX-MS-TOKEN-AAD-ACCESS-TOKENX-MS-TOKEN-AAD-ID-TOKEN
这是输出(输出太大;在屏幕截图中显示的输出下方,我可以看到标题内容): First half of my output

我的问题

我现在试图做的是通过函数的python代码访问分配给登录用户的组,以进一步授权他的请求(例如,“用户只能在分配组xyz时执行函数,否则将提示“不允许”。
为了实现这一点,我在我的应用注册的令牌配置中添加了“组”-声明

据我所知,使用ClaimsPrinciple对象(source),通过.NET中编码的函数访问用户组是很容易的

如何通过python代码访问用户分配的组?
这可能吗?
我是不是完全错了

跟进:
到目前为止,我还不明白的一件事是,当第一次通过浏览器访问函数时(为了触发登录),我可以在浏览器调试程序的回调http请求中看到id_tokenBrowser debugger: id_token in callback-request

当我使用jwt.io解密该令牌时,我能够看到分配的用户组的一些ID,这似乎正是我希望通过python代码访问的ID。
重新加载页面(我假设请求然后使用已经通过身份验证的浏览器会话)会使回调消失


Tags: 函数nameclienttokenidprincipalyourget
1条回答
网友
1楼 · 发布于 2024-05-29 04:24:35

X-MS-CLIENT-PRINCIPAL包含与id_令牌相同的声明。因此,如果我们想要获得组声明,我们可以对报头进行base64解码

比如说

我的代码

import logging

import azure.functions as func
import base64

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

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        aadAccessToken = req.headers.get('X-MS-TOKEN-AAD-ACCESS-TOKEN')
        principalID = req.headers.get('X-MS-CLIENT-PRINCIPAL-ID')
        principalName = req.headers.get('X-MS-CLIENT-PRINCIPAL-NAME')
        idProviderId = req.headers.get('X-MS-CLIENT-PRINCIPAL-IDP')
        aadRefreshToken = req.headers.get('X-MS-TOKEN-AAD-REFRESH-TOKEN')

        clientPrincipal = req.headers.get('X-MS-CLIENT-PRINCIPAL')
        clientPrincipal= base64.b64decode(clientPrincipal)

        result = "\n"
        myDict = sorted(dict(req.headers))
        for key in myDict:
            result += f"{key} = {dict(req.headers)[key]}\n"

        return func.HttpResponse(
            f"Hello, {name}. How are you ? Doing well ?"\
            f"\n\nHere is some data concerning your Client principal:"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL-ID: {principalID}"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL-NAME: {principalName}"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL-IDP: {idProviderId}"\
            f"\nThis is your X-MS-CLIENT-PRINCIPAL: {clientPrincipal}"\
            f"\n\nHere is some data concerning your AAD-token:"\
            f"\nThis is your X-MS-TOKEN-AAD-ID-TOKEN: {aadIdToken}"\
            f"\nThis is your X-MS-TOKEN-AAD-ACCESS-TOKEN: {aadAccessToken}"\
            f"\nThis is your X-MS-TOKEN-AAD-REFRESH-TOKEN: {aadRefreshToken}"\
            f"\n\n\nresult: {result}"\
        )
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

enter image description here

相关问题 更多 >

    热门问题