使用 Okta 与 React (typescript) 和 FastAPI (python) 进行 SSO

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

我使用 @okta/okta-react 和 @okta/okta-auth-js 包在前端 (React) 上实现了 Okta 授权。

在 Okta 端,我创建了使用“OIDC - OpenID Connect”登录方法并具有“单页应用程序”应用程序类型的应用程序。

对于 python(后端),我可以使用 okta-jwt-verifier-python 包,但我不知道如何构建整个流程以访问后端的用户信息。

你能帮我写一下,接下来的步骤是什么吗? 如何正确地从前端传递身份验证信息(令牌)以及如何在后端验证它? 如何通过 Okta 令牌获取后端的用户信息? 我需要在 Okta 中再创建一个应用程序作为后端吗?

我尝试在 FastAPI 中创建中间件,但它看起来像是解决方法,如果我决定使用内置 swagger 接口测试 API,它将无法工作

reactjs single-sign-on fastapi okta
1个回答
0
投票

我已经使用

okta-jwt-verifier
python 包解决了我的问题。它也可以通过 FastAPI 的 Web 界面运行,但您应该使用有效的 Bearer 令牌。

我使用下一个代码创建了新文件(

auth_utils.py
)来实现验证:

# The goal of this file is to check whether the request is authorized or not [ verification of the protected route]
from fastapi import Request, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from okta_jwt_verifier import BaseJWTVerifier
from okta_jwt_verifier.exceptions import JWTValidationException


class JWTBearer(HTTPBearer):
    def __init__(self, auto_error: bool = True):
        super(JWTBearer, self).__init__(auto_error=auto_error)

    async def __call__(self, request: Request):
        credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)
        if credentials:
            if not credentials.scheme == "Bearer":
                raise HTTPException(status_code=403, detail="Invalid authentication scheme.")

            try:
                await self.verify_jwt(credentials.credentials)
            except JWTValidationException as e:
                message = ''.join(e.args)
                raise HTTPException(status_code=403, detail=message)

            return credentials.credentials
        else:
            raise HTTPException(status_code=403, detail="Invalid authorization code.")

    async def verify_jwt(self, jwtoken: str):
        jwt_verifier = BaseJWTVerifier('https://your-issuer-domain.okta.com',
                                       'your_client_id',
                                       'api://default')
        await jwt_verifier.verify_access_token(jwtoken)

并以接下来的方式使用

JWTBearer
类来保护您想要保护的任何路由:

@app.get("/protected/endpoint", dependencies=[Depends(JWTBearer())])
async def protected_endpoint():
    return "It will work only with valid JWT token ;)"

但请注意,您应该从前端应用程序传递

Authorization
标头!

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