Вот соответствующая часть моего кода: < /p>
fastapi:
Код: Выделить всё
app.add_middleware(SessionMiddleware, secret_key="q803pJMcx6KNkIlBGi_mPQSYiOP0IPze")
#app.add_middleware(TokenVerificationMiddleware)
@app.get("/")
async def health():
return JSONResponse(content={"status": "healthy"}, status_code=200)
# Redirect to login URL
@app.get("/login")
async def login(request: Request):
redirect_uri = request.url_for('auth')
return await oauth.azure.authorize_redirect(request, redirect_uri)
# Callback endpoint
@app.get("/auth")
async def auth(request: Request):
token = await oauth.azure.authorize_access_token(request)
user = token.get('userinfo')
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Authentication failed')
return user
Код: Выделить всё
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2AuthorizationCodeBearer
from authlib.integrations.starlette_client import OAuth
from starlette.requests import Request
import os
# Load environment variables
CLIENT_ID = os.getenv("ASPEN_APP_AUTH_CLIENT_ID")
TENANT_ID = os.getenv("ASPEN_APP_AUTH_TENANT_ID")
CLIENT_SECRET = os.getenv("ASPEN_APP_AUTH_SECRET")
# Initialize OAuth2
oauth = OAuth()
oauth.register(
name='azure',
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
authorize_url=f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize',
token_url=f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token',
client_kwargs={'scope': 'openid email profile'}
)
oauth2_scheme = OAuth2AuthorizationCodeBearer(
authorizationUrl=f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize',
tokenUrl=f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token'
)
async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)):
try:
response = await oauth.azure.parse_id_token(request, token)
return response
except Exception as e:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=str(e)
)
< /code>
Ошибка возникает в линии token = await oauth.azure.authorize_access_token (запрос). Я подтвердил, что переменные среды устанавливаются правильно и что URL -адрес перенаправления в Azure точно соответствует. />Python 3.12
uvicorn~=0.23.2
fastapi~=0.103.1
pydantic~=2.4.2
pandas~=2.1.0
requests~=2.31.0
beautifulsoup4~=4.12.2
aiohttp~=3.9.1
pyproj~=3.6.0
python-dateutil~=2.8.2
python-dotenv~=1.0.0
python-jose~=3.3.0
mangum~=0.17.0
SQLAlchemy~=2.0.21
starlette~=0.27.0
bs4~=0.0.1
httpx~=0.23.0
Authlib~=1.2.1
itsdangerous~=2.1.2
boto3~=1.33.12
botocore~=1.33.12
respx>=0.20.1
< /code>
traceback: < /p>
#I add some print statements to fetch access token
redirect_uri: http://localhost:8000/auth
metadata: {'token_url': 'https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token'}
token_endpoint: None
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 408, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 84, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\fastapi\applications.py", line 292, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\applications.py", line 122, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\middleware\errors.py", line 184, in __call__
raise exc
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\middleware\errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\middleware\sessions.py", line 86, in __call__
await self.app(scope, receive, send_wrapper)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\middleware\exceptions.py", line 79, in __call__
raise exc
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 20, in __call__
raise e
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 17, in __call__
await self.app(scope, receive, send)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\routing.py", line 718, in __call__
await route.handle(scope, receive, send)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\routing.py", line 276, in handle
await self.app(scope, receive, send)
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\starlette\routing.py", line 66, in app
response = await func(request)
^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\fastapi\routing.py", line 273, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\fastapi\routing.py", line 190, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\AspenAPI\fast_api.py", line 56, in auth
token = await oauth.azure.authorize_access_token(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\authlib\integrations\starlette_client\apps.py", line 82, in authorize_access_token
token = await self.fetch_access_token(**params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\authlib\integrations\base_client\async_app.py", line 128, in fetch_access_token
token = await client.fetch_token(token_endpoint, **params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\authlib\integrations\httpx_client\oauth2_client.py", line 125, in _fetch_token
resp = await self.post(
^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\httpx\_client.py", line 1842, in post
return await self.request(
^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\authlib\integrations\httpx_client\oauth2_client.py", line 90, in request
return await super(AsyncOAuth2Client, self).request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\httpx\_client.py", line 1514, in request
request = self.build_request(
^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\httpx\_client.py", line 344, in build_request
url = self._merge_url(url)
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\X\PycharmProjects\ServicesAPI\venv\Lib\site-packages\httpx\_client.py", line 374, in _merge_url
merge_url = URL(url)
^^^^^^^^
File "C:\Users\X\PycharmProjects\AspenServicesAPI\venv\Lib\site-packages\httpx\_urls.py", line 102, in __init__
raise TypeError(
TypeError: Invalid type for url. Expected str or httpx.URL, got : None
< /code>
Я подозреваю, что может возникнуть проблема с зависимостями, в частности HTTPX и Authlib, но я не уверен, как это решить. Любые понимание или предложения о том, что может вызвать эту ошибку и как ее исправить, будет очень оценено.
Использование Python 3.11 или 3.9 не сработало. Тем не менее, я обнаружил, что переименование «toke_url» до 'token_endpoint' устраняет начальную ошибку. Кроме того, включение «jwks_uri», кажется, разрешает последующую ошибку. Но теперь я сталкиваюсь с новой проблемой: «KeyError», связанный с 'id_token'. Я обновил свой пост с более подробной информацией для дальнейшего понимания. < /P>
JWKS_URI = "https://login.microsoftonline.com/{TENANT_ID}/discovery/v2.0/keys".format(TENANT_ID=ASPEN_APP_AUTH_TENANT_ID)
# Initialize OAuth2
oauth = OAuth()
oauth.register(
name='azure',
client_id=ASPEN_APP_AUTH_CLIENT_ID,
client_secret=ASPEN_APP_AUTH_SECRET,
authorize_url=f'https://login.microsoftonline.com/{ASPEN_APP_AUTH_TENANT_ID}/oauth2/v2.0/authorize',
token_endpoint=f'https://login.microsoftonline.com/{ASPEN_APP_AUTH_TENANT_ID}/oauth2/v2.0/token',
token_url=f'https://login.microsoftonline.com/{ASPEN_APP_AUTH_TENANT_ID}/oauth2/v2.0/token',
client_kwargs={'scope': 'openid email profile'},
jwks_uri=JWKS_URI
)
заменить 'toke_url' на 'token_endpoint' fixed ожидаемый Str или httpx .Url, Got < /p>
, чем проблема с token_id была фиксирована так: < /p>
@app.get("/auth")
async def auth(request: Request):
try:
token = await oauth.azure.authorize_access_token(request)
nonce = token.get('userinfo').get('nonce')
# Parse the ID token
user_info = await oauth.azure.parse_id_token(token=token, nonce=nonce)
return {"user_info": user_info}
except HTTPException as e:
raise e
except Exception as e:
print("Error during authentication:", str(e))
raise HTTPException(status_code=500, detail="Authentication failed.")
< /code>
Я не уверен, является ли это правильным подходом, но, похоже, он функционирует как предназначенное для меня. Если есть какие -либо ошибки или проблемы безопасности в том, что я сделал, пожалуйста, дайте мне знать.
Подробнее здесь: https://stackoverflow.com/questions/776 ... entication