When creating an API endpoint, and trying to access it with a user issued token in the request Header, it's saying access denied for the newly created permission on the api class denied.
If you'd like to report a bug in Flask-Appbuilder, fill out the template below. Provide any extra information that may be useful
Responsible disclosure: We want to keep Flask-AppBuilder safe for everyone. If you've discovered a security vulnerability please report to [email protected].
Environment
Flask-Appbuilder version: 4.1.4
pip freeze output: aiocache==0.11.1 aiofiles==0.8.0 aiohttp==3.8.1 aiohttp-swagger==1.0.16 aiosignal==1.2.0 ansible==3.0.0 ansible-base==2.10.6 ansible-compat==2.2.1 ansible-core==2.13.4 ansible-lint==6.8.0 ansible-runner==2.3.1 apispec==3.3.2 appdirs==1.4.4 astroid==2.5 async-lru==1.0.3 async-timeout==4.0.2 attrs==22.1.0 Babel==2.10.3 bcrypt==3.2.0 black==23.1.0 bmc-helix-inventory==0.10.0 bracex==2.3.post1 cached-property==1.5.2 certifi==2020.12.5 cffi==1.14.5 chardet==4.0.0 charset-normalizer==2.1.0 cisco-gnmi==1.0.15 ciscoconfparse==1.6.40 click==8.1.3 colorama==0.4.5 commonmark==0.9.1 cryptography==3.4.6 defusedxml==0.7.1 dill==0.3.5.1 distlib==0.3.1 distro==1.7.0 dnspython==2.2.1 docker==4.4.4 docutils==0.19 email-validator==1.3.0 exceptiongroup==1.1.0 f5-icontrol-rest==1.3.13 f5-sdk==3.0.21 fastapi==0.68.2 filelock==3.0.12 Flask==2.2.2 Flask-AppBuilder==4.1.4 Flask-Babel==2.0.0 Flask-JWT-Extended==4.4.4 Flask-Login==0.6.2 flask-mongoengine==1.0.0 Flask-SQLAlchemy==2.5.1 Flask-WTF==1.0.1 frozenlist==1.3.0 future==0.18.2 genie==22.7 genie.libs.clean==22.7 genie.libs.conf==22.7 genie.libs.filetransferutils==22.7 genie.libs.health==22.7 genie.libs.ops==22.7 genie.libs.parser==22.7 genie.libs.sdk==22.7 gitdb==4.0.9 GitPython==3.1.18 greenlet==1.1.3.post0 grpcio==1.47.0 idna==2.10 importlib-metadata==5.0.0 importlib-resources==5.10.0 iniconfig==1.1.1 invoke==1.5.0 IPy==1.1 isodate==0.6.0 isort==5.7.0 itsdangerous==2.1.2 Jinja2==3.1.2 jsonify==0.5 jsonpickle==2.2.0 jsonschema==4.16.0 junit-xml==1.9 junos-eznc==2.6.4 lazy-object-proxy==1.5.2 lockfile==0.12.2 loguru==0.6.0 lxml==4.6.3 Markdown==3.4.1 MarkupSafe==2.1.1 marshmallow==3.18.0 marshmallow-enum==1.5.1 marshmallow-sqlalchemy==0.26.1 mccabe==0.6.1 mongo==0.2.0 mongoengine==0.24.2 multidict==6.0.2 mypy-extensions==0.4.3 ncclient==0.6.13 netaddr==0.8.0 netmiko==3.4.0 ntc-templates==3.0.0 numpy==1.21.3 packaging==23.0 pandas==1.3.4 paramiko==2.7.2 passlib==1.7.4 pathspec==0.10.1 pexpect==4.8.0 pii==0.0.1 pkgutil_resolve_name==1.3.10 platformdirs==2.5.2 pluggy==0.13.1 prettytable==3.3.0 prison==0.2.1 protobuf==3.20.1 psutil==5.9.1 ptyprocess==0.7.0 py==1.10.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pyats==22.7.1 pyats.aereport==22.7 pyats.aetest==22.7 pyats.async==22.7 pyats.connections==22.7 pyats.datastructures==22.7 pyats.easypy==22.7 pyats.kleenex==22.7 pyats.log==22.7 pyats.reporter==22.7 pyats.results==22.7 pyats.tcl==22.7 pyats.topology==22.7 pyats.utils==22.7 pycparser==2.20 pydantic==1.9.2 pyeapi==0.8.4 pyftpdlib==1.5.6 Pygments==2.13.0 PyJWT==2.5.0 pylint==2.7.0 pymongo==4.2.0 PyNaCl==1.4.0 pyntc==0.20.1 pynxos==0.0.5 pyparsing==3.0.9 pyrsistent==0.18.1 pyserial==3.5 pytest==7.2.1 python-daemon==2.3.2 python-dateutil==2.8.2 python-dotenv==0.10.5 python-engineio==3.14.2 python-ldap==3.4.3 python-socketio==4.6.1 pytz==2022.5 PyYAML==5.4.1 regex==2020.11.13 requests==2.25.1 requests-file==1.5.1 requests-toolbelt==0.9.1 resolvelib==0.8.1 rich==12.6.0 ruamel.yaml==0.17.21 ruamel.yaml.clib==0.2.6 scp==0.13.6 six==1.16.0 smmap==5.0.0 SQLAlchemy==1.4.42 SQLAlchemy-Utils==0.38.3 starlette==0.14.2 style==1.1.0 subprocess-tee==0.3.5 tenacity==8.0.1 textfsm==1.1.3 tftpy==0.8.0 toml==0.10.2 tomli==2.0.1 tox==3.22.0 tqdm==4.64.0 transitions==0.8.11 typed-ast==1.4.2 typing-extensions==3.10.0.2 unicon==22.7 unicon.plugins==22.7 update==0.0.1 urllib3==1.26.3 virtualenv==20.4.2 wcmatch==8.4.1 wcwidth==0.2.5 websocket-client==0.57.0 Werkzeug==2.2.2 wrapt==1.12.1 WTForms==3.0.1 xmltodict==0.13.0 yamllint==1.27.1 yamlordereddictloader==0.4.0 yang.connector==22.7 yarl==1.7.2 zeep==4.0.0 zipp==3.9.0
Describe the expected results
Tell us what should happen.
Sending a request like this:
curl 'http://localhost:8080/secured/security' -H "Authorization: Bearer $TOKEN"
TOKEN Has the issued token returned from an user in the mongodb database using create_access_token from flask_jwt_extended.
With the api endpoint written like this:
from flask_appbuilder.security.decorators import protect, has_access_api
from flask_appbuilder.api import BaseApi, expose
from flask import request
class SecuredApi(BaseApi):
"""Greeting API Test."""
route_base = "/secured"
@has_access_api
@expose("/security")
@protect()
def security_test(self):
return self.response(200, message="This is private")
It should return a response with the message "This is private".
Describe the actual results
Tell us what happens instead.
But instead returns this message:
{
"message": "Access is Denied",
"severity": "danger"
}
In the flask app output log will say this:
2023-03-07 14:59:29,400:WARNING:flask_appbuilder.security.decorators:Access is Denied for: can_security_test on: SecuredApi
2023-03-07 14:59:29,403:INFO:werkzeug:127.0.0.1 - - [07/Mar/2023 14:59:29] "GET /secured/security HTTP/1.1" 401 -
Steps to reproduce
Write and expose the same api endpoint code, run the flask app, and send the get method from the curl line.
When checking the permissions on the view from SecuredApi, it does have can_security_test permissions, assigned to the role of the user.
Hi,
Use the @protect() decorator instead, https://flask-appbuilder.readthedocs.io/en/latest/rest_api.html#security