dorinclisu / fastapi-auth0

FastAPI authentication and authorization using auth0.com
MIT License
230 stars 37 forks source link

pydantic validation error without scope #36

Closed AlexGisi closed 1 year ago

AlexGisi commented 1 year ago

I tried the simple example without the scoping:

from fastapi import FastAPI, Depends, Security
from fastapi_auth0 import Auth0, Auth0User

auth = Auth0(
    domain='...',
    api_audience='...',
)
app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/secure", dependencies=[Depends(auth.implicit_scheme)])
def get_secure(user: Auth0User = Security(auth.get_user)):
    return {"message": f"{user}"}

and authenticated a user. But when I tried to execute the /secure endpoint, it returns

{
  "detail": "Error parsing Auth0User"
}

and the console error

Handled exception parsing Auth0User: "1 validation error for Auth0User
permissions
  Field required [type=missing, input_value={'iss': 'https://dev-aos6...CCDkOMHVc', 'scope': ''}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.1/v/missing"
Traceback (most recent call last):
  File "~/server/venv/lib/python3.9/site-packages/fastapi_auth0/auth.py", line 219, in get_user
    user = self.auth0_user_model(**payload)
  File "~/server/venv/lib/python3.9/site-packages/pydantic/main.py", line 159, in __init__
    __pydantic_self__.__pydantic_validator__.validate_python(data, self_instance=__pydantic_self__)
pydantic_core._pydantic_core.ValidationError: 1 validation error for Auth0User
permissions
  Field required [type=missing, input_value={'iss': 'https://dev-aos6...CCDkOMHVc', 'scope': ''}, input_type=dict]

Am I missing a piece of syntax?

dorinclisu commented 1 year ago

You are not missing anything in the code.

As I can see from the error, the permissions field is not included in the token, so turning on RBAC for the API should be an easy workaround.

But the issue is caused by breaking changes of Pydantic v2 which now requires a default for Optional[] types.

isomogyi commented 1 year ago

The breaking change as one can read is that the field is now required https://docs.pydantic.dev/2.0/migration/#required-optional-and-nullable-fields

For minimizing the impact, one can assign None to the permissions in the model:

class Auth0User(BaseModel):
    id:                          str = Field(..., alias='sub')
    permissions: Optional[List[str]] = None
    email:             Optional[str] = Field(None, alias=f'{auth0_rule_namespace}/email')  # type: ignore [literal-required]
alex-does-stuff commented 1 year ago

Did you experience any issue with just adding the None assignment. I've monkey-patched that myself and it seems to be working.

isomogyi commented 1 year ago

It was the only issue I found so far. Would be great if it could be fixed in your official repo.

jw commented 1 year ago

Any progress on this? Or should I fork?

dorinclisu commented 1 year ago

Fixed in 0.5.0