# aiohttp_msal Python library
Authorization Code Flow Helper. Learn more about auth-code-flow at
<https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow>
Async based OAuth using the Microsoft Authentication Library (MSAL) for Python.
Blocking MSAL functions are executed in the executor thread.
Should be useful until such time as MSAL Python gets a true async version.
Tested with MSAL Python 1.21.0 onward - [MSAL Python docs](https://github.com/AzureAD/microsoft-authentication-library-for-python)
## AsycMSAL class
The AsyncMSAL class wraps the behavior in the following example app
<https://github.com/Azure-Samples/ms-identity-python-webapp/blob/master/app.py#L76>
It is responsible to manage tokens & token refreshes and as a client to retrieve data using these tokens.
### Acquire the token
Firstly you should get the tokens via OAuth
1. `initiate_auth_code_flow` [referernce](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.initiate_auth_code_flow)
The caller is expected to:
1. somehow store this content, typically inside the current session of the server,
2. guide the end user (i.e. resource owner) to visit that auth_uri, typically with a redirect
3. and then relay this dict and subsequent auth response to
acquire_token_by_auth_code_flow().
**Step 1** and part of **Step 3** is stored by this class in the aiohttp_session
2. `acquire_token_by_auth_code_flow` [referernce](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.initiate_auth_code_flow)
### Use the token
Now you are free to make requests (typically from an aiohttp server)
```python
session = await get_session(request)
aiomsal = AsyncMSAL(session)
async with aiomsal.get("https://graph.microsoft.com/v1.0/me") as res:
res = await res.json()
```
## Example web server
Complete routes can be found in [routes.py](./aiohttp_msal/routes.py)
### Start the login process
```python
@ROUTES.get("/user/login")
async def user_login(request: web.Request) -> web.Response:
"""Redirect to MS login page."""
session = await new_session(request)
redir = AsyncMSAL(session).build_auth_code_flow(
redirect_uri=get_route(request, URI_USER_AUTHORIZED)
)
return web.HTTPFound(redir)
```
### Acquire the token after being redirected back to the server
```python
@ROUTES.post(URI_USER_AUTHORIZED)
async def user_authorized(request: web.Request) -> web.Response:
"""Complete the auth code flow."""
session = await get_session(request)
auth_response = dict(await request.post())
aiomsal = AsyncMSAL(session)
await aiomsal.async_acquire_token_by_auth_code_flow(auth_response)
```
## Helper methods
- `@ROUTES.get("/user/photo")`
Serve the user's photo from their Microsoft profile
- `get_user_info`
Get the user's email and display name from MS Graph
- `get_manager_info`
Get the user's manager info from MS Graph
## Redis tools to retrieve session tokens
```python
from aiohttp_msal import ENV, AsyncMSAL
from aiohttp_msal.redis_tools import get_session
def main()
# Uses the redis.asyncio driver to retrieve the current token
# Will update the token_cache if a RefreshToken was used
ases = asyncio.run(get_session(MYEMAIL))
client = GraphClient(ases.get_token)
# ...
# use the Graphclient
```
Raw data
{
"_id": null,
"home_page": "https://github.com/kellerza/aiohttp_msal",
"name": "aiohttp-msal",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": "",
"keywords": "msal,oauth,aiohttp,asyncio",
"author": "Johann Kellerman",
"author_email": "kellerza@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/85/68/6900a88c236fef425c7a972ce3f6b34b4408808786802593c01a9ae94af5/aiohttp_msal-0.6.7.tar.gz",
"platform": null,
"description": "# aiohttp_msal Python library\n\nAuthorization Code Flow Helper. Learn more about auth-code-flow at\n<https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow>\n\nAsync based OAuth using the Microsoft Authentication Library (MSAL) for Python.\n\nBlocking MSAL functions are executed in the executor thread.\nShould be useful until such time as MSAL Python gets a true async version.\n\nTested with MSAL Python 1.21.0 onward - [MSAL Python docs](https://github.com/AzureAD/microsoft-authentication-library-for-python)\n\n## AsycMSAL class\n\nThe AsyncMSAL class wraps the behavior in the following example app\n<https://github.com/Azure-Samples/ms-identity-python-webapp/blob/master/app.py#L76>\n\nIt is responsible to manage tokens & token refreshes and as a client to retrieve data using these tokens.\n\n### Acquire the token\n\nFirstly you should get the tokens via OAuth\n\n1. `initiate_auth_code_flow` [referernce](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.initiate_auth_code_flow)\n\n The caller is expected to:\n 1. somehow store this content, typically inside the current session of the server,\n 2. guide the end user (i.e. resource owner) to visit that auth_uri, typically with a redirect\n 3. and then relay this dict and subsequent auth response to\n acquire_token_by_auth_code_flow().\n\n **Step 1** and part of **Step 3** is stored by this class in the aiohttp_session\n\n2. `acquire_token_by_auth_code_flow` [referernce](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.initiate_auth_code_flow)\n\n### Use the token\n\nNow you are free to make requests (typically from an aiohttp server)\n\n```python\nsession = await get_session(request)\naiomsal = AsyncMSAL(session)\nasync with aiomsal.get(\"https://graph.microsoft.com/v1.0/me\") as res:\n res = await res.json()\n```\n\n## Example web server\n\nComplete routes can be found in [routes.py](./aiohttp_msal/routes.py)\n\n### Start the login process\n\n```python\n@ROUTES.get(\"/user/login\")\nasync def user_login(request: web.Request) -> web.Response:\n \"\"\"Redirect to MS login page.\"\"\"\n session = await new_session(request)\n\n redir = AsyncMSAL(session).build_auth_code_flow(\n redirect_uri=get_route(request, URI_USER_AUTHORIZED)\n )\n\n return web.HTTPFound(redir)\n```\n\n### Acquire the token after being redirected back to the server\n\n```python\n@ROUTES.post(URI_USER_AUTHORIZED)\nasync def user_authorized(request: web.Request) -> web.Response:\n \"\"\"Complete the auth code flow.\"\"\"\n session = await get_session(request)\n auth_response = dict(await request.post())\n\n aiomsal = AsyncMSAL(session)\n await aiomsal.async_acquire_token_by_auth_code_flow(auth_response)\n```\n\n## Helper methods\n\n- `@ROUTES.get(\"/user/photo\")`\n\n Serve the user's photo from their Microsoft profile\n\n- `get_user_info`\n\n Get the user's email and display name from MS Graph\n\n- `get_manager_info`\n\n Get the user's manager info from MS Graph\n\n## Redis tools to retrieve session tokens\n\n```python\nfrom aiohttp_msal import ENV, AsyncMSAL\nfrom aiohttp_msal.redis_tools import get_session\n\ndef main()\n # Uses the redis.asyncio driver to retrieve the current token\n # Will update the token_cache if a RefreshToken was used\n ases = asyncio.run(get_session(MYEMAIL))\n client = GraphClient(ases.get_token)\n # ...\n # use the Graphclient\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Helper Library to use the Microsoft Authentication Library (MSAL) with aiohttp",
"version": "0.6.7",
"project_urls": {
"Homepage": "https://github.com/kellerza/aiohttp_msal"
},
"split_keywords": [
"msal",
"oauth",
"aiohttp",
"asyncio"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "aade98cc3c332e7a184d07d05f442d69815733099c7da3c821af2cf6388e81ac",
"md5": "51d57553eb1d179b2e15f5764e4cb3a9",
"sha256": "934dec62fefd95082d830377d852acc1184445bf6e680f83d54eceafe84241c2"
},
"downloads": -1,
"filename": "aiohttp_msal-0.6.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "51d57553eb1d179b2e15f5764e4cb3a9",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 17703,
"upload_time": "2023-11-01T14:31:45",
"upload_time_iso_8601": "2023-11-01T14:31:45.282494Z",
"url": "https://files.pythonhosted.org/packages/aa/de/98cc3c332e7a184d07d05f442d69815733099c7da3c821af2cf6388e81ac/aiohttp_msal-0.6.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "85686900a88c236fef425c7a972ce3f6b34b4408808786802593c01a9ae94af5",
"md5": "9bc79c0ba96fd47f1dd4f40119e0debc",
"sha256": "13ba84cdb80e8b5ebd2909a698219b3f60b1395e4e252ed135c46fc9fbe69c4d"
},
"downloads": -1,
"filename": "aiohttp_msal-0.6.7.tar.gz",
"has_sig": false,
"md5_digest": "9bc79c0ba96fd47f1dd4f40119e0debc",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 15367,
"upload_time": "2023-11-01T14:31:46",
"upload_time_iso_8601": "2023-11-01T14:31:46.495763Z",
"url": "https://files.pythonhosted.org/packages/85/68/6900a88c236fef425c7a972ce3f6b34b4408808786802593c01a9ae94af5/aiohttp_msal-0.6.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-01 14:31:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "kellerza",
"github_project": "aiohttp_msal",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "aiohttp-msal"
}