{"id":17030075,"url":"https://github.com/rob-blackbourn/bareasgi-sspi","last_synced_at":"2025-03-22T20:24:19.381Z","repository":{"id":58998924,"uuid":"534960753","full_name":"rob-blackbourn/bareasgi-sspi","owner":"rob-blackbourn","description":"ASGI middleware for SSPI authentication","archived":false,"fork":false,"pushed_at":"2022-10-12T11:03:45.000Z","size":94,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T10:04:59.403Z","etag":null,"topics":["asgi","asyncio","bareasgi","hypercorn","python","python3","spnego","sspi","uvicorn","windows"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rob-blackbourn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-09-10T10:14:06.000Z","updated_at":"2022-09-10T11:55:34.000Z","dependencies_parsed_at":"2022-09-14T22:54:04.506Z","dependency_job_id":null,"html_url":"https://github.com/rob-blackbourn/bareasgi-sspi","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fbareasgi-sspi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fbareasgi-sspi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fbareasgi-sspi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fbareasgi-sspi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rob-blackbourn","download_url":"https://codeload.github.com/rob-blackbourn/bareasgi-sspi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245015675,"owners_count":20547448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asgi","asyncio","bareasgi","hypercorn","python","python3","spnego","sspi","uvicorn","windows"],"created_at":"2024-10-14T08:04:00.696Z","updated_at":"2025-03-22T20:24:19.351Z","avatar_url":"https://github.com/rob-blackbourn.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bareASGI-sspi\n\n[ASGI](https://asgi.readthedocs.io/en/latest/index.html) middleware\nfor the [bareASGI](https://github.com/rob-blackbourn/bareASGI) framework\nproviding [SSPI](https://en.wikipedia.org/wiki/Security_Support_Provider_Interface) authentication\non Windows.\n\nThe implementation uses the [pyspnego](https://github.com/jborean93/pyspnego) package.\n\nThere is also a generic ASGI server middleware implementation in the package\n[jetblack-asgi-sspi](https://github.com/rob-blackbourn/jetblack-asgi-sspi).\n\n## Installation\n\nInstall from the pie store.\n\n```\npip install bareasgi-sspi\n```\n\n## Usage\n\nThe following program uses the\n[Hypercorn](https://pgjones.gitlab.io/hypercorn/)\nASGI server.\n\n```python\nimport asyncio\nimport logging\nfrom typing import Optional\n\nfrom bareasgi import Application, HttpRequest, HttpResponse\nfrom bareutils import text_writer\nfrom hypercorn import Config\nfrom hypercorn.asyncio import serve\n\nfrom bareasgi_sspi import add_sspi_middleware, sspi_details\n\n# A callback to display the results of the SSPI middleware.\nasync def http_request_callback(request: HttpRequest) -\u003e HttpResponse:\n    # Get the details from the request context request['sspi']. Note if\n    # authentication failed this might be absent or empty.\n    sspi = sspi_details(request)\n    client_principal = (\n        sspi['client_principal']\n        if sspi is not None\n        else 'unknown'\n    )\n    return HttpResponse(\n        200,\n        [(b'content-type', b'text/plain')],\n        text_writer(f\"Authenticated as '{client_principal}'\")\n    )\n\n\nasync def main_async():\n    # Make the ASGI application using the middleware.\n    app = Application()\n    app.http_router.add({'GET'}, '/', http_request_callback)\n\n    # Add the middleware. Change the protocol from Negotiate to NTLM,\n    # and allow unauthenticated requests to pass through.\n    add_sspi_middleware(\n        app,\n        protocol=b'NTLM',\n        forbid_unauthenticated=False\n    )\n\n    # Start the ASGI server.\n    config = Config()\n    config.bind = ['localhost:9023']\n    await serve(app, config)\n\nif __name__ == '__main__':\n    logging.basicConfig(level=logging.DEBUG)\n    asyncio.run(main_async())\n```\n\n### Arguments\n\nOptional arguments include:\n\n* `protocol` (`bytes`): Either `b\"Negotiate\"` or `b\"NTLM\"` (for systems not part of a domain).\n* `service` (`str`): The SPN service. Defaults to `\"HTTP\"`.\n* `hostname` (`str`, optional): The hostname. Defaults to he result of `socket.gethostname()`.\n* `session_duration` (`timedelta`, optional): The duration of a session. Defaults to 1 hour.\n* `forbid_unauthenticated` (`bool`): If true, and authentication fails, send 403 (Forbidden). Otherwise handle the request unauthenticated.\n* `context_key` (`str`, optional): The key used in the request context. Defaults to `sspi`.\n* `whitelist` (`Sequence[str]`, optional): Paths not to authenticate. Defaults to `()`.\n\n### Results\n\nIf the authentication is successful the SSPI details are added to the\n`context` dictionary of the HttpRequest object with the key `\"sspi\"`\n(if not overridden). There is a helper method `sspi_details` for this.\n\nThe following properties are set:\n\n* `\"client_principal\"` (`str`): The username of the client.\n* `\"negotiated_protocol\"` (`str`): The negotiated protocol.\n* `\"protocol\"` (`str`): The requested protocol.\n* `\"spn\"` (`str`): The SPN of the server.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frob-blackbourn%2Fbareasgi-sspi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frob-blackbourn%2Fbareasgi-sspi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frob-blackbourn%2Fbareasgi-sspi/lists"}