FastAPI - 支持基本身份验证或 JWT 身份验证来访问端点

问题描述 投票:0回答:1

参考此链接: fastapi 支持多重身份验证依赖项

我认为这是最接近我需要的,但不知何故我无法让任何一个依赖项工作,因为 fastapi 在授予对端点的访问权限之前会强制执行这两个依赖项。

自定义依赖关系的片段:

def basic_logged_user(credentials: Annotated[HTTPBasicCredentials, Depends(security)]):
    current_username_bytes = credentials.username.encode("utf8")
    correct_username_bytes = settings.SESSION_LOGIN_USER.encode("utf8")
    is_correct_username = secrets.compare_digest(
        current_username_bytes, correct_username_bytes
    )
    current_password_bytes = credentials.password.encode("utf8")
    correct_password_bytes = settings.SESSION_LOGIN_PASS.encode("utf8")
    is_correct_password = secrets.compare_digest(
        current_password_bytes, correct_password_bytes
    )

    if not (is_correct_username and is_correct_password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid Credentials",
            headers={"WWW-Authenticate": "Basic"},
        )
    return credentials.username


def jwt_logged_user(token: str = Depends(utils.OAuth2_scheme), 
                    db: Session = Depends(db_session)):
    credential_exception = HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
                                         detail="Incorrect username or password",
                                         headers={"WWW-Authenticate": "Bearer"})

    token = utils.verify_token(token, credential_exception)
    user = db.query(User).filter(User.username == token.username).first()

    return user


# custom auth
def auth_user(jwt_auth: HTTPBearer = Depends(jwt_logged_user), 
                    basic_auth: HTTPBasic = Depends(basic_logged_user)):
    if not (jwt_auth or basic_auth):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, 
                            detail='Invalid Credentials')


#endpoint
@router.get("/")
async def get_users(db: Session = Depends(db_session), logged_user: str = Depends(auth_user)):
    query_users = db.query(User).all()

    return query_users

当我为 JWT 身份验证或基本身份验证提供正确的凭据时,我希望它能够授予我对端点的访问权限,但它仍然迫使我为两者输入凭据。我如何才能实现提供两个身份验证中的任何一个而不是同时提供两个身份验证的效果。

python oauth-2.0 jwt fastapi basic-authentication
1个回答
0
投票

这个想法是让所有这些安全依赖关系都不会在依赖关系解析阶段引发用户身份验证错误的异常。

对于

HTTPBasic
通过
auto_error=False

security = HTTPBasic(auto_error=False)

然后在

basic_logged_user
你应该检查一下

def basic_logged_user(credentials: Annotated[Optional[HTTPBasicCredentials], Depends(security)]):
    if credentials is None:
        return None
    ...
    # Do not raise exception, but return None instead

您需要找到对第二个身份验证方案执行相同操作的方法 (

utils.OAuth2_scheme
) - 不提高
HTTP_401_UNAUTHORIZED
,而是返回
None

然后您的

auth_user
将按您的预期工作。仅当两个方案都返回
HTTP_401_UNAUTHORIZED
时,它才会提高
None

© www.soinside.com 2019 - 2024. All rights reserved.