From 9f72056d6f81bd6b419be6ebd1359089e17801b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emiliano=20Su=C3=B1=C3=A9?= Date: Tue, 10 Oct 2023 16:37:19 -0700 Subject: [PATCH 1/3] Expose LOG_LEVEL setting to docker/docker-compose.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emiliano Suñé --- docker/docker-compose.yaml | 1 + docker/manage | 1 + 2 files changed, 2 insertions(+) diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index d6bb4ee6..bbdc675f 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -15,6 +15,7 @@ services: fi" environment: - DEBUGGER=${DEBUGGER} + - LOG_LEVEL=${LOG_LEVEL} - DB_HOST=${MONGODB_HOST} - DB_PORT=${MONGODB_PORT} - DB_NAME=${MONGODB_NAME} diff --git a/docker/manage b/docker/manage index f53f84e1..e6c22e87 100755 --- a/docker/manage +++ b/docker/manage @@ -147,6 +147,7 @@ configureEnvironment() { ## global export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-vc-authn}" + export LOG_LEVEL=${LOG_LEVEL:-"DEBUG"} # controller-db export MONGODB_HOST="controller-db" From 7ad167ffd88891b6e957eafcfb74131cae5e8acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emiliano=20Su=C3=B1=C3=A9?= Date: Tue, 10 Oct 2023 16:39:23 -0700 Subject: [PATCH 2/3] Use stateless authorization db, add post as client authentication, fix bug with non-serializable sub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emiliano Suñé --- oidc-controller/api/clientConfigurations/models.py | 10 ++++++++-- .../api/core/oidc/issue_token_service.py | 4 ++-- oidc-controller/api/core/oidc/provider.py | 13 +++++++++++-- oidc-controller/api/routers/oidc.py | 14 ++++++-------- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/oidc-controller/api/clientConfigurations/models.py b/oidc-controller/api/clientConfigurations/models.py index 9b1aa852..295a88f5 100644 --- a/oidc-controller/api/clientConfigurations/models.py +++ b/oidc-controller/api/clientConfigurations/models.py @@ -1,13 +1,19 @@ from enum import Enum -from typing import Optional, List +from typing import List, Optional + from pydantic import BaseModel, Field -from .examples import ex_client_config from ..core.config import settings +from .examples import ex_client_config class TOKENENDPOINTAUTHMETHODS(str, Enum): client_secret_basic = "client_secret_basic" + client_secret_post = "client_secret_post" + + @classmethod + def list(cls): + return list(map(lambda c: c.value, cls)) class ClientConfigurationBase(BaseModel): diff --git a/oidc-controller/api/core/oidc/issue_token_service.py b/oidc-controller/api/core/oidc/issue_token_service.py index 3d50563d..e7de5eb0 100644 --- a/oidc-controller/api/core/oidc/issue_token_service.py +++ b/oidc-controller/api/core/oidc/issue_token_service.py @@ -96,7 +96,7 @@ def get_claims( """subject_identifer not found in presentation values, generating random subject_identifier""" ) - sub_id_value = uuid.uuid4() + sub_id_value = str(uuid.uuid4()) else: sub_id_value = sub_id_claim.value @@ -115,7 +115,7 @@ def get_claims( result[key] = value.value return result - + # TODO: Determine if this is useful to keep, and remove it if it's not. It is currently unused. # renames and calculates dict members appropriate to # https://openid.net/specs/openid-connect-core-1_0.html#IDToken diff --git a/oidc-controller/api/core/oidc/provider.py b/oidc-controller/api/core/oidc/provider.py index 7a6b3ef2..f0e4bb41 100644 --- a/oidc-controller/api/core/oidc/provider.py +++ b/oidc-controller/api/core/oidc/provider.py @@ -1,8 +1,10 @@ import os +import secrets from urllib.parse import urlparse import structlog import structlog.typing +from api.clientConfigurations.models import TOKENENDPOINTAUTHMETHODS from api.core.config import settings from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization @@ -11,6 +13,7 @@ from pymongo.database import Database from pyop.authz_state import AuthorizationState from pyop.provider import Provider +from pyop.storage import StatelessWrapper from pyop.subject_identifier import HashBasedSubjectIdentifierFactory from pyop.userinfo import Userinfo @@ -105,7 +108,7 @@ def pem_file_exists(filepath) -> bool: "request_parameter_supported": True, "request_uri_parameter_supported": False, "scopes_supported": ["openid"], - "token_endpoint_auth_methods_supported": ["client_secret_basic"], + "token_endpoint_auth_methods_supported": TOKENENDPOINTAUTHMETHODS.list(), "frontchannel_logout_supported": True, "frontchannel_logout_session_supported": True, "backchannel_logout_supported": True, @@ -113,6 +116,7 @@ def pem_file_exists(filepath) -> bool: } subject_id_factory = HashBasedSubjectIdentifierFactory(settings.SUBJECT_ID_HASH_SALT) +stateless_storage = StatelessWrapper("vc-authn", secrets.token_urlsafe()) # placeholder that gets set on app_start and write operations to ClientConfigurationCRUD provider = None @@ -131,7 +135,12 @@ async def init_provider(db: Database): provider = Provider( signing_key, configuration_information, - AuthorizationState(subject_id_factory), + AuthorizationState( + subject_id_factory, + authorization_code_db=stateless_storage, + access_token_db=stateless_storage, + refresh_token_db=stateless_storage, + ), client_db, Userinfo(user_db), ) diff --git a/oidc-controller/api/routers/oidc.py b/oidc-controller/api/routers/oidc.py index da12b09b..12e7cca4 100644 --- a/oidc-controller/api/routers/oidc.py +++ b/oidc-controller/api/routers/oidc.py @@ -6,8 +6,8 @@ import qrcode import structlog from fastapi import APIRouter, Depends, HTTPException, Request -from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse from fastapi import status as http_status +from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse from jinja2 import Template from oic.oic.message import AccessTokenRequest, AuthorizationRequest from pymongo.database import Database @@ -88,9 +88,10 @@ async def get_authorize(request: Request, db: Database = Depends(get_db)): ) except InvalidAuthenticationRequest as e: raise HTTPException( - status_code=http_status.HTTP_400_BAD_REQUEST, - detail=f"Invalid auth request: {e}") - + status_code=http_status.HTTP_400_BAD_REQUEST, + detail=f"Invalid auth request: {e}", + ) + # fetch placeholder user/model and create proof authn_response = provider.provider.authorize(model, "vc-user") @@ -161,7 +162,6 @@ async def post_token(request: Request, db: Database = Depends(get_db)): """Called by oidc platform to retrieve token contents""" form = await request.form() model = AccessTokenRequest().from_dict(form._dict) - client = AcapyClient() auth_session = await AuthSessionCRUD(db).get_by_pyop_auth_code(model.get("code")) ver_config = await VerificationConfigCRUD(db).get(auth_session.ver_config_id) @@ -169,9 +169,7 @@ async def post_token(request: Request, db: Database = Depends(get_db)): # modify subject identifier value to use vc-attribute as configured new_sub = claims.pop("sub") - provider.provider.authz_state.authorization_codes[model.get("code")][ - "public" - ] = new_sub + provider.provider.authz_state.subject_identifiers["vc-user"]["public"] = new_sub # convert form data to what library expects, Flask.app.request.get_data() data = urlencode(form._dict) From 4c957f3412c2963b7d3323dff2408ec676420c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emiliano=20Su=C3=B1=C3=A9?= Date: Tue, 10 Oct 2023 17:25:07 -0700 Subject: [PATCH 3/3] Add setuptools to dev requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emiliano Suñé --- oidc-controller/requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/oidc-controller/requirements-dev.txt b/oidc-controller/requirements-dev.txt index 6986fa9d..2998ccb8 100644 --- a/oidc-controller/requirements-dev.txt +++ b/oidc-controller/requirements-dev.txt @@ -6,3 +6,4 @@ pytest-asyncio==0.21.1 pytest-cov==4.1.0 pytest==7.3.1 requests-mock==1.11.0 +setuptools==68.2.2