11import logging
2+ from typing import List
3+
24import azure .functions as func
35import jwt
46import json
@@ -63,10 +65,17 @@ def blob_trigger(inbound: func.InputStream, outbound: func.Out[str]):
6365 return f"Error: { str (e )} "
6466
6567
66- def validate_jwt (token : str , audience : str ) -> bool :
68+ def validate_jwt (token : str , audience : str , required_scopes : List [ str ] ) -> bool :
6769 try :
6870 decoded = jwt .decode (token , audience = audience , options = {"verify_signature" : False })
69- # Optionally check claims like roles or scopes
71+
72+ # Check if the required scopes are present
73+ token_scopes = decoded .get ("scp" , "" ).split (" " )
74+ if not all (scope in token_scopes for scope in required_scopes ):
75+ logging .error (f"Required scopes { required_scopes } not found in token scopes { token_scopes } " )
76+ return False
77+
78+ logging .info ("Required scopes found in token: %s" , required_scopes )
7079 return True
7180 except Exception as e :
7281 logging .error (f"JWT validation failed: { e } " )
@@ -86,10 +95,13 @@ def upload_csv(req: func.HttpRequest, outbound: func.Out[str]) -> HttpResponse:
8695 return func .HttpResponse ("Missing auth header" , status_code = 401 )
8796
8897 token = auth_header .split (" " )[1 ] # Extract Bearer token
89- if not validate_jwt ( token , audience = os .environ .get ("FUNCTION_APP_CLIENT_ID" )):
90- return func . HttpResponse ( "Unauthorized" , status_code = 401 )
98+ audience = os .environ .get ("FUNCTION_APP_CLIENT_ID" )
99+ required_scopes = [ "Csv.Write" ]
91100
92- logging .info ("Received HTTP request to upload CSV" )
101+ if not validate_jwt (token , audience , required_scopes ):
102+ return HttpResponse ("Unauthorized" , status_code = 401 )
103+
104+ logging .info ("Successfully validated JWT token" )
93105
94106 # Parse raw bytes derived from request body to string
95107 string_body = req .get_body ().decode ("utf-8" )
0 commit comments