我正在尝试在我的烧瓶应用程序中添加oauth2(服务器),并且/oauth/token
端点和client_secret_post
出现了一些问题。
我的应用程序将以下内容以表单形式发布到它:
client_id=XXX
client_secret=YYY
grant_type=client_credentials
token_endpoint_auth_method=client_secret_post
redirect_uri=http://localhost:8081/oauth-callback
然后进入日志:
DEBUG:authlib.oauth2.rfc6749.authenticate_client:Authenticate None via "client_secret_basic" failed
127.0.0.1 - - [23/Jun/2019 18:05:26] "POST /oauth/token HTTP/1.0" 401 -
token_endpoint_auth_method
似乎没有任何改变,它总是返回{"error": "invalid_client"}
。
我尝试将TOKEN_ENDPOINT_AUTH_METHODS = ['client_secret_post']
添加到我的class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
中而没有任何影响(也没有记录器显示任何内容)。
我在那里错过了什么?
我或多或少已经在我的应用程序中实现了一些东西,例如oauth2 flask示例,这里有一些摘录:
app.py:
from app_oauth import config_oauth
...
def create_app(...):
...
config_oauth(app)
...
app_oauth.py:
from authlib.flask.oauth2 import AuthorizationServer, ResourceProtector
from authlib.flask.oauth2.sqla import (
create_query_client_func,
create_save_token_func,
create_revocation_endpoint,
create_bearer_token_validator,
)
from authlib.oauth2.rfc6749 import grants
from werkzeug.security import gen_salt
from models import db, User
from models import OAuth2Client, OAuth2AuthorizationCode, OAuth2Token
from flask import current_app
class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
def create_authorization_code(self, client, user, request):
current_app.logger.debug("create auth code")
code = gen_salt(48)
item = OAuth2AuthorizationCode(
code=code,
client_id=client.client_id,
redirect_uri=request.redirect_uri,
scope=request.scope,
user_id=user.get_user_id(),
)
db.session.add(item)
db.session.commit()
return code
def parse_authorization_code(self, code, client):
current_app.logger.debug("parse auth code")
item = OAuth2AuthorizationCode.query.filter_by(
code=code, client_id=client.client_id).first()
if item and not item.is_expired():
return item
def delete_authorization_code(self, authorization_code):
current_app.logger.debug("delete auth code")
db.session.delete(authorization_code)
db.session.commit()
def authenticate_user(self, authorization_code):
current_app.logger.debug("auth user")
return User.query.get(authorization_code.user_id)
class PasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant):
def authenticate_user(self, username, password):
current_app.logger.debug("password grant auth user")
user = User.query.filter_by(name=username).first()
if user.check_password(password):
return user
class RefreshTokenGrant(grants.RefreshTokenGrant):
def authenticate_refresh_token(self, refresh_token):
current_app.logger.debug("refresh token grant")
token = OAuth2Token.query.filter_by(refresh_token=refresh_token).first()
if token and not token.revoked and not token.is_refresh_token_expired():
return token
def authenticate_user(self, credential):
current_app.logger.debug("auth user grant user")
return User.query.get(credential.user_id)
query_client = create_query_client_func(db.session, OAuth2Client)
save_token = create_save_token_func(db.session, OAuth2Token)
authorization = AuthorizationServer(
query_client=query_client,
save_token=save_token,
)
require_oauth = ResourceProtector()
def config_oauth(app):
authorization.init_app(app)
# support all grants
authorization.register_grant(grants.ImplicitGrant)
authorization.register_grant(grants.ClientCredentialsGrant)
authorization.register_grant(AuthorizationCodeGrant)
authorization.register_grant(PasswordGrant)
authorization.register_grant(RefreshTokenGrant)
# support revocation
revocation_cls = create_revocation_endpoint(db.session, OAuth2Token)
authorization.register_endpoint(revocation_cls)
# protect resource
bearer_cls = create_bearer_token_validator(db.session, OAuth2Token)
require_oauth.register_token_validator(bearer_cls())
和我的蓝图:
from app_oauth import authorization
...
@bp_api_v1_auth.route("/oauth/token", methods=["POST"])
def oauth_token():
return authorization.create_token_response()
编辑:在挖掘之后,它看起来像是由ClientCredentialsGrant处理的,默认情况下它仅执行client_secret_basic
,然后我添加了:
class ClientCredentialsGrant(grants.ClientCredentialsGrant):
TOKEN_ENDPOINT_AUTH_METHODS = [
'client_secret_basic', 'client_secret_post'
]
...
authorization.register_grant(ClientCredentialsGrant)
现在可以验证但回复{"error": "unauthorized_client"}
答案 0 :(得分:0)
最后钉上它:我在数据库中的OAuth2Client条目只有authorization_code
和password
,client_credentials
才需要验证。