WGDashboard/src/modules/DashboardOIDC.py

95 lines
3.0 KiB
Python
Raw Normal View History

import os
import json
import requests
from jose import jwt
2025-06-29 21:18:20 +08:00
import certifi
class DashboardOIDC:
ConfigurationPath = os.getenv('CONFIGURATION_PATH', '.')
ConfigurationFilePath = os.path.join(ConfigurationPath, 'wg-dashboard-oidc-providers.json')
def __init__(self):
self.providers: dict[str, dict] = None
self.__default = {
'Provider': {
'client_id': '',
'client_secret': '',
'issuer': '',
},
}
if not os.path.exists(DashboardOIDC.ConfigurationFilePath):
with open(DashboardOIDC.ConfigurationFilePath, "w+") as f:
encoder = json.JSONEncoder(indent=4)
f.write(encoder.encode(self.__default))
self.ReadFile()
2025-06-29 16:11:05 +08:00
def GetProviders(self):
providers = {}
for k in self.providers.keys():
if all([self.providers[k]['client_id'], self.providers[k]['client_secret'], self.providers[k]['issuer']]):
providers[k] = {
'client_id': self.providers[k]['client_id'],
'issuer': self.providers[k]['issuer'].strip('/')
}
return providers
def VerifyToken(self, provider, code, redirect_uri):
if not all([provider, code, redirect_uri]):
return False, ""
if provider not in self.providers.keys():
return False, "Provider does not exist"
provider = self.providers.get(provider)
2025-06-29 21:18:20 +08:00
oidc_config = requests.get(
f"{provider.get('issuer').strip('/')}/.well-known/openid-configuration",
verify=certifi.where()
).json()
data = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": redirect_uri,
"client_id": provider.get('client_id'),
"client_secret": provider.get('client_secret')
}
2025-06-29 16:11:05 +08:00
try:
tokens = requests.post(oidc_config.get('token_endpoint'), data=data).json()
if not all([tokens.get('access_token'), tokens.get('id_token')]):
return False, tokens.get('error_description', None)
except Exception as e:
return False, str(e)
id_token = tokens.get('id_token')
jwks_uri = oidc_config.get("jwks_uri")
issuer = oidc_config.get("issuer")
2025-06-29 21:18:20 +08:00
jwks = requests.get(jwks_uri, verify=certifi.where()).json()
2025-06-29 22:27:46 +08:00
print(jwks)
headers = jwt.get_unverified_header(id_token)
kid = headers["kid"]
key = next(k for k in jwks["keys"] if k["kid"] == kid)
payload = jwt.decode(
id_token,
key,
algorithms=[key["alg"]],
audience=provider.get('client_id'),
issuer=issuer
)
2025-06-29 16:11:05 +08:00
return True, payload
def ReadFile(self):
decoder = json.JSONDecoder()
self.providers = decoder.decode(
open(DashboardOIDC.ConfigurationFilePath, 'r').read()
)