def __init__( self, authorization_url: str, token_url: str, refresh_url: str = None, scopes: dict = {}, auto_error: bool = True ): _ResourceProtector.__init__(self) OAuth2AuthorizationCodeBearer.__init__( self, authorization_url, token_url, refresh_url, scopes, auto_error )
def __init__(self, domain: str, api_audience: str, scopes: Dict[str, str]={}, auto_error: bool=True, scope_auto_error: bool=True, email_auto_error: bool=False, auth0user_model: Type[Auth0User]=Auth0User): self.domain = domain self.audience = api_audience self.auto_error = auto_error self.scope_auto_error = scope_auto_error self.email_auto_error = email_auto_error self.auth0_user_model = auth0user_model self.algorithms = ['RS256'] self.jwks: Dict = requests.get(f'https://{domain}/.well-known/jwks.json').json() self.implicit_scheme = OAuth2ImplicitBearer( authorizationUrl=f'https://{domain}/authorize?audience={api_audience}', scopes=scopes, scheme_name='Auth0ImplicitBearer') self.password_scheme = OAuth2PasswordBearer(tokenUrl=f'https://{domain}/oauth/token', scopes=scopes) self.authcode_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=f'https://{domain}/authorize?audience={api_audience}', tokenUrl=f'https://{domain}/oauth/token', scopes=scopes) self.oidc_scheme = OpenIdConnect(openIdConnectUrl=f'https://{domain}/.well-known/openid-configuration')
def __init__(self, auto_error: bool = True) -> None: self.auto_error = auto_error self.openid_config: OpenIdConfig = OpenIdConfig() self.oauth = OAuth2AuthorizationCodeBearer( authorizationUrl='https://auth.klepp.me/oauth2/authorize', tokenUrl='https://auth.klepp.me/oauth2/token', scopes={'openid': 'openid'}, scheme_name='CognitoAuth', auto_error=True, ) self.model = self.oauth.model self.scheme_name: str = 'Cognito'
print(BASE_PATH) logger.add(f"{BASE_PATH}/logs/main.log", rotation="32 MB") app = FastAPI() app.debug = True def access_deny(): return HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials", headers={"WWW-Authenticate": "Bearer"}, ) oauth2_scheme_code = OAuth2AuthorizationCodeBearer(tokenUrl="token", authorizationUrl="auth") async def check_auth(token: str = Depends(oauth2_scheme_code)): if token != fake_yandex_oauth['token']: raise access_deny() return True @app.head("/yandex/v1.0") async def return_ok(): return Response(status_code=200) @app.get("/yandex/v1.0/user/devices") async def get_devices_list(x_request_id: str = Header(None),
def add_api_routes(self, api_server, api_routes: Dict[str, ApiRoute], prefix) -> None: """Add api routes to the api server""" # Get important app configs api_prefix = uvicore.config.app.api.prefix # Different that the prefix parameter openapi = uvicore.config.app.api.openapi oauth2 = uvicore.config.app.auth.oauth2 # Determine if OpenAPI docs oauth2 authentication is enabled # If OpenAPI oauth2 is enabled, create a FastAPI OAuth2AuthorizationCodeBearer variable if openapi.oauth2_enabled and oauth2: from fastapi.security import OAuth2AuthorizationCodeBearer oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=oauth2.base_url + oauth2.authorize_path, tokenUrl=oauth2.base_url + oauth2.token_path, ) # Create our own custom OpenAPI docs route if openapi.path and openapi.docs.path: # Oauth2 redirect URL (without api_prefid) openapi_redirect_url = openapi.docs.path + '/login' @api_server.get(openapi.docs.path, include_in_schema=False) def openapi_docs(): return get_swagger_ui_html( openapi_url=api_prefix + openapi.path, title=openapi.title, swagger_favicon_url=openapi.docs.favicon_url, swagger_js_url=openapi.docs.js_url, swagger_css_url=openapi.docs.css_url, oauth2_redirect_url=api_prefix + openapi_redirect_url, init_oauth={ 'clientId': oauth2.client_id, #'clientSecret': "GaMz_F83_KB8ac6g-Eds0uoHyeoxg03X184yBqZR5Ws", #'realm': "https://auth-local.triglobal.io", 'appName': uvicore.config.app.name, #'scopeSeparator': " ", 'scopes': "openid profile", #'additionalQueryStringParams': {'client_id': "7cc7d2a5-cc02-43ca-93bc-8476370ebf9d"}, #'usePkceWithAuthorizationCodeGrant': False }, ) @api_server.get(openapi_redirect_url, include_in_schema=False) def openapi_redirect(): return get_swagger_ui_oauth2_redirect_html() # Loop each uvicore route and add as FastAPI route for route in api_routes.values(): endpoint_func = route.endpoint response_model = route.response_model # If endpoint is partial, grab inside func for type hindint and docstrings if isinstance(route.endpoint, partial): # Endpoint is a partial (was overwritten to default some higher order middleware) # A partial overwrites the original docstring. Functools update_wrapper will copy it back # as well as handle merging of other important properties #update_wrapper(route.endpoint, route.endpoint.func) endpoint_func = route.endpoint.func # Blank out the __doc__ on actual Partial itself, not actual endpoint inside partial. # If not, OpenAPI doc description will be partial(func, *args, **keywords) - new function with partial application etc... route.endpoint.__doc__ = None # Get response model from parameter or infer from endpoint return type hint #response_model = route.response_model if route.response_model else get_type_hints(endpoint_func).get('return') response_model = route.response_model or get_type_hints( endpoint_func).get('return') # Get openapi description from route param or endpoint docstring description = route.description or endpoint_func.__doc__ # If OpenAPI oauth2 authentication is enabled, add the proper route # dependency to our oauth2_schema if openapi.oauth2_enabled: found_guard = False for middleware in route.middleware: if type(middleware) == Guard: found_guard = True break if found_guard: route.middleware.append(Depends(oauth2_scheme)) # Add uvicore route to FastAPI route api_server.add_api_route( path=(prefix + route.path) or '/', endpoint=route.endpoint, methods=route.methods, name=route.name, response_model=response_model, tags=route.tags, dependencies=route.middleware, summary=route.summary, description=description, )
from typing import Optional from fastapi import FastAPI, Security from fastapi.security import OAuth2AuthorizationCodeBearer from fastapi.testclient import TestClient app = FastAPI() oauth2_scheme = OAuth2AuthorizationCodeBearer(authorizationUrl="/authorize", tokenUrl="/token", auto_error=True) @app.get("/items/") async def read_items(token: Optional[str] = Security(oauth2_scheme)): return {"token": token} client = TestClient(app) openapi_schema = { "openapi": "3.0.2", "info": { "title": "FastAPI", "version": "0.1.0" }, "paths": { "/items/": { "get": { "responses": { "200": {
from backend.api import settings from fastapi.security import OAuth2AuthorizationCodeBearer from fastapi import Depends from backend.api.service_utils.services import decode_access_token from backend.api.db_utils.user_crud import retrieve_user from backend.api.schema.schemas import MDLUser oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=settings.Settings.AUTHORIZATION_URL, tokenUrl=settings.Settings.TOKEN_URL, auto_error=True, scopes={ "openid": "Get openId data", "email": "Get email access", "profile": "Get profile information" }) async def get_current_active_user(token: str = Depends( oauth2_scheme)) -> MDLUser: """THIS IS A DEPENDENCY THAT RETURNS USER""" user_sub: str = decode_access_token(token) user: MDLUser = await retrieve_user(user_sub) return user
_TENANT_ID).replace("{ServerId}", _SERVER_ID) _USER_ID_CLAIM = _CONFIG("USER_ID_CLAIM") # noinspection SpellCheckingInspection SWAGGER_UI_INIT_OAUTH = { "usePkceWithAuthorizationCodeGrant": True, "clientId": _SWAGGER_CLIENT_ID, "scopes": _SCOPE } ALLOW_ORIGIN_REGEX = _CONFIG("ALLOW_ORIGIN_REGEX") _JWKS_CACHE = {} _oauth2_scheme = OAuth2AuthorizationCodeBearer( # scopes={"api://c70e0ac4-7775-4615-b1a0-76eb1ca838a0/Items.Read.All": "Read All Items"}, authorizationUrl=_AUTHORIZE_URL, tokenUrl=_TOKEN_URL) def _validate_token(access_token: str) -> Mapping[str, str]: # Decoding Header & Payload from token header = jwt.get_unverified_header(access_token) payload = jwt.get_unverified_claims(access_token) # Verifying Claims try: verify_iss(payload, _TOKEN_ISSUER) except Exception: raise HTTPException(HTTPStatus.UNAUTHORIZED, "Wrong 'iss' claim.") try:
class Services(): users: UsersService services = Services(None) def set_services(users_service: UsersService): services.users = users_service # oauth2_scheme dependency alllows fastapi to interrogate the Authorization: Beaarer <token> # header sent from the splash client. It's very close to working with the swagger UI, but not quite... oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=ConfigStore.OAUTH_AUTH_URL, tokenUrl=ConfigStore.OAUTH_TOKEN_URL, auto_error=True, scopes={'email': 'profile'}) class OauthVerificationError(ValueError): pass class UserNotFoundError(Exception): # TODO: make the base class more specific pass class MultipleUsersError(Exception): pass
from datetime import datetime, timedelta from jose import JWTError, jwt # type: ignore from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2AuthorizationCodeBearer, SecurityScopes from pydantic import ValidationError from sqlalchemy.orm import Session # type: ignore from typing import List, Optional, Tuple from cotacol import crud, schemas, settings from cotacol.db import get_db from cotacol.models import User oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl="/login/{provider}/", tokenUrl="/auth/token/", scopes={"read": "Read COTACOL information.", "write": "Read or write COTACOL information."}, ) def get_user_from_token( security_scopes: SecurityScopes, db: Session = Depends(get_db), token: str = Depends(oauth2_scheme) ) -> User: if security_scopes.scopes: authenticate_value = f'Bearer scope="{security_scopes.scope_str}"' else: authenticate_value = "Bearer" def raise_credentials_exception(msg: str = "Could not validate credentials"): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=msg, headers={"WWW-Authenticate": authenticate_value},
from fastapi.security import OAuth2AuthorizationCodeBearer from keycloak import KeycloakOpenID from pydantic.tools import lru_cache from app import config @lru_cache() def get_keycloak_settings(): return config.Settings().keycloak keycloak_openid = KeycloakOpenID( server_url=get_keycloak_settings().address + "/", client_id=get_keycloak_settings().client_id, realm_name=get_keycloak_settings().realm ) oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=f"{get_keycloak_settings().address}/realms/{get_keycloak_settings().realm}/protocol/openid-connect/auth", tokenUrl=f"{get_keycloak_settings().address}/realms/{get_keycloak_settings().realm}/protocol/openid-connect/token" )
from typing import Optional from fastapi import FastAPI, Security from fastapi.security import OAuth2AuthorizationCodeBearer from fastapi.testclient import TestClient app = FastAPI() oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl="authorize", tokenUrl="token", description="OAuth2 Code Bearer", auto_error=True, ) @app.get("/items/") async def read_items(token: Optional[str] = Security(oauth2_scheme)): return {"token": token} client = TestClient(app) openapi_schema = { "openapi": "3.0.2", "info": { "title": "FastAPI", "version": "0.1.0" }, "paths": { "/items/": {
from fastapi.security import OAuth2AuthorizationCodeBearer from fastapi.security.api_key import APIKeyQuery from .client import get_client from .models import User ### Endpoints can require authentication using Depends(get_current_user) ### get_current_user will look for a token in url params or ### Authorization: bearer token (header). ### Hub technically supports cookie auth too, but it is deprecated so ### not being included here. auth_by_param = APIKeyQuery(name="token", auto_error=False) auth_url = os.environ["PUBLIC_HOST"] + "/hub/api/oauth2/authorize" auth_by_header = OAuth2AuthorizationCodeBearer(authorizationUrl=auth_url, tokenUrl="get_token", auto_error=False) ### ^^ The flow for OAuth2 in Swagger is that the "authorize" button ### will redirect user (browser) to "auth_url", which is the Hub login page. ### After logging in, the browser will POST to our internal /get_token endpoint ### with the auth code. That endpoint POST's to Hub /oauth2/token with ### our client_secret (JUPYTERHUB_API_TOKEN) and that code to get an ### access_token, which it returns to browser, which places in Authorization header. if os.environ.get("JUPYTERHUB_OAUTH_SCOPES"): # typically ["access:services", "access:services!service=$service_name"] access_scopes = json.loads(os.environ["JUPYTERHUB_OAUTH_SCOPES"]) else: access_scopes = ["access:services"]
from typing import Dict from fastapi.security import OAuth2AuthorizationCodeBearer from keycloak import KeycloakOpenID from mludolph import config from fastapi import Depends, Security, HTTPException, status # This is just for fastapi docs oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=config.AUTH_HOST, tokenUrl=config.AUTH_TOKEN_URL, ) keycloak_openid = KeycloakOpenID( server_url=config.AUTH_HOST, client_id=config.AUTH_CLIENT_ID, realm_name=config.AUTH_REALM, verify=True, ) async def get_idp_public_key(): return ("-----BEGIN PUBLIC KEY-----\n" f"{keycloak_openid.public_key()}" "\n-----END PUBLIC KEY-----") async def verify_token(token: str) -> Dict: return keycloak_openid.decode_token( token, key=await get_idp_public_key(), options={
from fastapi import Depends from fastapi.requests import Request from fastapi.security import OAuth2AuthorizationCodeBearer from pichi.models.auth0 import Claims from pichi.services.auth0 import Auth0Service oauth2_scheme = OAuth2AuthorizationCodeBearer(authorizationUrl="", tokenUrl="bearer") def get_auth0_service(request: Request): return request.app.state.auth0_service def get_current_user( auth0: Auth0Service = Depends(get_auth0_service), token: str = Depends(oauth2_scheme), ) -> Claims: """verify a token and extract the claims""" return auth0.parse_claims(token)
def db(request: Request) -> Database: return request.app.state.db def use_case( repository_type: Type[DatabaseUseCase], ) -> Callable[[], DatabaseUseCase]: def wrap(db_: Database = Depends(db)) -> DatabaseUseCase: return repository_type(db_) return wrap oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl="", tokenUrl="", auto_error=False ) def update_oauth2_scheme(authorization_url="", token_url=""): oauth2_scheme.model = OAuth2( flows=OAuthFlows( authorizationCode={ "authorizationUrl": authorization_url, "tokenUrl": token_url, "refreshUrl": token_url, } ) )
from datetime import datetime, timedelta from jose import JWTError, jwt # type: ignore from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2AuthorizationCodeBearer, SecurityScopes from pydantic import ValidationError from sqlalchemy.orm import Session # type: ignore from typing import List, Optional, Tuple from cotacol import crud, schemas, settings from cotacol.db import get_db from cotacol.models import User oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl="[client]", tokenUrl="/auth/token/", scopes={ "read": "Read COTACOL information.", "write": "Read or write COTACOL information.", }, ) def fake_decode_token(token): return User(username=token + "fakedecoded", full_name="John Doe") def get_user_from_token( security_scopes: SecurityScopes, db: Session = Depends(get_db), token: str = Depends(oauth2_scheme) ) -> User: if security_scopes.scopes:
from fastapi.security import OAuth2AuthorizationCodeBearer, SecurityScopes from jose import jwt from httpx import AsyncClient from app.config import get_settings class AuthError(Exception): def __init__(self, error, status_code): self.error = error self.status_code = status_code settings = get_settings() hydra_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=settings.hydra_url + "/oauth2/auth", tokenUrl=settings.hydra_url + "/oauth2/token", scopes={"all": "Get all information"}) async def get_current_token( security_scopes: SecurityScopes, token: str = Depends(hydra_scheme)) -> dict: async with AsyncClient() as session: resp = await session.get(settings.hydra_url + "/.well-known/jwks.json") jwks = resp.json() unverified_header = jwt.get_unverified_header(token) rsa_key = dict() for key in jwks["keys"]: if key["kid"] == unverified_header["kid"]: rsa_key = {
origins = [ "http://localhost", "http://localhost:8080", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) oauth2_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=f"{keycloak_url}realms/{realm_name}/protocol/openid-connect/auth", tokenUrl=f"{keycloak_url}realms/{realm_name}/protocol/openid-connect/token", ) async def get_current_user(token: str = Depends(oauth2_scheme)): try: KEYCLOAK_PUBLIC_KEY = ( "-----BEGIN PUBLIC KEY-----\n" + keycloak_openid.public_key() + "\n-----END PUBLIC KEY-----" ) return keycloak_openid.decode_token( token, key=KEYCLOAK_PUBLIC_KEY, options={"verify_signature": True, "verify_aud": False, "exp": True}, )
KEYCLOAK_HOST = getenv("KEYCLOAK_HOST", "http://localhost:8080/auth/") KEYCLOAK_REALM = getenv("KEYCLOAK_REALM", "master") print(f"Waiting for Keycloak {KEYCLOAK_HOST} using realm '{KEYCLOAK_REALM}'.", end='') wait_for_http_connection_to(KEYCLOAK_HOST) try: keycloak_openid = KeycloakOpenID(server_url=KEYCLOAK_HOST, realm_name=KEYCLOAK_REALM, client_id="admin") KEYCLOAK_WELL_KNOW = keycloak_openid.well_know() KEYCLOAK_CERTS = keycloak_openid.certs() oAuthBearer = OAuth2AuthorizationCodeBearer( authorizationUrl=KEYCLOAK_WELL_KNOW['authorization_endpoint'], tokenUrl=KEYCLOAK_WELL_KNOW['token_endpoint']) except Exception as e: print(f"...failed: {e}. Endpoints with Authorization will not work.") def oAuthBearer(): raise AuthError("Keycloak not set up correctly!", 500) async def parse_bearer_token(security_scopes: SecurityScopes, token: str = Depends(oAuthBearer)): try: token_info = keycloak_openid.decode_token(token, key=KEYCLOAK_CERTS, options={
aud: str = "" sub: str = "" scope: str = "" exp: str = "" expires_in: str = "" email: str = "" email_verified: str = "" access_type: str = "" # Define a Authorization scheme specific to our Auth0 config auth0_scheme = OAuth2AuthorizationCodeBearer( authorizationUrl=AUTHORIZATION_URL, tokenUrl=TOKEN_URL, scopes={ "openid": "openid", "email": "email", "profile": "profile" }, ) async def get_current_user(security_scopes: SecurityScopes, token: str = Security(auth0_scheme)): if not verify(token): raise AuthError(error="유효하지 않은 토큰입니다", status_code=HTTPStatus.UNAUTHORIZED) response = requests.get(USER_INFO_URL.format(access_token=token)) if response.status_code == HTTPStatus.OK: return response.json()
def _get_oauth2_scheme(base_url): return OAuth2AuthorizationCodeBearer( authorizationUrl=_url_for(base_url, "oauth2_authorize"), tokenUrl=_url_for(base_url, "oauth2_token"), auto_error=False, )