As far as my searches could tell, I could not find any solid information on how to go about doing this (i may be missing something obvious):
I currently have an api using the documented password oauth flow, however I am now in the process of upgrading this flow to something more robust as the password flow is not recommended in most cases. I have selected a client_credentials type flow and have built an authorization server to generate JWT tokens. Now, in order to 'log in' via the openAPI UI, one must retrieve a JWT token from this authorization server which can be decoded to access relevant endpoints. How can i modify the openAPI UI to utilise the usual 'authorize' button but instead of taking username & password, only take client_id, client_secret and scope. Is there a base class i can take that such as this Oauth2 class which can be modified or used to hit the authorization server and retrieve a token?
Thanks for any help in advance
I think I found the solution for others looking to implement the code - tiangolo has already enabled this. instead of using:
oauth2_scheme = Oauth2PasswordBearer(
tokenUrl=JWT_TOKEN_URL, scopes={"foo": "bar"}
)
you create your own version of the Oauth2PasswordBearer class like so:
class Oauth2ClientCredentials(OAuth2):
def __init__(
self,
tokenUrl: str,
scheme_name: str = None,
scopes: dict = None,
auto_error: bool = True,
):
if not scopes:
scopes = {}
flows = OAuthFlowsModel(clientCredentials={"tokenUrl": tokenUrl, "scopes": scopes})
super().__init__(flows=flows, scheme_name=scheme_name, auto_error=auto_error)
async def __call__(self, request: Request) -> Optional[str]:
authorization: str = request.headers.get("Authorization")
scheme, param = get_authorization_scheme_param(authorization)
if not authorization or scheme.lower() != "bearer":
if self.auto_error:
raise HTTPException(
status_code=HTTP_401_UNAUTHORIZED,
detail="Not authenticated",
headers={"WWW-Authenticate": "Bearer"},
)
else:
return None
return param
with the key difference being a line change here:
flows = OAuthFlowsModel(clientCredentials={"tokenUrl": tokenUrl, "scopes": scopes})
to take the fastAPI model clientCredentials instead of Password. Hope that helps anyone else that gets stuck with this. It is actually in the documentation but it was not immediately apparent to me that I needed to do this. +1 for easy to understand source code :)
Thanks for reporting back and closing the issue @Charlie-iProov :+1:
Yeah, there's some extra docs and even classes missing :sweat_smile: :memo:
Most helpful comment
I think I found the solution for others looking to implement the code - tiangolo has already enabled this. instead of using:
you create your own version of the
Oauth2PasswordBearerclass like so:with the key difference being a line change here:
flows = OAuthFlowsModel(clientCredentials={"tokenUrl": tokenUrl, "scopes": scopes})to take the fastAPI model clientCredentials instead of Password. Hope that helps anyone else that gets stuck with this. It is actually in the documentation but it was not immediately apparent to me that I needed to do this. +1 for easy to understand source code :)