2023-07-07 09:53:56 +08:00
|
|
|
import time
|
2019-07-10 17:34:45 +08:00
|
|
|
from aiohttp_auth import auth
|
2023-07-07 09:53:56 +08:00
|
|
|
from aiohttp_auth.auth.ticket_auth import TktAuthentication
|
2019-07-10 17:34:45 +08:00
|
|
|
from os import urandom
|
|
|
|
from aiohttp import web
|
|
|
|
import aiohttp_session
|
2023-07-18 18:25:59 +08:00
|
|
|
import aioredis
|
2023-04-05 23:28:17 +08:00
|
|
|
import base64
|
2019-07-10 17:34:45 +08:00
|
|
|
|
|
|
|
from aiohttp_session import get_session, session_middleware
|
|
|
|
from aiohttp_session.cookie_storage import EncryptedCookieStorage
|
2023-07-18 18:25:59 +08:00
|
|
|
from aiohttp_session.redis_storage import RedisStorage
|
2019-07-10 17:34:45 +08:00
|
|
|
|
2020-02-26 17:24:07 +08:00
|
|
|
from appPublic.jsonConfig import getConfig
|
2022-09-27 14:03:16 +08:00
|
|
|
from appPublic.rsawrap import RSA
|
2022-06-23 14:58:03 +08:00
|
|
|
from appPublic.app_logger import AppLogger
|
2023-07-18 18:25:59 +08:00
|
|
|
|
2022-06-23 14:58:03 +08:00
|
|
|
class AuthAPI(AppLogger):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
2023-06-12 14:05:23 +08:00
|
|
|
self.conf = getConfig()
|
2020-02-26 17:24:07 +08:00
|
|
|
|
2023-07-04 12:02:13 +08:00
|
|
|
async def checkUserPermission(self, user, path):
|
2023-07-05 11:12:39 +08:00
|
|
|
print('************* checkUserPermission() use default one ****************')
|
2023-07-04 12:02:13 +08:00
|
|
|
return True
|
|
|
|
|
2020-02-26 17:24:07 +08:00
|
|
|
def getPrivateKey(self):
|
|
|
|
if not hasattr(self,'rsaEngine'):
|
|
|
|
self.rsaEngine = RSA()
|
|
|
|
fname = self.conf.website.rsakey.privatekey
|
|
|
|
self.privatekey = self.rsaEngine.read_privatekey(fname)
|
|
|
|
return self.privatekey
|
|
|
|
|
|
|
|
def rsaDecode(self,cdata):
|
|
|
|
self.getPrivateKey()
|
|
|
|
return self.rsaEngine.decode(self.privatekey,cdata)
|
|
|
|
|
2023-07-19 11:38:09 +08:00
|
|
|
async def setupAuth(self,app):
|
2019-07-10 17:34:45 +08:00
|
|
|
# setup session middleware in aiohttp fashion
|
2023-07-18 18:25:59 +08:00
|
|
|
|
2019-07-10 17:34:45 +08:00
|
|
|
storage = EncryptedCookieStorage(urandom(32))
|
2023-07-18 18:25:59 +08:00
|
|
|
if self.conf.website.session_redis:
|
|
|
|
url = self.conf.website.session_redis.url
|
|
|
|
# redis = await aioredis.from_url("redis://127.0.0.1:6379")
|
|
|
|
redis = await aioredis.from_url(url)
|
|
|
|
storage = aiohttp_session.redis_storage.RedisStorage(redis)
|
2019-07-10 17:34:45 +08:00
|
|
|
aiohttp_session.setup(app, storage)
|
|
|
|
|
|
|
|
# Create an auth ticket mechanism that expires after 1 minute (60
|
|
|
|
# seconds), and has a randomly generated secret. Also includes the
|
|
|
|
# optional inclusion of the users IP address in the hash
|
2023-06-12 14:05:23 +08:00
|
|
|
session_max_time = 120
|
|
|
|
session_reissue_time = 30
|
|
|
|
if self.conf.website.session_max_time:
|
|
|
|
session_max_time = self.conf.website.session_max_time
|
|
|
|
if self.conf.website.session_reissue_time:
|
|
|
|
session_reissue_time = self.conf.website.session_reissue_time
|
|
|
|
|
2023-07-07 09:53:56 +08:00
|
|
|
def _get_ip(self,request):
|
|
|
|
ip = request.headers.get('X-Forwarded-For')
|
|
|
|
if not ip:
|
|
|
|
ip = request.remote
|
|
|
|
return ip
|
|
|
|
|
|
|
|
def _new_ticket(self, request, user_id):
|
|
|
|
client_uuid = request.headers.get('client_uuid')
|
|
|
|
ip = self._get_ip(request)
|
|
|
|
if not ip:
|
|
|
|
ip = request.remote
|
|
|
|
valid_until = int(time.time()) + self._max_age
|
|
|
|
print(f'hack: my _new_ticket() called ...remote {ip=}, {client_uuid=}')
|
|
|
|
return self._ticket.new(user_id, valid_until=valid_until, client_ip=ip, user_data=client_uuid)
|
|
|
|
|
|
|
|
TktAuthentication._get_ip = _get_ip
|
|
|
|
TktAuthentication._new_ticket = _new_ticket
|
2023-06-12 14:05:23 +08:00
|
|
|
policy = auth.SessionTktAuthentication(urandom(32), session_max_time,
|
2023-06-30 14:46:08 +08:00
|
|
|
reissue_time=session_reissue_time,
|
2019-07-10 17:34:45 +08:00
|
|
|
include_ip=True)
|
|
|
|
|
|
|
|
# setup aiohttp_auth.auth middleware in aiohttp fashion
|
2023-04-06 16:20:19 +08:00
|
|
|
# print('policy = ', policy)
|
2019-07-10 17:34:45 +08:00
|
|
|
auth.setup(app, policy)
|
2023-06-12 14:54:49 +08:00
|
|
|
print('add auth middleware ....................')
|
2019-07-10 17:34:45 +08:00
|
|
|
app.middlewares.append(self.checkAuth)
|
|
|
|
|
|
|
|
@web.middleware
|
|
|
|
async def checkAuth(self,request,handler):
|
2023-07-05 11:22:13 +08:00
|
|
|
print('checkAuth() called ..................')
|
2019-07-10 17:34:45 +08:00
|
|
|
path = request.path
|
|
|
|
user = await auth.get_auth(request)
|
2023-04-04 10:34:02 +08:00
|
|
|
is_ok = await self.checkUserPermission(user, path)
|
|
|
|
if is_ok:
|
2019-07-10 17:34:45 +08:00
|
|
|
return await handler(request)
|
2023-06-15 10:38:32 +08:00
|
|
|
if user is None:
|
2023-06-25 11:04:41 +08:00
|
|
|
print(f'**{user=}, {path} need login**')
|
2023-06-15 10:38:32 +08:00
|
|
|
raise web.HTTPUnauthorized
|
2023-06-25 11:04:41 +08:00
|
|
|
print(f'**{user=}, {path} forbidden**')
|
2019-07-10 17:34:45 +08:00
|
|
|
raise web.HTTPForbidden()
|
|
|
|
|
|
|
|
async def needAuth(self,path):
|
|
|
|
return False
|
|
|
|
|