身份验证失败-缺少“授权”标头-向Azure发出Python HTTP请求

时间:2020-04-08 05:30:36

标签: python azure rest http python-requests

当尝试将REST API PUT调用发送到Azure时,请参阅下面的错误。

{"error":{"code":"AuthenticationFailed","message":"Authentication failed. The 'Authorization' header is missing."}}

这是我的授权代码。

def authorized():
    if request.args.get('state') != session.get("state"):
        return redirect(url_for("index"))  # No-OP. Goes back to Index page
    if "error" in request.args:  # Authentication/Authorization failure
        return render_template("auth_error.html", result=request.args)
    if request.args.get('code'):
        cache = _load_cache()
        result = _build_msal_app(cache=cache).acquire_token_by_authorization_code(
            request.args['code'],
            scopes=app_config.SCOPE,  # Misspelled scope would cause an HTTP 400 error here
            redirect_uri=url_for("authorized", _external=True))
        if "error" in result:
            return render_template("auth_error.html", result=result)
        session["user"] = result.get("id_token_claims")
        _save_cache(cache)
    return redirect(url_for("index"))

def _load_cache():
    cache = msal.SerializableTokenCache()
    if session.get("token_cache"):
        cache.deserialize(session["token_cache"])
    return cache

def _save_cache(cache):
    if cache.has_state_changed:
        session["token_cache"] = cache.serialize()

def _build_msal_app(cache=None, authority=None):
    return msal.ConfidentialClientApplication(
        app_config.CLIENT_ID, authority=authority or app_config.AUTHORITY,
        client_credential=app_config.CLIENT_SECRET, token_cache=cache)

def _build_auth_url(authority=None, scopes=None, state=None):
    return _build_msal_app(authority=authority).get_authorization_request_url(
        scopes or [],
        state=state or str(uuid.uuid4()),
        redirect_uri=url_for("authorized", _external=True))

def _get_token_from_cache(scope=None):
    cache = _load_cache()  # This web app maintains one cache per session
    cca = _build_msal_app(cache=cache)
    accounts = cca.get_accounts()
    if accounts:  # So all account(s) belong to the current signed-in user
        result = cca.acquire_token_silent(scope, account=accounts[0])
        _save_cache(cache)
        return result

此处是包含http请求的代码。

@app.route('/storageaccountcreate', methods = ['POST', 'PUT'])
def storageaccountcreate():
    name = request.form['storageaccountname']
    resourcegroup = request.form['resourcegroup']
    subscriptionId = request.form['subscriptionId']
    location = request.form['location']
    sku = request.form['sku']

    url = f'https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourcegroup}/providers/Microsoft.Storage/storageAccounts/{name}?api-version=2019-06-01'
    r = requests.put((url))
    print(r.text)
    return r.text

还要注意,我已经在Azure AD中注册了该应用程序,并且已经将我的应用程序设置为可以通过Azure AD进行身份验证,并且可以使用Azure AD身份验证登录到该应用程序。我还在登录时收到令牌,该令牌已存储在缓存中。

1 个答案:

答案 0 :(得分:2)

如果要使用Azure rest API创建Azure存储帐户,我们需要使用Azure AD访问令牌调用Azure rest API。有关更多详细信息,请参阅official documentblog

例如

REST API

PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}?api-version=2019-06-01

Authorization: Bearer <access token>
content-type: application/json


{
  "sku": {
    "name": "Standard_GRS"
  },
  "kind": "Storage",
  "location": "eastus"

}

python代码

import json
@app.route("/storageaccountcreate")
def graphcall():
    token = _get_token_from_cache(["https://management.azure.com/user_impersonation"])
    if not token:
        return redirect(url_for("login"))
    headers={'Authorization': 'Bearer ' + token['access_token'],
             'Content-Type': 'application/json'

    }
    payload={
            "sku": {
                "name": "Standard_GRS"
            },
            "kind": "Storage",
            "location": "eastus"}
    payload=json.dumps(payload)
    name = request.form['storageaccountname']
    resourcegroup = request.form['resourcegroup']
    subscriptionId = request.form['subscriptionId']
    location = request.form['location']
    sku = request.form['sku']

    url = f'https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourcegroup}/providers/Microsoft.Storage/storageAccounts/{name}?api-version=2019-06-01'

    response = requests.request("PUT", url, headers=headers, data = payload)
    print(response.text)
    return response.text