Нам нужно предоставить доступ только к определенным папкам больших двоичных объектов. для каждого пользователя, поэтому с помощью его электронной почты мы можем фильтровать то, что пользователь сможет видеть.
Приложение делегировало разрешения для электронной почты и профиля пользователя.
Мы пробовали многое, но ничего не получилось.
Код, который у нас есть на данный момент:
Код: Выделить всё
##credential and connections
credential = DefaultAzureCredential()
KEY_VAULT_NAME = os.environ.get("KEY_VAULT_NAME")
KV_URI = f"https://{KEY_VAULT_NAME}.vault.azure.net"
client = SecretClient(vault_url=KV_URI, credential=credential)
##sso
# Azure AD Config
TENANT_ID=client.get_secret("tenantid")
TENANT_ID=TENANT_ID.value
CLIENT_ID = client.get_secret("clientid")
CLIENT_ID=CLIENT_ID.value
CLIENT_SECRET=client.get_secret("clientsecret")
CLIENT_SECRET=CLIENT_SECRET.value
scope=["https://graph.microsoft.com/User.Read"]
app = PublicClientApplication(
client_id=CLIENT_ID,
authority=f"https://login.microsoftonline.com/{TENANT_ID}")
result = None
if not result:
result = app.acquire_token_interactive(scopes=["User.Read"])
if "access_token" in result:
access_token = result["access_token"]
if "id_token" in result:
id_token = result["id_token"]
user_info = jwt.decode(id_token, options={"verify_signature": False})
st.write(f"Welcome, {user_info.get('name', 'User')}!")
st.write(f"Your email: {user_info.get('preferred_username', 'Not available')}")
else:
st.write('No id_token in results')
email = user_info.get('mail', user_info.get('preferred_username', None))
if email:
if not is_valid_email(email):
st.error("Invalid email format. Please enter a valid email address.")
elif email in ALLOWED_EMAILS:
company_list = df_access['Companies'][df_access['Email']==email].unique() # Get the list of all unique companies
if len(company_list) >0:
st.session_state.logged_in = True
st.session_state.email = email
st.session_state.login_time = datetime.now()
st.success("Login successful!")
st.rerun()
else:
st.error("No companies available for this email.")
else:
st.error("Invalid email. Please try again.")
st.session_state.logged_in = False
else:
st.error("Email not found in user information.")
At first we tried this approach with st.query_params():
def get_public_keys():
"""Retrieve public keys from Azure AD for validating ID tokens."""
response = requests.get(DISCOVERY_URL)
response.raise_for_status()
jwks_uri = response.json()["jwks_uri"]
jwks_response = requests.get(jwks_uri)
jwks_response.raise_for_status()
keys = jwks_response.json()["keys"]
print(keys)
return {key["kid"]: RSAAlgorithm.from_jwk(json.dumps(key)) for key in keys}
def validate_id_token(token, public_keys):
"""Decode and validate the ID token using Azure AD public keys."""
unverified_header = jwt.get_unverified_header(token)
kid = unverified_header["kid"]
if kid not in public_keys:
raise ValueError("Invalid token key ID (kid).")
# Decode and validate token
decoded_token = jwt.decode(
token,
public_keys[kid],
algorithms=["RS256"],
audience=CLIENT_ID, # Replace with your Azure app's Client ID
issuer=f"https://login.microsoftonline.com/{TENANT_ID}/v2.0"
)
return decoded_token
def get_token_from_headers():
"""Extract the ID token from the HTTP headers (Streamlit app)."""
headers = st.query_params() # Simulating header extraction
token = headers.get("id_token", [None])[0] # Replace with actual header extraction
if not token:
st.error("No ID token found in the headers.")
st.stop()
return token
public_keys = get_public_keys()
token = get_token_from_headers()
user_info = validate_id_token(token, public_keys)
Мы также пытались использовать Microsoft Graph API, но это тоже не сработало.
Подробнее здесь: https://stackoverflow.com/questions/792 ... o-log-in-t