diff --git a/.github/ISSUE_TEMPLATE/bug-report-question.md b/.github/ISSUE_TEMPLATE/bug-report-question.md index 15dafa14..f8d0ea1d 100644 --- a/.github/ISSUE_TEMPLATE/bug-report-question.md +++ b/.github/ISSUE_TEMPLATE/bug-report-question.md @@ -18,7 +18,7 @@ Steps to reproduce the behavior: 3. See error -If this can be related to your Azure AD set up, please also provide screenshots/reproduce steps of that. +If this can be related to your Azure Entra ID set up, please also provide screenshots/reproduce steps of that. Blur sensitive data. --> diff --git a/README.md b/README.md index b82f7029..663a6f6f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

- Azure AD Authentication for FastAPI apps made easy. + Azure Entra ID Authentication for FastAPI apps made easy.

@@ -59,7 +59,7 @@ Also, [we're hiring!](https://intility.no/en/career/) ## ๐Ÿ“š Resources -The [documentation](https://intility.github.io/fastapi-azure-auth/) contains a full tutorial on how to configure Azure AD +The [documentation](https://intility.github.io/fastapi-azure-auth/) contains a full tutorial on how to configure Azure Entra ID and FastAPI for single- and multi-tenant applications as well as B2C apps. It includes examples on how to lock down your APIs to certain scopes, tenants, roles etc. For first time users it's strongly advised to set up your application exactly how it's described there, and then alter it to your needs later. diff --git a/docs/docs/b2c/azure_setup.mdx b/docs/docs/b2c/azure_setup.mdx index 26f6cbd5..776babbe 100644 --- a/docs/docs/b2c/azure_setup.mdx +++ b/docs/docs/b2c/azure_setup.mdx @@ -3,7 +3,7 @@ title: Azure configuration sidebar_position: 1 --- -We'll need to create two application registrations for Azure AD B2C authentication to cover both direct API +We'll need to create two application registrations for Azure Entra ID B2C authentication to cover both direct API use and usage from the OpenAPI (swagger) documentation. :::info @@ -15,7 +15,7 @@ This guide assumes that an Azure B2C tenant was already created and linked to an ### Step 1 - Create app registration Head over to -[Azure -> Azure AD B2C -> App registrations](https://portal.azure.com/#view/Microsoft_AAD_B2CAdmin/TenantManagementMenuBlade/~/registeredApps), +[Azure -> Azure Entra ID B2C -> App registrations](https://portal.azure.com/#view/Microsoft_AAD_B2CAdmin/TenantManagementMenuBlade/~/registeredApps), and create a new registration. Select a fitting name for your project; Azure will present the name to the user during consent. @@ -56,7 +56,7 @@ OPENAPI_CLIENT_ID= AUTH_POLICY_NAME= ``` -Also, in the Azure AD B2C overview get the tenant name from the domain name (without the `.onmicrosoft.com` part) +Also, in the Azure Entra ID B2C overview get the tenant name from the domain name (without the `.onmicrosoft.com` part) and add it to the `.env` file as well: ```bash title=".env" {1} @@ -97,7 +97,7 @@ So, let's set it up! Just like in the previous chapter, we have to create an application registration for our OpenAPI. Head over to -[Azure -> Azure AD B2C -> App registrations](https://portal.azure.com/#view/Microsoft_AAD_B2CAdmin/TenantManagementMenuBlade/~/registeredApps), +[Azure -> Azure Entra ID B2C -> App registrations](https://portal.azure.com/#view/Microsoft_AAD_B2CAdmin/TenantManagementMenuBlade/~/registeredApps), and create a new registration. Use the same name, but with `- OpenAPI` appended to it. @@ -157,7 +157,7 @@ That's it! Next step is to configure the FastAPI application. ### Step 1 - Create a user flow Head over to -[Azure -> Azure AD B2C -> Users flows](https://portal.azure.com/#view/Microsoft_AAD_B2CAdmin/TenantManagementMenuBlade/~/userJourneys), +[Azure -> Azure Entra ID B2C -> Users flows](https://portal.azure.com/#view/Microsoft_AAD_B2CAdmin/TenantManagementMenuBlade/~/userJourneys), and create a new user flow. Select a user flow type of `Sign up and sign in` with the Version `Recommended`, then press **Create**. diff --git a/docs/docs/b2c/fastapi_configuration.mdx b/docs/docs/b2c/fastapi_configuration.mdx index eb950433..fa03e5a0 100644 --- a/docs/docs/b2c/fastapi_configuration.mdx +++ b/docs/docs/b2c/fastapi_configuration.mdx @@ -42,8 +42,8 @@ if __name__ == '__main__': Run your application and ensure that everything works on [http://localhost:8000/docs](http://localhost:8000/docs) :::info -You need to run the application on the configured port in Azure AD B2C for the next steps to work! If you are unsure, -revisit the previous chapter or review the Azure AD B2C configuration under `App Registrations` -> `Authentication`. +You need to run the application on the configured port in Azure Entra ID B2C for the next steps to work! If you are unsure, +revisit the previous chapter or review the Azure Entra ID B2C configuration under `App Registrations` -> `Authentication`. ::: ## Add your settings @@ -188,7 +188,7 @@ if __name__ == '__main__': uvicorn.run('main:app', reload=True) ``` -The `swagger_ui_oauth2_redirect_url` setting for redirect should be as configured in Azure AD. +The `swagger_ui_oauth2_redirect_url` setting for redirect should be as configured in Azure Entra ID. The `swagger_ui_init_oauth` are standard mapped OpenAPI properties. You can find documentation about them [here](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/) We've used two flags: `usePkceWithAuthorizationCodeGrant`, which is the authentication flow. diff --git a/docs/docs/introduction.mdx b/docs/docs/introduction.mdx index d7cf7d17..452bb973 100644 --- a/docs/docs/introduction.mdx +++ b/docs/docs/introduction.mdx @@ -14,13 +14,13 @@ import GitHubButton from 'react-github-btn';

FastAPI-Azure-Auth

- Azure AD Authentication for FastAPI apps made easy. + Azure Entra ID Authentication for FastAPI apps made easy.

-**FastAPI-Azure-Auth** implements Azure AD and Azure AD B2C authentication and authorization +**FastAPI-Azure-Auth** implements Azure Entra ID and Azure Entra ID B2C authentication and authorization for your FastAPI APIs and OpenAPI documentation. In the sidebar to the left you'll be able to find information on how to configure both Azure and your FastAPI application. diff --git a/docs/docs/multi-tenant/azure_setup.mdx b/docs/docs/multi-tenant/azure_setup.mdx index c8fc7670..d0421448 100644 --- a/docs/docs/multi-tenant/azure_setup.mdx +++ b/docs/docs/multi-tenant/azure_setup.mdx @@ -3,7 +3,7 @@ title: Azure configuration sidebar_position: 1 --- -We'll need to create two application registrations for Azure AD authentication to cover both direct API +We'll need to create two application registrations for Azure Entra ID authentication to cover both direct API use and usage from the OpenAPI (swagger) documentation. We'll start with the API. diff --git a/docs/docs/multi-tenant/fastapi_configuration.mdx b/docs/docs/multi-tenant/fastapi_configuration.mdx index 908aeddd..e93de52b 100644 --- a/docs/docs/multi-tenant/fastapi_configuration.mdx +++ b/docs/docs/multi-tenant/fastapi_configuration.mdx @@ -41,7 +41,7 @@ if __name__ == '__main__': Run your application and ensure that everything works on [http://localhost:8000/docs](http://localhost:8000/docs) :::info -You need to run the application on the configured port in Azure AD for the next steps to work! +You need to run the application on the configured port in Azure Entra ID for the next steps to work! ::: ## Add your settings @@ -177,7 +177,7 @@ if __name__ == '__main__': uvicorn.run('main:app', host='localhost', port=8000, reload=True) ``` -The `swagger_ui_oauth2_redirect_url` setting for redirect should be as configured in Azure AD. +The `swagger_ui_oauth2_redirect_url` setting for redirect should be as configured in Azure Entra ID. The `swagger_ui_init_oauth` are standard mapped OpenAPI properties. You can find documentation about them [here](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/) We've used two flags: `usePkceWithAuthorizationCodeGrant`, which is the authentication flow. diff --git a/docs/docs/settings/b2c.mdx b/docs/docs/settings/b2c.mdx index 0fe1ab08..2c8e979c 100644 --- a/docs/docs/settings/b2c.mdx +++ b/docs/docs/settings/b2c.mdx @@ -6,7 +6,7 @@ sidebar_position: 3 ### app_client_id: `str` **Default**: `None` -Your applications client ID. This will be the `Web app` in Azure AD +Your applications client ID. This will be the `Web app` in Azure Entra ID ----------------- @@ -20,7 +20,7 @@ Override OpenID config URL (used for B2C tenants) ### scopes: `Optional[dict[str, str]]` **Default:** `None` -Scopes, these are the ones you've configured in Azure AD B2C. Key is scope, value is a description. +Scopes, these are the ones you've configured in Azure Entra ID B2C. Key is scope, value is a description. ```python { diff --git a/docs/docs/settings/multi_tenant.mdx b/docs/docs/settings/multi_tenant.mdx index 163281e3..14a585a1 100644 --- a/docs/docs/settings/multi_tenant.mdx +++ b/docs/docs/settings/multi_tenant.mdx @@ -6,7 +6,7 @@ sidebar_position: 2 ### app_client_id: `str` **Default**: `None` -Your applications client ID. This will be the `Web app` in Azure AD +Your applications client ID. This will be the `Web app` in Azure Entra ID ----------------- @@ -22,7 +22,7 @@ for more details ### scopes: `Optional[dict[str, str]]` **Default:** `None` -Scopes, these are the ones you've configured in Azure AD. Key is scope, value is a description. +Scopes, these are the ones you've configured in Azure Entra ID. Key is scope, value is a description. ```python { diff --git a/docs/docs/settings/single_tenant.mdx b/docs/docs/settings/single_tenant.mdx index ec84d592..2252aa71 100644 --- a/docs/docs/settings/single_tenant.mdx +++ b/docs/docs/settings/single_tenant.mdx @@ -6,7 +6,7 @@ sidebar_position: 1 ### app_client_id: `str` **Default**: `None` -Your applications client ID. This will be the `Web app` in Azure AD +Your applications client ID. This will be the `Web app` in Azure Entra ID ----------------- @@ -29,7 +29,7 @@ for more details ### scopes: `Optional[dict[str, str]]` **Default:** `None` -Scopes, these are the ones you've configured in Azure AD. Key is scope, value is a description. +Scopes, these are the ones you've configured in Azure Entra ID. Key is scope, value is a description. ```python { diff --git a/docs/docs/single-tenant/azure_setup.mdx b/docs/docs/single-tenant/azure_setup.mdx index b243b029..f670a32e 100644 --- a/docs/docs/single-tenant/azure_setup.mdx +++ b/docs/docs/single-tenant/azure_setup.mdx @@ -3,7 +3,7 @@ title: Azure configuration sidebar_position: 1 --- -We'll need to create two application registrations for Azure AD authentication to cover both direct API +We'll need to create two application registrations for Azure Entra ID authentication to cover both direct API use and usage from the OpenAPI (swagger) documentation. We'll start with the API. diff --git a/docs/docs/single-tenant/fastapi_configuration.mdx b/docs/docs/single-tenant/fastapi_configuration.mdx index 5387d2a3..17f22484 100644 --- a/docs/docs/single-tenant/fastapi_configuration.mdx +++ b/docs/docs/single-tenant/fastapi_configuration.mdx @@ -41,7 +41,7 @@ if __name__ == '__main__': Run your application and ensure that everything works on [http://localhost:8000/docs](http://localhost:8000/docs) :::info -You need to run the application on the configured port in Azure AD for the next steps to work! +You need to run the application on the configured port in Azure Entra ID for the next steps to work! ::: ## Add your settings @@ -175,7 +175,7 @@ if __name__ == '__main__': uvicorn.run('main:app', reload=True) ``` -The `swagger_ui_oauth2_redirect_url` setting for redirect should be as configured in Azure AD. +The `swagger_ui_oauth2_redirect_url` setting for redirect should be as configured in Azure Entra ID. The `swagger_ui_init_oauth` are standard mapped OpenAPI properties. You can find documentation about them [here](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/) We've used two flags: `usePkceWithAuthorizationCodeGrant`, which is the authentication flow. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 144abf02..0142ac67 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -4,7 +4,7 @@ const darkCodeTheme = require('prism-react-renderer').themes.dracula /** @type {import('@docusaurus/types').DocusaurusConfig} */ module.exports = { title: 'FastAPI-Azure-Auth', - tagline: 'Easy and secure implementation of Azure AD for your FastAPI APIs ๐Ÿ”’', + tagline: 'Easy and secure implementation of Azure Entra ID for your FastAPI APIs ๐Ÿ”’', url: 'https://your-docusaurus-test-site.com', baseUrl: '/fastapi-azure-auth/', onBrokenLinks: 'throw', diff --git a/fastapi_azure_auth/auth.py b/fastapi_azure_auth/auth.py index 898fddca..38a6e3f0 100644 --- a/fastapi_azure_auth/auth.py +++ b/fastapi_azure_auth/auth.py @@ -50,13 +50,13 @@ def __init__( Initialize settings. :param app_client_id: str - Your application client ID. This will be the `Web app` in Azure AD + Your application client ID. This will be the `Web app` in Azure Entra ID :param auto_error: bool Whether to throw exceptions or return None on __call__. :param tenant_id: str Your Azure tenant ID, only needed for single tenant apps :param scopes: Optional[dict[str, str] - Scopes, these are the ones you've configured in Azure AD. Key is scope, value is a description. + Scopes, these are the ones you've configured in Azure Entra ID. Key is scope, value is a description. Example: { f'api://{settings.APP_CLIENT_ID}/user_impersonation': 'user impersonation' @@ -181,7 +181,7 @@ async def __call__(self, request: HTTPConnection, security_scopes: SecurityScope # Use the `kid` from the header to find a matching signing key to use try: if key := self.openid_config.signing_keys.get(header.get('kid', '')): - # We require and validate all fields in an Azure AD token + # We require and validate all fields in an Azure Entra ID token required_claims = ['exp', 'aud', 'iat', 'nbf', 'sub'] if self.validate_iss: required_claims.append('iss') @@ -277,13 +277,13 @@ def __init__( Initialize settings for a single tenant application. :param app_client_id: str - Your application client ID. This will be the `Web app` in Azure AD + Your application client ID. This will be the `Web app` in Azure Entra ID :param tenant_id: str Your Azure tenant ID, only needed for single tenant apps :param auto_error: bool Whether to throw exceptions or return None on __call__. :param scopes: Optional[dict[str, str] - Scopes, these are the ones you've configured in Azure AD. Key is scope, value is a description. + Scopes, these are the ones you've configured in Azure Entra ID. Key is scope, value is a description. Example: { f'api://{settings.APP_CLIENT_ID}/user_impersonation': 'user impersonation' @@ -342,11 +342,11 @@ def __init__( Initialize settings for a multi-tenant application. :param app_client_id: str - Your application client ID. This will be the `Web app` in Azure AD + Your application client ID. This will be the `Web app` in Azure Entra ID :param auto_error: bool Whether to throw exceptions or return None on __call__. :param scopes: Optional[dict[str, str] - Scopes, these are the ones you've configured in Azure AD. Key is scope, value is a description. + Scopes, these are the ones you've configured in Azure Entra ID. Key is scope, value is a description. Example: { f'api://{settings.APP_CLIENT_ID}/user_impersonation': 'user impersonation' @@ -413,13 +413,13 @@ def __init__( """ Initialize settings for a B2C multi-tenant application. :param app_client_id: str - Your application client ID. This will be the `Web app` in Azure AD + Your application client ID. This will be the `Web app` in Azure Entra ID :param openid_config_url: str Override OpenID config URL (used for B2C tenants) :param auto_error: bool Whether to throw exceptions or return None on __call__. :param scopes: Optional[dict[str, str] - Scopes, these are the ones you've configured in Azure AD. Key is scope, value is a description. + Scopes, these are the ones you've configured in Azure Entra ID. Key is scope, value is a description. Example: { f'api://{settings.APP_CLIENT_ID}/user_impersonation': 'user impersonation' diff --git a/fastapi_azure_auth/openid_config.py b/fastapi_azure_auth/openid_config.py index 6d402ce7..470fc4a0 100644 --- a/fastapi_azure_auth/openid_config.py +++ b/fastapi_azure_auth/openid_config.py @@ -38,23 +38,23 @@ async def load_config(self) -> None: refresh_time = datetime.now() - timedelta(hours=24) if not self._config_timestamp or self._config_timestamp < refresh_time: try: - log.debug('Loading Azure AD OpenID configuration.') + log.debug('Loading Azure Entra ID OpenID configuration.') await self._load_openid_config() self._config_timestamp = datetime.now() except Exception as error: - log.exception('Unable to fetch OpenID configuration from Azure AD. Error: %s', error) + log.exception('Unable to fetch OpenID configuration from Azure Entra ID. Error: %s', error) # We can't fetch an up to date openid-config, so authentication will not work. if self._config_timestamp: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, - detail='Connection to Azure AD is down. Unable to fetch provider configuration', + detail='Connection to Azure Entra ID is down. Unable to fetch provider configuration', headers={'WWW-Authenticate': 'Bearer'}, ) from error else: raise RuntimeError(f'Unable to fetch provider information. {error}') from error - log.info('fastapi-azure-auth loaded settings from Azure AD.') + log.info('fastapi-azure-auth loaded settings from Azure Entra ID.') log.info('authorization endpoint: %s', self.authorization_endpoint) log.info('token endpoint: %s', self.token_endpoint) log.info('issuer: %s', self.issuer) diff --git a/fastapi_azure_auth/user.py b/fastapi_azure_auth/user.py index 3d5d0804..37cb93a0 100644 --- a/fastapi_azure_auth/user.py +++ b/fastapi_azure_auth/user.py @@ -16,7 +16,7 @@ class Claims(BaseModel): ) iss: str = Field( ..., - description='Identifies the STS that constructs and returns the token, and the Azure AD tenant of the' + description='Identifies the STS that constructs and returns the token, and the Azure Entra ID tenant of the' ' authenticated user. If the token issued is a v2.0 token (see the ver claim), the URI ends in /v2.0.', ) idp: Optional[str] = Field( @@ -39,7 +39,7 @@ class Claims(BaseModel): ) aio: Optional[str] = Field( default=None, - description='An internal claim used by Azure AD to record data for token reuse. Resources should not use this claim.', + description='An internal claim used by Azure Entra ID to record data for token reuse. Resources should not use this claim.', ) name: Optional[str] = Field( default=None, @@ -55,7 +55,7 @@ class Claims(BaseModel): ) wids: List[str] = Field( default=[], - description='Denotes the tenant-wide roles assigned to this user, from the section of roles present in Azure AD built-in roles.', + description='Denotes the tenant-wide roles assigned to this user, from the section of roles present in Azure Entra ID built-in roles.', ) groups: List[str] = Field( default=[], @@ -86,7 +86,7 @@ class Claims(BaseModel): description='Indicates the version of the access token.', ) - # Optional claims, configured in Azure AD + # Optional claims, configured in Azure Entra ID acct: Optional[int] = Field( default=None, description="User's account status in tenant", diff --git a/pyproject.toml b/pyproject.toml index 46a8cb2e..e376a828 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "fastapi-azure-auth" version = "5.0.1" # Remember to change in __init__.py as well -description = "Easy and secure implementation of Azure AD for your FastAPI APIs" +description = "Easy and secure implementation of Azure Entra ID for your FastAPI APIs" authors = ["Jonas Krรผger Svensson "] readme = "README.md" homepage = "https://github.com/intility/fastapi-azure-auth" @@ -14,6 +14,9 @@ keywords = [ 'authentication', 'azure', 'azure ad', + 'azure entra id', + 'azure entra', + 'entra id', 'azuread', 'fastapi', 'multi tenant', diff --git a/tests/test_openapi_scheme.py b/tests/test_openapi_scheme.py index bf10e454..907f9fb9 100644 --- a/tests/test_openapi_scheme.py +++ b/tests/test_openapi_scheme.py @@ -82,7 +82,7 @@ 'HelloWorldResponse': { 'properties': { 'hello': {'type': 'string', 'title': 'Hello', 'description': "What we're saying hello to"}, - 'user': {'allOf': [{'$ref': '#/components/schemas/User'}], 'description': 'The user object'}, + 'user': {'$ref': '#/components/schemas/User', 'description': 'The user object'}, }, 'type': 'object', 'required': ['hello', 'user'], @@ -107,7 +107,7 @@ 'iss': { 'type': 'string', 'title': 'Iss', - 'description': 'Identifies the STS that constructs and returns the token, and the Azure AD tenant of the authenticated user. If the token issued is a v2.0 token (see the ver claim), the URI ends in /v2.0.', + 'description': 'Identifies the STS that constructs and returns the token, and the Azure Entra ID tenant of the authenticated user. If the token issued is a v2.0 token (see the ver claim), the URI ends in /v2.0.', }, 'idp': { 'anyOf': [{'type': 'string'}, {'type': 'null'}], @@ -132,7 +132,7 @@ 'aio': { 'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Aio', - 'description': 'An internal claim used by Azure AD to record data for token reuse. Resources should not use this claim.', + 'description': 'An internal claim used by Azure Entra ID to record data for token reuse. Resources should not use this claim.', }, 'name': { 'anyOf': [{'type': 'string'}, {'type': 'null'}], @@ -157,7 +157,7 @@ 'items': {'type': 'string'}, 'type': 'array', 'title': 'Wids', - 'description': 'Denotes the tenant-wide roles assigned to this user, from the section of roles present in Azure AD built-in roles.', + 'description': 'Denotes the tenant-wide roles assigned to this user, from the section of roles present in Azure Entra ID built-in roles.', 'default': [], }, 'groups': { diff --git a/tests/test_provider_config.py b/tests/test_provider_config.py index 8779ad61..757f0c56 100644 --- a/tests/test_provider_config.py +++ b/tests/test_provider_config.py @@ -20,7 +20,7 @@ async def test_http_error_old_config_found(respx_mock, mock_config_timestamp): app=app, base_url='http://test', headers={'Authorization': f'Bearer {build_access_token()}'} ) as ac: response = await ac.get('api/v1/hello') - assert response.json() == {'detail': 'Connection to Azure AD is down. Unable to fetch provider configuration'} + assert response.json() == {'detail': 'Connection to Azure Entra ID is down. Unable to fetch provider configuration'} @pytest.mark.anyio