The Authlib documentation describes how a resource server can validate the auth_token from the client implementing a BearerTokenValidator as such:
class MyBearerTokenValidator(BearerTokenValidator):
def authenticate_token(self, token_string):
return Token.query.filter_by(access_token=token_string).first()
require_oauth = ResourceProtector()
require_oauth.register_token_validator(MyBearerTokenValidator())
# protecting the resource
@app.route('/user')
@require_oauth()
def user_profile():
user = current_token.user
return jsonify(user)
https://docs.authlib.org/en/stable/flask/2/resource-server.html
This solution assumes the Resource server has access to the db where the Authentication server (AS) manages the token, using the ORM tool like SQLAlchemy.
In my case, I don't have access to the token db and the AS only provides a REST introspection endpoint to validate whether the token is valid.
I am planning to use the requests library and pass the token to the AS to implement my token validator
class MyBearerTokenValidator(BearerTokenValidator):
def authenticate_token(self, token_string):
resp = requests.post("https://oauth-server-host/oauth/v2/introspection", auth=(id, secret), data={"token": "TK"})
return resp.json()
Is this the correct approach or is there a better, more standard approach?
According to the Authlib documentation, there is a built-in approach to this problem. Thanks @lepture for pointing this out in the comments.
We can extend a built-in IntrospectTokenValidator to implement our validator.
from authlib.oauth2.rfc7662 import IntrospectTokenValidator
from your_project import secrets
class MyIntrospectTokenValidator(IntrospectTokenValidator):
def introspect_token(self, token_string):
url = 'https://example.com/oauth/introspect'
data = {'token': token_string, 'token_type_hint': 'access_token'}
auth = (secrets.internal_client_id, secrets.internal_client_secret)
resp = requests.post(url, data=data, auth=auth)
return resp.json()
We can then register this token validator in to resource protector:
require_oauth = ResourceProtector()
require_oauth.register_token_validator(MyIntrospectTokenValidator())
Source https://docs.authlib.org/en/latest/specs/rfc7662.html#use-introspection-in-resource-server