Skip to content

Commit 089b059

Browse files
authored
Added FIC auth support (#1539)
1 parent 4c51dfe commit 089b059

File tree

2 files changed

+80
-20
lines changed

2 files changed

+80
-20
lines changed
Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,56 @@
1-
import adal
21
import pytest
2+
import os
3+
import json
4+
import requests
5+
from azure.identity import ClientAssertionCredential, ClientSecretCredential, ManagedIdentityCredential, CertificateCredential
36

4-
from msrestazure.azure_active_directory import AADTokenCredentials
7+
# Function that returns aad token credentials for a given spn
8+
# Default behavior is to use managed identity, if use_cert_auth is set we attempt to use a certificate, if use_SPN_auth is set we fall back to SPN client secret auth
9+
def get_fed_token():
10+
system_accesstoken = os.getenv('SYSTEM_ACCESSTOKEN')
11+
service_connection_id = os.getenv('SERVICE_CONNECTION_ID')
12+
system_oidc_request_uri = os.getenv('SYSTEM_OIDCREQUESTURI')
513

14+
if system_accesstoken and service_connection_id and system_oidc_request_uri:
15+
# Construct the OIDC_REQUEST_URL
16+
oidc_request_url = f"{system_oidc_request_uri}?api-version=7.1&serviceConnectionId={service_connection_id}"
17+
# Preparing headers for ADO Pipeline OIDC authentication
18+
headers = {
19+
"Content-Length": "0",
20+
"Content-Type": "application/json",
21+
"Authorization": f"Bearer {system_accesstoken}"
22+
}
623

7-
# Function to fetch aad token from spn id and password
8-
def fetch_aad_token(client_id, client_secret, authority_uri, resource_uri):
9-
"""
10-
Authenticate using service principal w/ key.
11-
"""
12-
try:
13-
context = adal.AuthenticationContext(authority_uri, api_version=None)
14-
return context.acquire_token_with_client_credentials(resource_uri, client_id, client_secret)
15-
except Exception as e:
16-
pytest.fail("Error occured while fetching aad token: " + str(e))
24+
# Make the POST request
25+
response = requests.post(oidc_request_url, headers=headers)
1726

27+
# Check the response and extract the OIDC token
28+
if response.status_code == 200:
29+
# Assuming the response is JSON and has an 'oidcToken' field
30+
arm_oidc_token = response.json().get('oidcToken')
31+
print("Return Fed token")
32+
return arm_oidc_token
33+
else:
34+
print("Failed to retrieve FED Token:", response.status_code, response.text)
1835

19-
# Function that returns aad token credentials for a given spn
20-
def fetch_aad_token_credentials(client_id, client_secret, authority_uri, resource_uri):
21-
mgmt_token = fetch_aad_token(client_id, client_secret, authority_uri, resource_uri)
36+
else:
37+
print("""
38+
One or more variables (SYSTEM_ACCESSTOKEN,
39+
SERVICE_CONNECTION_ID,
40+
SYSTEM_OIDCREQUESTURI) are either not set or empty.
41+
""")
42+
43+
def fetch_aad_token_credentials(tenant_id, client_id, client_secret, authority, use_cert_auth = False, use_SPN_auth = False, use_FIC_auth = False):
2244
try:
23-
return AADTokenCredentials(mgmt_token, client_id)
45+
if use_FIC_auth:
46+
return ClientAssertionCredential(tenant_id=tenant_id, client_id=client_id, func=get_fed_token, authority=authority)
47+
if use_SPN_auth:
48+
return ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret, authority=authority)
49+
if use_cert_auth:
50+
import base64
51+
cert_bytes = base64.b64decode(client_secret)
52+
return CertificateCredential(tenant_id=tenant_id, client_id=client_id, certificate_data=cert_bytes, send_certificate_chain=True)
53+
else:
54+
return ManagedIdentityCredential(client_id=client_id)
2455
except Exception as e:
2556
pytest.fail("Error occured while fetching credentials: " + str(e))

test/e2e/src/core/e2e_tests.sh

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,34 @@ deleteArcCIExtension() {
155155
}
156156

157157
login_to_azure() {
158-
if [[ -z $WORKLOAD_CLIENT_ID ]]; then
158+
## Federted Identity credentials authentication mechanism added.
159+
if [[ -v SYSTEM_ACCESSTOKEN && -n "$SYSTEM_ACCESSTOKEN" &&
160+
-v SERVICE_CONNECTION_ID && -n "$SERVICE_CONNECTION_ID" &&
161+
-v SYSTEM_OIDCREQUESTURI && -n "$SYSTEM_OIDCREQUESTURI" ]]; then
162+
163+
export OIDC_REQUEST_URL="${SYSTEM_OIDCREQUESTURI}?api-version=7.1&serviceConnectionId=${SERVICE_CONNECTION_ID}"
164+
echo "OIDC_REQUEST_URL= $OIDC_REQUEST_URL"
165+
166+
FED_TOKEN=$(curl -s -H "Content-Length: 0" -H "Content-Type: application/json" -H "Authorization: Bearer $SYSTEM_ACCESSTOKEN" -X POST $OIDC_REQUEST_URL | jq -r '.oidcToken')
167+
echo "FED_TOKEN= $FED_TOKEN"
168+
169+
echo "logging in using Federated Identity"
170+
az login --service-principal -u $FED_CLIENT_ID --tenant $TENANT_ID --allow-no-subscriptions --federated-token $FED_TOKEN 2> >(tee "${results_dir}/error" >&2) || python3 setup_failure_handler.py
171+
172+
elif [[ -v BASE_64_CLIENT_CERTIFICATE && -n "$BASE_64_CLIENT_CERTIFICATE" ]]; then
173+
BASE_64_CLIENT_CERTIFICATE=${BASE_64_CLIENT_CERTIFICATE#\"} # Remove leading quote
174+
BASE_64_CLIENT_CERTIFICATE=${BASE_64_CLIENT_CERTIFICATE%\"} # Remove trailing quote
175+
echo "logging in using Certificate '${BASE_64_CLIENT_CERTIFICATE}'"
176+
## create base64 cert to pem
177+
echo ${BASE_64_CLIENT_CERTIFICATE:0} | tr ' ' "\n" > base64_cert
178+
# convert base64 to PEM
179+
openssl base64 -d -in base64_cert -out clientcert.pem
180+
# minutes=60
181+
# seconds=$((minutes * 60))
182+
# sleep $seconds
183+
az login --service-principal --use-cert-sn-issuer -u $CLIENT_ID -p clientcert.pem --tenant $TENANT_ID 2> >(tee "${results_dir}/error" >&2) || python3 setup_failure_handler.py
184+
185+
elif [[ -z $WORKLOAD_CLIENT_ID ]]; then
159186
echo "logging in using service principal '${CLIENT_ID}'"
160187
az login --service-principal \
161188
-u ${CLIENT_ID} \
@@ -166,9 +193,11 @@ login_to_azure() {
166193
az login --identity \
167194
-u ${WORKLOAD_CLIENT_ID} 2> ${results_dir}/error || python3 setup_failure_handler.py
168195
fi
169-
170-
echo "setting subscription: ${SUBSCRIPTION_ID} as default subscription"
171-
az account set -s $SUBSCRIPTION_ID
196+
197+
echo "setting subscription: ${SUBSCRIPTION_ID} as default subscription"
198+
##
199+
az account set \
200+
--subscription ${SUBSCRIPTION_ID} 2> >(tee "${results_dir}/error" >&2) || python3 setup_failure_handler.py
172201
}
173202

174203

0 commit comments

Comments
 (0)