diff --git a/docs/docs/documentation/getting-started/authentication/oidc.md b/docs/docs/documentation/getting-started/authentication/oidc.md index fc8764ffe87e..1d6119a1b6cc 100644 --- a/docs/docs/documentation/getting-started/authentication/oidc.md +++ b/docs/docs/documentation/getting-started/authentication/oidc.md @@ -46,6 +46,14 @@ Before you can start using OIDC Authentication, you must first configure a new c Take the client id and your discovery URL and update your environment variables to include the required OIDC variables described in [Installation - Backend Configuration](../installation/backend-config.md#openid-connect-oidc). +### Groups + +There are two (optional) [environment variables](../installation/backend-config.md#openid-connect-oidc) that can control which of the users in your IdP can log in to Mealie and what permissions they will have. The groups should be **defined in your IdP** and be returned in the `groups` claim. + +`OIDC_USER_GROUP`: Users must be a part of this group (within your IdP) to be able to log in. + +`OIDC_ADMIN_GROUP`: Users that are in this group (within your IdP) will be made an **admin** in Mealie. + ## Examples Example configurations for several Identity Providers have been provided by the Community in the [GitHub Discussions](https://github.com/mealie-recipes/mealie/discussions/categories/oauth-provider-example). diff --git a/docs/docs/documentation/getting-started/installation/backend-config.md b/docs/docs/documentation/getting-started/installation/backend-config.md index 657b42e72bf0..8f0379c2f8f2 100644 --- a/docs/docs/documentation/getting-started/installation/backend-config.md +++ b/docs/docs/documentation/getting-started/installation/backend-config.md @@ -85,11 +85,12 @@ For usage, see [Usage - OpenID Connect](../authentication/oidc.md) | OIDC_SIGNUP_ENABLED | True | Enables new users to be created when signing in for the first time with OIDC | | OIDC_CONFIGURATION_URL | None | The URL to the OIDC configuration of your provider. This is usually something like https://auth.example.com/.well-known/openid-configuration | | OIDC_CLIENT_ID | None | The client id of your configured client in your provider | -| OIDC_USER_GROUP| None | If specified, only users belonging to this group will be able to successfully authenticate, regardless of the OIDC_ADMIN_GROUP | -| OIDC_ADMIN_GROUP | None | If specified, users belonging to this group will be made an admin | +| OIDC_USER_GROUP| None | If specified, only users belonging to this group will be able to successfully authenticate, regardless of the `OIDC_ADMIN_GROUP`. For more information see [this page](../authentication/oidc.md#groups) | +| OIDC_ADMIN_GROUP | None | If specified, users belonging to this group will be made an admin. For more information see [this page](../authentication/oidc.md#groups) | | OIDC_AUTO_REDIRECT | False | If `True`, then the login page will be bypassed an you will be sent directly to your Identity Provider. You can still get to the login page by adding `?direct=1` to the login URL | | OIDC_PROVIDER_NAME | OAuth | The provider name is shown in SSO login button. "Login with " | | OIDC_REMEMBER_ME | False | Because redirects bypass the login screen, you cant extend your session by clicking the "Remember Me" checkbox. By setting this value to true, a session will be extended as if "Remember Me" was checked | +| OIDC_SIGNING_ALGORITHM | RS256 | The algorithm used to sign the id token (examples: RS256, HS256) | ### Themeing diff --git a/docs/docs/overrides/api.html b/docs/docs/overrides/api.html index 542d50c80d7b..1a9cf805c033 100644 --- a/docs/docs/overrides/api.html +++ b/docs/docs/overrides/api.html @@ -14,7 +14,7 @@
diff --git a/mealie/core/security/providers/openid_provider.py b/mealie/core/security/providers/openid_provider.py index 3416b4ef0e5c..af8cd83fa54a 100644 --- a/mealie/core/security/providers/openid_provider.py +++ b/mealie/core/security/providers/openid_provider.py @@ -3,13 +3,14 @@ from functools import lru_cache import requests from authlib.jose import JsonWebKey, JsonWebToken, JWTClaims, KeySet -from authlib.jose.errors import ExpiredTokenError +from authlib.jose.errors import ExpiredTokenError, UnsupportedAlgorithmError from authlib.oidc.core import CodeIDToken from sqlalchemy.orm.session import Session from mealie.core import root_logger from mealie.core.config import get_app_settings from mealie.core.security.providers.auth_provider import AuthProvider +from mealie.core.settings.settings import AppSettings from mealie.db.models.users.users import AuthMethod from mealie.repos.all_repositories import get_repositories from mealie.schema.user.auth import OIDCRequest @@ -26,11 +27,11 @@ class OpenIDProvider(AuthProvider[OIDCRequest]): async def authenticate(self) -> tuple[str, timedelta] | None: """Attempt to authenticate a user given a username and password""" - claims = self.get_claims() + settings = get_app_settings() + claims = self.get_claims(settings) if not claims: return None - settings = get_app_settings() repos = get_repositories(self.session) user = self.try_get_user(claims.get("email")) @@ -76,13 +77,20 @@ class OpenIDProvider(AuthProvider[OIDCRequest]): self._logger.info("[OIDC] Found user but their AuthMethod does not match OIDC") return None - def get_claims(self) -> JWTClaims | None: + def get_claims(self, settings: AppSettings) -> JWTClaims | None: """Get the claims from the ID token and check if the required claims are present""" required_claims = {"preferred_username", "name", "email"} jwks = OpenIDProvider.get_jwks() if not jwks: return None - claims = JsonWebToken(["RS256"]).decode(s=self.data.id_token, key=jwks, claims_cls=CodeIDToken) + + algorithm = settings.OIDC_SIGNING_ALGORITHM + try: + claims = JsonWebToken([algorithm]).decode(s=self.data.id_token, key=jwks, claims_cls=CodeIDToken) + except UnsupportedAlgorithmError as e: + self._logger.error( + f"[OIDC] Unsupported algorithm '{algorithm}'. Unable to decode id token due to mismatched algorithm." + ) try: claims.validate() diff --git a/mealie/core/settings/settings.py b/mealie/core/settings/settings.py index 52e0ad050ce1..96b379a8b3aa 100644 --- a/mealie/core/settings/settings.py +++ b/mealie/core/settings/settings.py @@ -182,6 +182,7 @@ class AppSettings(BaseSettings): OIDC_AUTO_REDIRECT: bool = False OIDC_PROVIDER_NAME: str = "OAuth" OIDC_REMEMBER_ME: bool = False + OIDC_SIGNING_ALGORITHM: str = "RS256" @property def OIDC_READY(self) -> bool: