Ajout JWTAuthenticationBackend (from https://github.com/amitripshtos/starlette-jwt/blob/master/starlette_jwt/middleware.py).
This commit is contained in:
parent
d1e3198441
commit
dada376016
|
@ -136,3 +136,5 @@ dmypy.json
|
|||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
domains/
|
||||
|
|
|
@ -9,9 +9,10 @@ from starlette.exceptions import HTTPException
|
|||
from starlette.middleware import Middleware
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import Response
|
||||
from starlette.responses import Response, JSONResponse
|
||||
from starlette.routing import Route, Match, Mount
|
||||
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||
from starlette.middleware.authentication import AuthenticationMiddleware
|
||||
|
||||
# typing
|
||||
from typing import Any, Awaitable, Callable, MutableMapping
|
||||
|
@ -26,6 +27,7 @@ from .models.api.view.route import Route as RouteView
|
|||
|
||||
# module libraries
|
||||
from .lib.responses import ForbiddenResponse, NotFoundResponse
|
||||
from .lib.jwt_middleware import JWTAuthenticationBackend
|
||||
|
||||
def match_route(app: ASGIApp, scope: Scope):
|
||||
""" Checks all routes from "app" and checks if it matches with the one from
|
||||
|
@ -215,7 +217,13 @@ def startup():
|
|||
sys.stderr.write(str(e))
|
||||
sys.exit(1)
|
||||
|
||||
async def root(request):
|
||||
return JSONResponse({'payload': request.payload})
|
||||
|
||||
app = Starlette(
|
||||
middleware=[Middleware(AclCallerMiddleware)],
|
||||
on_startup=[startup]
|
||||
middleware=[
|
||||
Middleware(AuthenticationMiddleware, backend=JWTAuthenticationBackend(secret_key=open('/etc/half_orm/secret').read())),
|
||||
Middleware(AclCallerMiddleware),
|
||||
],
|
||||
on_startup=[startup],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
__LICENSE__ = """
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018, Amit Ripshtos
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import jwt
|
||||
from uuid import UUID
|
||||
from starlette.authentication import (
|
||||
AuthenticationBackend, AuthenticationError, BaseUser, AuthCredentials,
|
||||
UnauthenticatedUser)
|
||||
|
||||
|
||||
class JWTUser(BaseUser):
|
||||
def __init__(self, id: UUID, token: str, payload: dict) -> None:
|
||||
self.__id = id
|
||||
self.token = token
|
||||
self.payload = payload
|
||||
|
||||
@property
|
||||
def is_authenticated(self) -> bool:
|
||||
return True
|
||||
|
||||
@property
|
||||
def id(self) -> str:
|
||||
return self.id
|
||||
|
||||
|
||||
class JWTAuthenticationBackend(AuthenticationBackend):
|
||||
|
||||
def __init__(self, secret_key: str, algorithm: str = 'HS256', prefix: str = 'JWT', name: str = 'name'):
|
||||
self.secret_key = secret_key
|
||||
self.algorithm = algorithm
|
||||
self.prefix = prefix
|
||||
self.id = id
|
||||
|
||||
async def authenticate(self, request):
|
||||
if "Authorization" not in request.headers:
|
||||
return None
|
||||
|
||||
token = request.headers["Authorization"]
|
||||
try:
|
||||
payload = jwt.decode(token, key=self.secret_key, algorithms=self.algorithm)
|
||||
except jwt.InvalidTokenError as e:
|
||||
raise AuthenticationError(str(e))
|
||||
|
||||
return AuthCredentials(["authenticated"]), JWTUser(
|
||||
id=payload['id'], token=token, payload=payload)
|
||||
|
||||
|
||||
class JWTWebSocketAuthenticationBackend(AuthenticationBackend):
|
||||
|
||||
def __init__(self, secret_key: str, algorithm: str = 'HS256', query_param_name: str = 'jwt',
|
||||
id: UUID = None, audience = None, options = {}):
|
||||
self.secret_key = secret_key
|
||||
self.algorithm = algorithm
|
||||
self.query_param_name = query_param_name
|
||||
self.id = id
|
||||
self.audience = audience
|
||||
self.options = options
|
||||
|
||||
|
||||
async def authenticate(self, request):
|
||||
if self.query_param_name not in request.query_params:
|
||||
return AuthCredentials(), UnauthenticatedUser()
|
||||
|
||||
token = request.query_params[self.query_param_name]
|
||||
|
||||
try:
|
||||
payload = jwt.decode(token, key=self.secret_key, algorithms=self.algorithm,
|
||||
audience=self.audience, options=self.options)
|
||||
except jwt.InvalidTokenError as e:
|
||||
raise AuthenticationError(str(e))
|
||||
|
||||
return AuthCredentials(["authenticated"]), JWTUser(id = payload['id'],
|
||||
token=token, payload=payload)
|
|
@ -1,4 +1,5 @@
|
|||
starlette
|
||||
uvicorn
|
||||
jwt
|
||||
half_orm @ git+ssh://git@gite.lirmm.fr/newsi/halfORM.git
|
||||
apidb @ git+ssh://git@gite.lirmm.fr/newsi/db/hop_api.git
|
||||
|
|
Loading…
Reference in New Issue