Checkout my page
djpugh / fastapi_aad_auth Goto Github PK
View Code? Open in Web Editor NEWAzure Active Directory Authentication wrapper for fast api
License: MIT License
Azure Active Directory Authentication wrapper for fast api
License: MIT License
Checkout my page
I tried your library and it works fine for app tokens generated via postman with "//api/{client_id}/.default" as scope and there is no validation error. But when I generate a token using the "@azure/msal-react" library with scope "https://graph.microsoft.com/User.Read", I keep getting the unable to parse authentication token error. I also see this
"authlib.jose.errors.BadSignatureError: bad_signature:" in the logs. I used "jwt.io" to parse the token and there was no error. I added the scope to config as follows and it doesn't make any difference too.
msal_scopes = [AADConfig(scopes=['https://graph.microsoft.com/User.Read'])]
auth_provider = Authenticator(Config(providers=msal_scopes))
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
actions/download-artifact
, actions/upload-artifact
).github/workflows/pipeline.yml
actions/checkout v4
actions/setup-python v4
actions/checkout v4
actions/setup-python v4
actions/checkout v4
actions/setup-python v4
actions/checkout v4
actions/setup-python v4
codecov/codecov-action v3
actions/checkout v4
actions/checkout v4
fossa-contrib/fossa-action v3
actions/checkout v4
github/codeql-action v2
github/codeql-action v2
actions/checkout v4
actions/setup-python v4
actions/upload-artifact v3
actions/checkout v4
actions/setup-python v4
actions/upload-artifact v3
actions/checkout v4
actions/setup-python v4
actions/download-artifact v3
actions/checkout v4
actions/setup-python v4
actions/download-artifact v3
actions/download-artifact v3
peaceiris/actions-gh-pages v3
.github/workflows/pr-labeler.yaml
TimonVS/pr-labeler-action v4
.github/workflows/release-management.yaml
toolmantim/release-drafter v5.25.0
requirements.txt
jinja2 >=2.11.3
cryptography >=3.3.2
setup.cfg
File "D:\src\repos\docserver\.venv\lib\site-packages\fastapi_aad_auth\auth.py", line 157, in require_endpoint
self._session_validator.set_post_auth_redirect(request, request.url.path)
File "D:\src\repos\docserver\.venv\lib\site-packages\fastapi_aad_auth\_base\validators\session.py", line 44, in set_post_auth_redirect
if not self.is_valid_redirect(redirect):
File "D:\src\repos\docserver\.venv\lib\site-packages\fastapi_aad_auth\_base\validators\session.py", line 51, in is_valid_redirect
return not any(map(partial(fnmatch.fnmatch, redirect), self._ignore_redirect_routes))
File "c:\python37\lib\fnmatch.py", line 35, in fnmatch
pat = os.path.normcase(pat)
File "c:\python37\lib\ntpath.py", line 48, in normcase
s = os.fspath(s)
TypeError: expected str, bytes or os.PathLike object, not NoneType
redirect
= None
fails in fnmatch
@djpugh I'm still struggling a bit how to do this whole thing without a UI... I mean I only have my API, and use Insomnia (or Postman) to interact with the API.
Could you give some pointers, as to how I should go about to actually initialize the auth flow to Azure, then use a token in the headers to be able to use the endpoints?
And as a bonus, does this module provide a callback, so that the user model could be persisted in the DB?
Originally posted by @soderluk in #16 (comment)
I have previously deployed fastapi_aad_auth successfully in an Azure Functions app. I'm now trying to replicate this in a second Azure Functions app, and am running into an error.
When I go to the /login
endpoint, I get the standard dialogs to login, but then I get a 500 error. The full trace is below (sorry for the poor formatting, Azure provides the logs from Azure Functions in a strange format and I had to try and tidy it up myself) - the main error is an Invalid key set format
error.
Do you have any idea what's going on here? I'm pretty sure I've set up the app in the same way as my first app (which works fine).
Exception: ValueError: Invalid key set format
Stack:
File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 402, in _handle__invocation_request
call_result = await self._loop.run_in_executor(
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 611, in _run_sync_func
return ExtensionManager.get_sync_invocation_wrapper(context,
File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/extension.py", line 215, in _raw_invocation_wrapperresult = function(**args)
File "/home/site/wwwroot/HttpTrigger1/__init__.py", line 172, in mainreturn AsgiMiddleware(app).handle(req, context)
File "/home/site/wwwroot/HttpTrigger1/__init__.py", line 154, in handlereturn self._handle(req, context)
File "/home/site/wwwroot/HttpTrigger1/__init__.py", line 161, in _handleasgi_response = self._loop.run_until_complete(
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 616, in run_until_completereturn future.result()
File "/home/site/wwwroot/HttpTrigger1/__init__.py", line 71, in from_appawait app(scope, res._receive, res._send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi/applications.py", line 208, in __call__await super().__call__(scope, receive, send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/applications.py", line 112, in __call__await self.middleware_stack(scope, receive, send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/errors.py", line 181, in __call__raise exc
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/errors.py", line 159, in __call__await self.app(scope, receive, _send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/sessions.py", line 77, in __call__await self.app(scope, receive, send_wrapper)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/authentication.py", line 48, in __call__await self.app(scope, receive, send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/cors.py", line 84, in __call__await self.app(scope, receive, send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/exceptions.py", line 82, in __call__raise exc
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/exceptions.py", line 71, in __call__await self.app(scope, receive, sender)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/routing.py", line 589, in __call__await route.handle(scope, receive, send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/routing.py", line 250, in handleawait self.app(scope, receive, send)
File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/routing.py", line 52, in appresponse = await func(request)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi_aad_auth/_base/provider.py", line 44, in login_callback
return self.authenticator.process_login_callback(request)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi_aad_auth/_base/authenticators/session.py", line 66, in process_login_callback
user = self._get_user_from_token(token)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi_aad_auth/providers/aad.py", line 109, in _get_user_from_token
return super()._get_user_from_token(token, options=options)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi_aad_auth/_base/authenticators/session.py", line 91, in _get_user_from_token
validated_claims = self._token_validator.validate_token(token, options=options)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi_aad_auth/_base/validators/token.py", line 120, in validate_token
claims = self._decode_token(token)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi_aad_auth/providers/aad.py", line 194, in _decode_token
jwk_ = self._get_ms_jwk(token)
File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi_aad_auth/providers/aad.py", line 188, in _get_ms_jwk
return jwk.loads(key)
File "/home/site/wwwroot/.python_packages/lib/site-packages/authlib/jose/jwk.py", line 6, in loads
key_set = JsonWebKey.import_key_set(obj)
File "/home/site/wwwroot/.python_packages/lib/site-packages/authlib/jose/rfc7517/jwk.py", line 55, in import_key_set
raise ValueError('Invalid key set format')
Is it possible to get some caching around _get_ms_jwk? It requests that key_url endpoint per login which can add up when not using sessions. Guess it would be safe to cache the result for maybe 60s or something?
I didn't get much from the doc to secure an API with azure openid token. Lets say my web/mobile client is sending Bearer token in header and I want my api to be secured e.g.
app = FastAPI()
app.config['AZURE_OAUTH_TENANCY'] = 'xxx'
app.config['AZURE_OAUTH_APPLICATION_ID'] = 'xxx'
auth = Authenticator()
auth.init_app(app)
@app.route('/unprotected')
def unprotected():
return 'hello world'
@app.route('/protected')
@auth()
def protected():
return 'hello authenticated entity'
@app.route('/protected-with-single-scope')
@auth('required-scope')
def protected_with_scope():
return 'hello authenticated and authorised entity'
@app.route('/protected-with-multiple-scopes')
@auth('required-scope1 required-scope2')
def protected_with_multiple_scopes():
return 'hello authenticated and authorised entity'
I'm looking for some declarative like @auth or some kind of configuration which will secure my /helllo api at backend.
The links placed in the readme all seem to lead to 404s, so accessing the documentation is made somewhat more difficult, forcing one to pore through docs/source
And as a bonus, does this module provide a callback, so that the user model could be persisted in the DB?
Originally posted by @soderluk in #16 (comment)
This package has type hints, but none of them are available to codebases using this package as the py.typed
marker is not present. All you need to do is add an empty file called py.typed
and all library users can enjoy the benefits of seeing the type hints inside the library. You may also need to update the setup.cfg
to ensure the py.typed
file is included in the package bundle.
See: https://peps.python.org/pep-0561/#packaging-type-information
Hello !
Is there a way to configure OpenApi to use Implicit flow ?
I need to be able to authenticate my through the OpenAPI ("/doc") interface, using the "implicit" flow:
Today, I'm constraint to use the "authorization code" strategy (where I need to provide client id / secret)
Other question, using the authorization code, I did not find a way to specify the scope ?
Where should I register my API scope ?
(Great work on this tool, love it :) )
UPDATE
Using only FastAPI, I'm able to prefill scopes and set the authentication from OpenApi, to Implicit flow, using this code
scopes = {
"https://..../user_impersonation": "https://..../user_impersonation",
}
oauth2_scheme = OAuth2(
flows=OAuthFlows(
implicit=OAuthFlowImplicit(
authorizationUrl="https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
scopes=scopes,
)
)
)
@app.get("/hello")
async def hello_world(token: str = Depends(oauth2_scheme)):
print(token)
return {"hello": "world"}
The idea is to know how to do the same, using your great api ?
I'm trying to restrict the users allowed to login to my application to just those who have a specific role set.
I have set my roles up in the Azure Portal, and the role (Data
) is defined in the manifest for my app. If I add or remove that role to my user, then I can see it is correctly listed (or not listed) in the /me
endpoint once I've logged in.
I have tried to set the AAD_ROLES
variable in my .env file to list the role that I want all users to have. I've specified it like this:
AAD_ROLES="[\"Data\"]"
However, I still find that I am able to login even when I haven't been assigned that role.
Is this the correct way to require a specific role when logging in? Have I specified the role correctly in the AAD_ROLES
env var? (I tried various ways, and most of them gave JSON errors, but this doesn't seem to give an error)
Any help would be much appreciated.
#16 needs releasing - there was an error in the tags that is affecting the build
fastapi_aad_auth/src/fastapi_aad_auth/oauth/validators/token.py
Lines 191 to 194 in 1081831
TODO
comment in 1081831 in #5. cc @djpugh.Originally posted by @todo in #5 (comment)
I am not sure whether this actually is an issue with this library. If it is not I hope someone here might know the issue.
I am trying to setup a public client application for internal use, using our aad. Authorization using the /docs page works fine, however a sign-in using the msal.PublicClientApplication
fails wit the following:
2021-06-01 12:08:58,760 - 918bd735a7944622ac7d2ba14c50629c - AADTokenValidator - DEBUG - Processed Key: b'-----BEGIN RSA PUBLIC KEY-----\nMIIBC...IDAQAB\n-----END RSA PUBLIC KEY-----\n'
2021-06-01 12:08:58,760 - 918bd735a7944622ac7d2ba14c50629c - AADTokenValidator - ERROR - Unable to parse error
Traceback (most recent call last):
File "python3.9/site-packages/fastapi_aad_auth/providers/aad.py", line 202, in _decode_token
claims = jwt.decode(
File "python3.9/site-packages/authlib/jose/rfc7519/jwt.py", line 99, in decode
data = self._jws.deserialize_compact(s, load_key, decode_payload)
File "python3.9/site-packages/authlib/jose/rfc7515/jws.py", line 105, in deserialize_compact
raise BadSignatureError(rv)
authlib.jose.errors.BadSignatureError: bad_signature:
2021-06-01 12:08:58,760 - 918bd735a7944622ac7d2ba14c50629c - AADTokenValidator - ERROR - Error authenticating via token
Traceback (most recent call last):
File "python3.9/site-packages/fastapi_aad_auth/providers/aad.py", line 202, in _decode_token
claims = jwt.decode(
File "python3.9/site-packages/authlib/jose/rfc7519/jwt.py", line 99, in decode
data = self._jws.deserialize_compact(s, load_key, decode_payload)
File "python3.9/site-packages/authlib/jose/rfc7515/jws.py", line 105, in deserialize_compact
raise BadSignatureError(rv)
authlib.jose.errors.BadSignatureError: bad_signature:
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "python3.9/site-packages/fastapi_aad_auth/_base/validators/token.py", line 52, in check
claims = self.validate_token(token)
File "python3.9/site-packages/fastapi_aad_auth/_base/validators/token.py", line 109, in validate_token
claims = self._decode_token(token)
File "python3.9/site-packages/fastapi_aad_auth/providers/aad.py", line 208, in _decode_token
raise AuthenticationError("Unable to parse authentication token")
starlette.authentication.AuthenticationError: Unable to parse authentication token
I have verified the arguments to jwt.decode(token, key)
and both are set, I did notice the token is much longer than when used through the /docs endpoint.
To replicate this, the client looks like:
import msal
from pprint import pprint
import requests
client_id = ''
tenant_id = ''
if __name__ == '__main__':
client = msal.PublicClientApplication(
client_id=client_id,
authority=f'https://login.microsoftonline.com/{tenant_id}'
)
response = client.acquire_token_interactive([client_id])
pprint(response)
try:
token = response['access_token']
except KeyError:
pprint(response)
else:
user_response = requests.get('https://graph.microsoft.com/v1.0/me', headers={
'Authorization': f'Bearer {token}'
})
pprint(user_response.json())
my_api_response = requests.get('http://localhost:8000/customers', headers={
'Authorization': f'Bearer {token}'
})
pprint(my_api_response.json())
The "graph" endpoint works and I can see the signed in user. My_api however doesn't and produces the error above.
In AAD I have added under "Authentication"->"Mobile and Desktop Applications" the callback url "http://localhost".
Further is ofcourse the "Allow public client flows" option set to Yes.
Could this be an issue with the way this library processes the token or is something else wrong?
fastapi_aad_auth/tests/unit/test_errors.py
Lines 5 to 10 in 9c81c78
TODO
comment in 9c81c78 in #5. cc @djpugh.Originally posted by @todo in #5 (comment)
The login page templating seems to be broken with fastapi 0.70.0/Starlette 0.16.0.
2021-10-12 13:33:08,118 - uvicorn.access - INFO - 127.0.0.1:59355 - "GET /login HTTP/1.1" 500
2021-10-12 13:33:08,119 - uvicorn.error - ERROR - Exception in ASGI application
Traceback (most recent call last):
File "/path/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/path/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "/path/python3.9/site-packages/fastapi/applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "/path/python3.9/site-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/path/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc
File "/path/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/path/python3.9/site-packages/starlette/middleware/sessions.py", line 77, in __call__
await self.app(scope, receive, send_wrapper)
File "/path/python3.9/site-packages/starlette/middleware/authentication.py", line 48, in __call__
await self.app(scope, receive, send)
File "/path/python3.9/site-packages/starlette_context/middleware/raw_middleware.py", line 96, in __call__
await self.app(scope, receive, send_wrapper)
File "/path/python3.9/site-packages/starlette/middleware/cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "/path/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc
File "/path/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/path/python3.9/site-packages/starlette/routing.py", line 656, in __call__
await route.handle(scope, receive, send)
File "/path/python3.9/site-packages/starlette/routing.py", line 259, in handle
await self.app(scope, receive, send)
File "/path/python3.9/site-packages/starlette/routing.py", line 61, in app
response = await func(request)
File "/path/python3.9/site-packages/fastapi_aad_auth/ui/__init__.py", line 123, in login
return self._login(request)
File "/path/python3.9/site-packages/fastapi_aad_auth/ui/__init__.py", line 64, in _login
return self.login_templates.TemplateResponse(self.login_template_path.name, context) # type: ignore
File "/path/python3.9/site-packages/starlette/templating.py", line 87, in TemplateResponse
return _TemplateResponse(
File "/path/python3.9/site-packages/starlette/templating.py", line 33, in __init__
content = template.render(context)
File "/path/python3.9/site-packages/jinja2/environment.py", line 1304, in render
self.environment.handle_exception()
File "/path/python3.9/site-packages/jinja2/environment.py", line 925, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/path/python3.9/site-packages/fastapi_aad_auth/ui/login.html", line 1, in top-level template code
{% extends "fastapi_aad_auth.ui:base.html" %}
File "/path/python3.9/site-packages/jinja2/loaders.py", line 214, in get_source
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: fastapi_aad_auth.ui:base.html
@djpugh: The dev server is running all the time, and it still requires me to log in almost every time I refresh the docs.
Originally posted by @soderluk in #16 (comment)
I've run into a strange problem where I'm suddenly getting a Session states do not match
error when trying to login in my app using fastapi_aad_auth. Everything was working fine and then I suddenly started getting this error, and I'm pretty sure I haven't changed anything.
I can see that the error is raised from state.py, line 91:
Are you able to provide any information on why there might be a mismatch in session states occurring here? I've tried this on two different computers with two different AAD logins, and it is occurring in both situations. I've tried running locally and it is working fine, so I'm only running into the error on the version that is hosted on Azure. I've tried restarting the Azure Functions app, and that hasn't solved it.
Also, on a different note: my boss has just pointed out that I'm working for the same company as you! I'm working with Sam Murphy.
First of all, thanks for your work on the library!
I'm struggling a bit trying to understand the usage of the library though.
How does one protect an API route without the need to have any UI?
I'm reading the docs, but cannot for the life of me figure out how to use this for a plain API.
The authentication works well when using the /docs
endpoint, but e.g. using insomnia and reading endpoints, I just can't get the authentication to work.
Having the dependency in the route auth_state: AuthenticationState = Depends(auth_provider.api_auth_scheme)
shows the auth_state
as None
.
In my main.py
I use
auth_provider = AADAuth()
app = FastAPI(
title=PROJECT_TITLE,
debug=DEBUG,
version=VERSION,
swagger_ui_init_oauth=auth_provider.api_auth_scheme.init_oauth,
)
auth_provider.configure_app(app)
in my routes:
@router.get("/", response_model=List[schemas.Model])
async def list_models(
skip: int = 0,
limit: int = 100,
auth_state: AuthenticationState = Depends(auth_provider.api_auth_scheme),
):
stored = await domain.Model.find_all(skip, limit)
models = [schemas.Model(**model) for model in stored]
return JSONResponse(content=jsonable_encoder(models))
Any help appreciated!
fastapi_aad_auth/src/fastapi_aad_auth/config.py
Lines 71 to 74 in 31dc0fe
TODO
comment in 31dc0fe in #5. cc @djpugh.Originally posted by @todo in #5 (comment)
Hello, i try use your library, but i get some problems
I wrote
import uvicorn
from fastapi import FastAPI, Request, Response, Depends
from starlette.middleware.sessions import SessionMiddleware
import os
from fastapi_sqlalchemy import DBSessionMiddleware
from fastapi_sqlalchemy import db
from models import User as ModelUser
from schema import User as SchemaUser
from dotenv import load_dotenv
from fastapi_aad_auth import AuthenticationState, Config, auth, Authenticator
from fastapi_aad_auth.providers.aad import AADConfig
auth_provider = auth.AADAuth()
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
load_dotenv(os.path.join(BASE_DIR, ".env"))
app = FastAPI()
auth_provider.configure_app(app)
app.add_middleware(DBSessionMiddleware, db_url=os.environ["DATABASE_URL"])
app.add_middleware(SessionMiddleware, secret_key="example")
@app.post("/user/", response_model=SchemaUser)
def create_user(user: SchemaUser):
db_user = ModelUser(
first_name=user.first_name, last_name=user.last_name, age=user.age
)
db.session.add(db_user)
db.session.commit()
return db_user
@app.get("/")
def index(auth_state: AuthenticationState = Depends(auth_provider.auth_backend.requires_auth(allow_session=True))):
print(auth_state)
return {'hello': 'world'}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
But when i try to load 127.0.0.1:8000/docs
, i get an error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 366, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\fastapi\applications.py", line 261, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\middleware\base.py", line 63, in __call__
response = await self.dispatch_func(request, call_next)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\fastapi_sqlalchemy\middleware.py", line 44, in dispatch
response = await call_next(request)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\middleware\base.py", line 44, in call_next
raise app_exc
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\middleware\base.py", line 34, in coro
await self.app(scope, request.receive, send_stream.send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\middleware\sessions.py", line 77, in __call__
await self.app(scope, receive, send_wrapper)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\middleware\authentication.py", line 48, in __call__
await self.app(scope, receive, send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 21, in __call__
raise e
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\routing.py", line 656, in __call__
await route.handle(scope, receive, send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\routing.py", line 259, in handle
await self.app(scope, receive, send)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\routing.py", line 61, in app
response = await func(request)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\fastapi_aad_auth\ui\__init__.py", line 123, in login
return self._login(request)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\fastapi_aad_auth\ui\__init__.py", line 64, in _login
return self.login_templates.TemplateResponse(self.login_template_path.name, context) # type: ignore
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\templating.py", line 90, in TemplateResponse
return _TemplateResponse(
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\starlette\templating.py", line 34, in __init__
content = template.render(context)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\jinja2\environment.py", line 1291, in render
self.environment.handle_exception()
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\jinja2\environment.py", line 926, in handle_exception
raise rewrite_traceback_stack(source=source)
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\fastapi_aad_auth\ui\login.html", line 1, in top-level template code
{% extends "fastapi_aad_auth.ui:base.html" %}
File "C:\Users\andrey\.virtualenvs\backend-9dmwlUHU\lib\site-packages\jinja2\loaders.py", line 218, in get_source
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: fastapi_aad_auth.ui:base.html```
@djpugh I have cloned master branch and ran setup.py install, then i am trying to run tests/testapp/server.py with .env that has AAD_CLIENT_ID,AAD_TENANT_ID and AAD_CLIENT_SECRET
(my-env) PS C:\Users\user1\Downloads\fastapi_aad_auth-master\fastapi_aad_auth-master> uvicorn --host=0.0.0.0 tests.testapp.server:app --reload
?[32mINFO?[0m: Uvicorn running on ?[1mhttp://0.0.0.0:8000?[0m (Press CTRL+C to quit)
?[32mINFO?[0m: Started reloader process [?[36m?[1m24616?[0m] using ?[36m?[1mstatreload?[0m
Process SpawnProcess-1:
Traceback (most recent call last):
File "C:\Users\user1\Anaconda\lib\multiprocessing\process.py", line 258, in _bootstrap
self.run()
File "C:\Users\user1\Anaconda\lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self.kwargs)
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\uvicorn\subprocess.py", line 62, in subprocess_started
target(sockets=sockets)
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\uvicorn\main.py", line 390, in run
loop.run_until_complete(self.serve(sockets=sockets))
File "C:\Users\user1\Anaconda\lib\asyncio\base_events.py", line 484, in run_until_complete
return future.result()
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\uvicorn\main.py", line 397, in serve
config.load()
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\uvicorn\config.py", line 278, in load
self.loaded_app = import_from_string(self.app)
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\uvicorn\importer.py", line 20, in import_from_string
module = importlib.import_module(module_str)
File "C:\Users\user1\Anaconda\lib\importlib_init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 994, in _gcd_import
File "", line 971, in _find_and_load
File "", line 955, in _find_and_load_unlocked
File "", line 665, in _load_unlocked
File "", line 678, in exec_module
File "", line 219, in _call_with_frames_removed
File ".\tests\testapp\server.py", line 11, in
from fastapi_aad_auth import AADAuth, AuthenticationState, Config
File "", line 971, in _find_and_load
File "", line 955, in _find_and_load_unlocked
File "", line 656, in _load_unlocked
File "", line 626, in load_backward_compatible
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\fastapi_aad_auth-0.0.1-py3.6.egg\fastapi_aad_auth_init.py", line 1, in
from fastapi_aad_auth.auth import AADAuth # noqa F401
File "", line 971, in _find_and_load
File "", line 955, in _find_and_load_unlocked
File "", line 656, in _load_unlocked
File "", line 626, in _load_backward_compatible
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\fastapi_aad_auth-0.0.1-py3.6.egg\fastapi_aad_auth\auth.py", line 14, in
from fastapi_aad_auth.config import Config
File "", line 971, in _find_and_load
File "", line 955, in _find_and_load_unlocked
File "", line 656, in load_unlocked
File "", line 626, in load_backward_compatible
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\fastapi_aad_auth-0.0.1-py3.6.egg\fastapi_aad_auth\config.py", line 36, in
class LoginUIConfig(BaseSettings):
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\fastapi_aad_auth-0.0.1-py3.6.egg\fastapi_aad_auth\config.py", line 38, in LoginUIConfig
template_file: FilePath = Field(resource_filename('fastapi_aad_auth.ui', 'login.html'), env='FASTAPI_AUTH_LOGIN_TEMPLATE_FILE')
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\pkg_resources_init.py", line 1143, in resource_filename
self, resource_name
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\pkg_resources_init.py", line 1650, in get_resource_filename
return self.extract_resource(manager, zip_path)
File "C:\Users\user1\downloads\fastapi_aad_auth-master\fastapi_aad_auth-master\my-env\lib\site-packages\pkg_resources_init.py", line 1671, in _extract_resource
timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
KeyError: 'fastapi_aad_auth\ui\login.html'
It will be also great help if you can share any articles that you published for using this package
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.