AzureAD OIDC: access_token из https://sts.windows.net/ не является токеном JWT

Я реализую поток авторизации_кода с помощью AzureAD OIDC для своего приложения на Python, используя библиотеку MSAL.

Мне нужно использовать конечные точки OAuth2 версии 1, чтобы требовать аутентификацию MFA (которая, похоже, недоступна в версии 2.0), поэтому:

https://login.microsoftonline.com/{tenant}/oauth2/

Вместо

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/

Вот пример кода:

msal_app = ConfidentialClientApplication(
    client_id = "xxx",
    client_credential = "yyy",
    oidc_authority = "https://sts.windows.net/{tenant}",  # Force OAuth2 v1.0
)

...

flow = msal_app.initiate_auth_code_flow(
    scopes=["User.Read"],
    redirect_uri = "zzz",
)

# Redirect to: flow["auth_uri"] + "&amr_values=ngcmfa"  # OAuth2 v2.0 does not accept amr_values which requires the MFA authentication

...

payload = msal_app.acquire_token_by_auth_code_flow(flow, dict(request.query_params))

Вот что содержит payload:

Это сработало, но access_token странно: похоже, это не токен JWT (который обычно начинается с ey).

Если я попытаюсь использовать его с Microsoft Graph, чтобы использовать запрошенную мной область User.Read, это не удастся:

requests.get(
        "https://graph.microsoft.com/v1.0/me",
        headers = {"Authorization": f"Bearer {payload['access_token']}"}
    ).json()
{'error': {'code': 'InvalidAuthenticationToken', 'message': "IDX14100: JWT is not well formed, there are no dots (.).\nThe token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EndcodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.", 'innerError': {'date': '2024-06-03T08:58:59', 'request-id': 'qqq', 'client-request-id': 'www'}}}

Итак, вопрос: почему он дает access_token, который нельзя использовать?

Примечание. Если я переключусь на OAuth2 v2.0, он будет работать без проблем и вернет действительный токен JWT в access_token, однако я не смогу использовать amr_values для обеспечения соблюдения MFA, что является обязательным требованием.

Можете ли вы помочь мне понять, что происходит?

Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
0
118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обратите внимание: чтобы принудительно использовать многофакторную аутентификацию, вам необходимо передать amr_values в URL-адрес авторизации. Обратитесь к этому МсДок

  • И он поддерживает только конечную точку версии 1.0.
  • В вашем коде попробуйте изменить полномочия как https://login.microsoftonline.com/TenantID. Обратитесь сюда MsDoc

Например, я изменил код, передав URL-адрес авторизации напрямую, и успешно получил результаты:

# Create a Flask web application
app = Flask(__name__)
app.secret_key = 'os.urandom(24)'  
 
client_id = "ClientID"
tenant_id = "TenantID"
redirect_uri = "RedirectURL"
 
msal_app = ConfidentialClientApplication(
    client_id=client_id,
    authority = "https://login.microsoftonline.com/" + tenant_id
)
# Define the authorization endpoint URL
auth_url = (
    "https://login.microsoftonline.com/"
    + tenant_id
    + "/oauth2/authorize?"
    + "response_type=code&"
    + "client_id = " + client_id + "&"
    + "state=12345&"
    + "resource=https://graph.microsoft.com&"
    + "client-request-id=67890&"
    + "amr_values=ngcmfa&" 
    + "redirect_uri = " + redirect_uri
)
@app.route("/")
def home():
    return redirect(auth_url)
@app.route("/get_a_token")
def get_a_token():
    auth_code = request.args.get('code')
    # Acquire an access token using the authorization code
    try:
        token_response = msal_app.acquire_token_by_authorization_code(
            auth_code,
            scopes=["User.Read"],
            redirect_uri=redirect_uri
        )
    except Exception as e:
        return f"Token acquisition failed: {str(e)}"
    if "access_token" in token_response:
        access_token = token_response["access_token"]
        print("Access Token:", access_token)
        # Use the access token to make a request to Microsoft Graph
        graph_response = requests.get(
            "https://graph.microsoft.com/v1.0/me",
            headers = {"Authorization": f"Bearer {access_token}"}
        )
        if graph_response.status_code == 200:
            user_data = graph_response.json()
            return f"User: {user_data['displayName']}, Email: {user_data['mail']}"
        else:
            return f"Failed to fetch user data from Microsoft Graph: {graph_response.text}"
    else:
        error_message = token_response.get("error_description", "Unknown error")
        return f"Token acquisition failed: {error_message}"
# Run the Flask application
if __name__ == "__main__":
    app.run(debug=True)

Пользователь перенаправляется на страницу MFA:

И после успешного входа я получил токен доступа:

Используя токен доступа, я могу успешно запросить API Micrsoft Graph, как показано ниже:

Ссылка:

Многофакторная проверка авторизации Azure Active Directory - Stack Overflow на русском

Другие вопросы по теме