From e874374b7feafc602cada9b24041537d823fdddd Mon Sep 17 00:00:00 2001 From: Christian Seifert Date: Fri, 16 Aug 2024 16:48:40 +0200 Subject: [PATCH] Allow definition of additional OAuth2 authentication providers besides Google --- README.md | 146 ++++++++++-------- development/authentik/.gitignore | 2 + development/authentik/docker-compose.yml | 80 ++++++++++ .../FixedAuthenticationConfiguration.java | 6 +- ...henticationClientRegistrationProvider.java | 9 ++ .../Oauth2AuthenticationConfiguration.java | 38 ++++- .../Oauth2AuthenticationLoginController.java | 2 +- .../Oauth2AuthenticationUserService.java | 4 - .../GenericClientRegistrationProvider.java | 44 ++++++ .../GoogleClientRegistrationProvider.java | 46 ++++++ src/main/resources/application.yml | 11 -- 11 files changed, 306 insertions(+), 82 deletions(-) create mode 100644 development/authentik/.gitignore create mode 100644 development/authentik/docker-compose.yml create mode 100644 src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationClientRegistrationProvider.java create mode 100644 src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GenericClientRegistrationProvider.java create mode 100644 src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GoogleClientRegistrationProvider.java diff --git a/README.md b/README.md index 9b2afee..8b73f6e 100644 --- a/README.md +++ b/README.md @@ -14,38 +14,11 @@ Therefore, with no suitable tool available, I decided to create one myself. The ![Home screen](docs/screenshots/home.png) -# Build - -Flightlog is a [Spring Boot application](https://spring.io/guides/gs/spring-boot/) and can be built and executed accordingly: - - $ git clone https://github.com/perdian/flightlog.git - $ cd flightlog - $ mvn clean package - -This creates the application JAR file into `target/flightlog.jar` - -# Run - -## JAR - -The JAR file already contains everything needed to start Flighlog with its default settings: - - $ mvn clean package - $ java -jar target/flightlog.jar - -The application will now start and is accessible at - - http://localhost:8080/flightlog/ - -An embedded H2 database file will be stored at `~/.flightlog/`. Both the database location as well as the database type can be configured using environment variables (see the **Configuration** section for details). - -## Docker container - -### Fetch from Docker Hub +# Installation -An alternative do running the JAR file directly is to create a Docker container that wraps the complete application. +### Docker container -Releases are automatically pushed to Docker Hub so all you need to do is to run the Docker image. +The easiest way to start a flightlog application is by starting a Docker container which can be easily fetched from [DockerHub](https://hub.docker.com/r/perdian/flightlog) (new releases are automatically pushed to Docker Hub so all you need to do is to start a Docker container). $ docker run -p 8080:8080 perdian/flightlog:latest @@ -55,30 +28,15 @@ The application will be available on the machine on which you're executing the c http://localhost:8080/flightlog/ -An embedded H2 database file will stored as volume for the created container. It can be configured using environment variables (see the **Configuration** section for details). +An embedded H2 database file will be used, mounted as volume for the created container. It can be configured using environment variables (see the [**Configuration**](#configuration) section for details). -To persist the database you have to mount the directory `/var/flightlog/database/` from the container to somewhere on your host machine: +To persist the database you have to mount the directory `/var/flightlog/database/` from the Docker container to somewhere on your host machine: $ docker run -v /path/to/your/host/directory:/var/flightlog/database -p 8080:8080 perdian/flightlog -### Build from sources - -If you want to build the Docker image yourself from the sources it can be done like this: - - $ mvn clean package - $ docker build -t perdian/flightlog . - -After the container is built you can verify the application by running it: - - $ docker run -p 8080:8080 perdian/flightlog - -The application will be available on the machine on which you're executing the container at: - - http://localhost:8080/flightlog/ - # Configuration -The complete configuration can be done through environment variables so whether you're launching the application directly from the JAR file or via a Docker container the same set of environment variables is used. +The complete configuration can be done through environment variables so whether you're launching the application as a Docker container or through any other method the same set of environment variables can be used. ## Database @@ -94,42 +52,68 @@ By default an embedded H2 database is used but any database supported by Hiberna ## Authentication -The application ships with a few options of authentication providers available. +The application ships with a few options of authentication providers readily available. By default no authentication is required, which means without any additional configuration the application works in a single user mode: All flights are implicitly linked to a single user named `example@example.com`. +The user won't have to authenticate but will automatically be authenticated with every request. -## OAuth2 authentication +The email of the user can be changed by setting the environment variable `FLIGHTLOG_AUTHENTICATION_FIXED_DEFAULT_EMAIL_ADDRESS`. -Flightlog supports OAuth2 authentication via the following providers: +### OAuth2 authentication -* Google +Flightlog supports OAuth2 authentication via any OAuth2 authentication providers. +To enable an OAuth2 authentication provider you have to set the `FLIGHTLOG_AUTHENTICATION_TYPE` environment variable to `OAUTH2`. -To enable the OAuth authentication you have to set the `FLIGHTLOG_AUTHENTICATION_TYPE` environment variable to `oauth2` +For each login the application will perform an OAuth2 authentication. +After the successful authentication an entry within the `flightuser_user` database table will be made, populated with the values retrieved from the OAuth2 provider. + +#### Google -For each login the application will perform an OAuth2 authentication. After the successful authentication an entry within the `flightuser_user` will be made, populated with the values retrieved from the OAuth2 provider. +To enable the OAuth authentication you have to set the `FLIGHTLOG_AUTHENTICATION_TYPE` environment variable to `oauth2` The following environment variables have to be set to the OAuth2 credentials retrieved from the Google Cloud console: * `FLIGHTLOG_AUTHENTICATION_OAUTH2_GOOGLE_CLIENT_ID` * `FLIGHTLOG_AUTHENTICATION_OAUTH2_GOOGLE_CLIENT_SECRET` +> The redirect URL `/login/oauth2/code/flightlog` must be entered in the Google Cloud console for your Google application. +> +> For example if you run Flightlog directly from the Docker container on `localhost` via `http://localhost:8080/flightlog/` then the redirect URL that needs to be configured at Google is `http://localhost:8080/flightlog//login/oauth2/code/flightlog`. + +#### Generic OAuth2 authentication provider + +Any other OAuth2 authentication provider can be configured in a similar manner to Google but with a few more environment variables required. + +The examples listed below are taken from an [Authentik](https://goauthentik.io) installation run directly from a [Docker container](https://docs.goauthentik.io/docs/installation/docker-compose): + +| Environment variable | Required | Default value | Example | +| -------------------- | -------- | ------------- | ------- | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_CLIENT_ID` | Yes | | `abc123` | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_CLIENT_SECRET` | Yes | | `xyz987` | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_CLIENT_NAME` | No | `flightlog` | | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_AUTHORIZATION_URI` | Yes | | `http://localhost:9000/application/o/authorize/` | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_TOKEN_URI` | Yes | | `http://localhost:9000/application/o/token/` | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_USER_INFO_URI` | Yes | | `http://localhost:9000/application/o/userinfo/` | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_USER_NAME_ATTRIBUTE` | No | `name` | | +| `FLIGHTLOG_AUTHENTICATION_OAUTH2_JWK_SET_URI` | Yes | | `http://localhost:9000/application/o/flightlog/jwks/` | + ## Whitelisting users -By default no new users can be registered in a flightlog applcation. This is a conscious choice to prohibit someone spamming the system and creating entries in the database by simply performing multiple OAuth2 authentications. +**By default no new users can register themselves in a Flightlog application**. + +This is a conscious choice to prohibit someone spamming the system and creating entries in the database by simply performing multiple OAuth2 authentications. There are two ways to allow an authentication from a new OAuth2 account: ### Disabling registration blocker -By setting the environment variable `FLIGHTLOG_REGISTRATION_ALLOW_BY_DEFAULT` to `true` will bypass the check for existence and will create a new entry in the local database for every new account authenticated via OAuth2. - -### Adding the email address to the whitelist +Setting the environment variable `FLIGHTLOG_REGISTRATION_ALLOW_BY_DEFAULT` to `true` will bypass the check for existence and will create a new entry in the local database for every new account authenticated via the currently configured OAuth2 authentication provider. -When a new OAuth2 account is found the system will check the internal *whitelist* whether the email address of the new user is found in the whitelist. If that's the case then the new user will be added into the database and the authentication will succeed. +### Adding the email address to the allowlist -To place one (or more) user(s) on the whitelist add the email addresses to the environment variable `FLIGHTLOG_REGISTRATION_EMAIL_ADDRESSES_ALLOWLIST` (separate multiple addresses by comma). +When a new OAuth2 account is found the system will check the internal *allowlist* whether the email address of the new user is found on the allowlist. If that's the case then the new user will be added into the database and the authentication will succeed. -A second option (which is mainly designed for a personal installation without any open registration) is to add the whitelisted email addresses directly as environment variable `FLIGHTLOG_AUTHENTICATION_REGISTRATION_EMAIL_WHITELIST`: +To place one or more user(s) on the allowlist add the email addresses to the environment variable `FLIGHTLOG_REGISTRATION_EMAIL_ADDRESSES_ALLOWLIST` (separate multiple addresses by commata). ## Other environment variables @@ -139,6 +123,46 @@ A second option (which is mainly designed for a personal installation without an | `FLIGHTLOG_SERVER_CONTEXT_PATH` | `/flighlog` | The context path under which the application will be made available. The default value `/flightlog` implies that when using the default port of `8080` the applications main page can be reached at `http://localhost:8080/flightlog`. | | `FLIGHTLOG_SERVER_COOKIE_NAME` | `flightlog-session` | The name of the cookie that is used to store session related data. | +# Build + +Flightlog is a [Spring Boot application](https://spring.io/guides/gs/spring-boot/) and can be built and executed accordingly: + + $ git clone https://github.com/perdian/flightlog.git + $ cd flightlog + $ mvn clean package + +This creates the application JAR file into `target/flightlog.jar` + +# Run + +## JAR + +The JAR file already contains everything needed to start Flighlog with its default settings: + + $ mvn clean package + $ java -jar target/flightlog.jar + +The application will now start and is accessible at + + http://localhost:8080/flightlog/ + +An embedded H2 database file will be stored at `~/.flightlog/`. Both the database location as well as the database type can be configured using environment variables (see the **Configuration** section for details). + +### Build from sources + +If you want to build the Docker image yourself from the sources it can be done like this: + + $ mvn clean package + $ docker build -t perdian/flightlog . + +After the container is built you can verify the application by running it: + + $ docker run -p 8080:8080 perdian/flightlog + +The application will be available on the machine on which you're executing the container at: + + http://localhost:8080/flightlog/ + # Credits This application would not be possible without the great work of other open source projects. diff --git a/development/authentik/.gitignore b/development/authentik/.gitignore new file mode 100644 index 0000000..6ee0103 --- /dev/null +++ b/development/authentik/.gitignore @@ -0,0 +1,2 @@ +/data +/.env diff --git a/development/authentik/docker-compose.yml b/development/authentik/docker-compose.yml new file mode 100644 index 0000000..042c376 --- /dev/null +++ b/development/authentik/docker-compose.yml @@ -0,0 +1,80 @@ +--- + +services: + postgresql: + image: docker.io/library/postgres:16-alpine + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 5s + volumes: + - ./data/database:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: ${PG_PASS:?database password required} + POSTGRES_USER: ${PG_USER:-authentik} + POSTGRES_DB: ${PG_DB:-authentik} + env_file: + - .env + redis: + image: docker.io/library/redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 3s + volumes: + - ./data/redis:/data + server: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.3} + restart: unless-stopped + command: server + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + volumes: + - ./data/media:/media + - ./data/custom-templates:/templates + env_file: + - .env + ports: + - "${COMPOSE_PORT_HTTP:-9000}:9000" + - "${COMPOSE_PORT_HTTPS:-9443}:9443" + depends_on: + - postgresql + - redis + worker: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.3} + restart: unless-stopped + command: worker + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + # `user: root` and the docker socket volume are optional. + # See more for the docker socket integration here: + # https://goauthentik.io/docs/outposts/integrations/docker + # Removing `user: root` also prevents the worker from fixing the permissions + # on the mounted folders, so when removing this make sure the folders have the correct UID/GID + # (1000:1000 by default) + user: root + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./data/media:/media + - ./data/certs:/certs + - ./data/custom-templates:/templates + env_file: + - .env + depends_on: + - postgresql + - redis diff --git a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/fixed/FixedAuthenticationConfiguration.java b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/fixed/FixedAuthenticationConfiguration.java index fa7cf21..71ab1d3 100644 --- a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/fixed/FixedAuthenticationConfiguration.java +++ b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/fixed/FixedAuthenticationConfiguration.java @@ -5,14 +5,14 @@ import de.perdian.flightlog.modules.authentication.persistence.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.domain.Specification; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @Configuration -@ConditionalOnProperty(name = "flightlog.authentication.type", havingValue = "fixed") +@ConditionalOnExpression("#{environment['FLIGHTLOG_AUTHENTICATION_TYPE'] == null or environment['FLIGHTLOG_AUTHENTICATION_TYPE'].toUpperCase() == 'FIXED'}") public class FixedAuthenticationConfiguration extends AbstractAuthenticationConfiguration { private UserRepository userRepository = null; @@ -46,7 +46,7 @@ FixedAuthenticationFilter fixedAuthenticationFilter() { String getEmailAddress() { return this.emailAddress; } - @Value("${flightlog.authentication.fixed.defaultEmailAddress:}") + @Value("${FLIGHTLOG_AUTHENTICATION_FIXED_DEFAULT_EMAIL_ADDRESS:example@example.com}") void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } diff --git a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationClientRegistrationProvider.java b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationClientRegistrationProvider.java new file mode 100644 index 0000000..043aa61 --- /dev/null +++ b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationClientRegistrationProvider.java @@ -0,0 +1,9 @@ +package de.perdian.flightlog.modules.authentication.configuration.oauth2; + +import org.springframework.security.oauth2.client.registration.ClientRegistration; + +public interface Oauth2AuthenticationClientRegistrationProvider { + + ClientRegistration createRegistration(String registrationId); + +} diff --git a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationConfiguration.java b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationConfiguration.java index cb5c710..592b1fd 100644 --- a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationConfiguration.java +++ b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationConfiguration.java @@ -1,15 +1,25 @@ package de.perdian.flightlog.modules.authentication.configuration.oauth2; import de.perdian.flightlog.modules.authentication.configuration.AbstractAuthenticationConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; + +import java.util.List; @Configuration -@ConditionalOnProperty(name = "flightlog.authentication.type", havingValue = "oauth2") +@ConditionalOnExpression("#{environment['FLIGHTLOG_AUTHENTICATION_TYPE'] == null or environment['FLIGHTLOG_AUTHENTICATION_TYPE'].toUpperCase() == 'OAUTH2'}") class Oauth2AuthenticationConfiguration extends AbstractAuthenticationConfiguration { + static final String REGISTRATION_ID = "flightlog"; + + private List registrationProviders = null; + @Override protected void configureSecurityFilterChainHttpSecurity(HttpSecurity httpSecurity) throws Exception { @@ -27,4 +37,28 @@ Oauth2AuthenticationUserService oidcUserService() { return new Oauth2AuthenticationUserService(); } + @Bean + ClientRegistration clientRegistration() { + for (Oauth2AuthenticationClientRegistrationProvider registrationProvider : this.getRegistrationProviders()) { + ClientRegistration registration = registrationProvider.createRegistration(REGISTRATION_ID); + if (registration != null) { + return registration; + } + } + throw new IllegalArgumentException("Cannot create OAuth2 ClientRegistration instance from any provider"); + } + + @Bean + ClientRegistrationRepository clientRegistrationRepository() { + return new InMemoryClientRegistrationRepository(this.clientRegistration()); + } + + List getRegistrationProviders() { + return this.registrationProviders; + } + @Autowired + void setRegistrationProviders(List registrationProviders) { + this.registrationProviders = registrationProviders; + } + } diff --git a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationLoginController.java b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationLoginController.java index b840c25..592de55 100644 --- a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationLoginController.java +++ b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationLoginController.java @@ -34,7 +34,7 @@ String doLogin(Model model, HttpServletRequest servletRequest) { httpSession.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION); return "authentication/login/oauth-error"; } else { - return "redirect:/oauth2/authorization/google"; + return "redirect:/oauth2/authorization/" + Oauth2AuthenticationConfiguration.REGISTRATION_ID; } } diff --git a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationUserService.java b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationUserService.java index 5fe192f..ef73657 100644 --- a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationUserService.java +++ b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/Oauth2AuthenticationUserService.java @@ -63,10 +63,6 @@ private UserEntity ensureUserEntity(OidcUser oidcUser) { } - private boolean checkUserAllowedToRegister(OidcUser oidcUser) { - return false; - } - UserRepository getUserRepository() { return this.userRepository; } diff --git a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GenericClientRegistrationProvider.java b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GenericClientRegistrationProvider.java new file mode 100644 index 0000000..332fb2c --- /dev/null +++ b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GenericClientRegistrationProvider.java @@ -0,0 +1,44 @@ +package de.perdian.flightlog.modules.authentication.configuration.oauth2.impl; + +import de.perdian.flightlog.modules.authentication.configuration.oauth2.Oauth2AuthenticationClientRegistrationProvider; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.Order; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.stereotype.Component; + +@Component +@Order(10) +class GenericClientRegistrationProvider implements Oauth2AuthenticationClientRegistrationProvider { + + @Override + public ClientRegistration createRegistration(String registrationId) { + return ClientRegistration.withRegistrationId(registrationId) + .clientId(this.extractRequiredEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_CLIENT_ID")) + .clientSecret(this.extractRequiredEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_CLIENT_SECRET")) + .clientName(this.extractEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_CLIENT_NAME", "flightlog")) + .redirectUri("{baseUrl}/{action}/oauth2/code/{registrationId}") + .authorizationUri(this.extractRequiredEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_AUTHORIZATION_URI")) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .tokenUri(this.extractRequiredEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_TOKEN_URI")) + .userInfoUri(this.extractRequiredEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_USER_INFO_URI")) + .userNameAttributeName(this.extractEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_USER_NAME_ATTRIBUTE", "name")) + .jwkSetUri(this.extractRequiredEnvironmentVariable("FLIGHTLOG_AUTHENTICATION_OAUTH2_JWK_SET_URI")) + .scope("openid", "profile", "email") + .build(); + } + + private String extractEnvironmentVariable(String environmentVariable, String defaultValue) { + return StringUtils.defaultIfEmpty(System.getenv(environmentVariable), defaultValue); + } + + private String extractRequiredEnvironmentVariable(String environmentVariable) { + String environmentVariableValue = System.getenv(environmentVariable); + if (StringUtils.isEmpty(environmentVariableValue)) { + throw new IllegalArgumentException("Required environment variable is not set: " + environmentVariable); + } else { + return environmentVariableValue; + } + } + +} diff --git a/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GoogleClientRegistrationProvider.java b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GoogleClientRegistrationProvider.java new file mode 100644 index 0000000..d0d98f3 --- /dev/null +++ b/src/main/java/de/perdian/flightlog/modules/authentication/configuration/oauth2/impl/GoogleClientRegistrationProvider.java @@ -0,0 +1,46 @@ +package de.perdian.flightlog.modules.authentication.configuration.oauth2.impl; + +import de.perdian.flightlog.modules.authentication.configuration.oauth2.Oauth2AuthenticationClientRegistrationProvider; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.oauth2.client.CommonOAuth2Provider; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.stereotype.Component; + +@Component +@Order(0) +class GoogleClientRegistrationProvider implements Oauth2AuthenticationClientRegistrationProvider { + + private String googleClientId = null; + private String googleClientSecret = null; + + @Override + public ClientRegistration createRegistration(String registrationId) { + if (StringUtils.isNotEmpty(this.getGoogleClientId()) || StringUtils.isNotEmpty(this.getGoogleClientSecret())) { + return CommonOAuth2Provider.GOOGLE.getBuilder(registrationId) + .clientId(this.getGoogleClientId()) + .clientSecret(this.getGoogleClientSecret()) + .build(); + } else { + return null; + } + } + + String getGoogleClientId() { + return this.googleClientId; + } + @Value("${FLIGHTLOG_AUTHENTICATION_OAUTH2_GOOGLE_CLIENT_ID:}") + void setGoogleClientId(String googleClientId) { + this.googleClientId = googleClientId; + } + + String getGoogleClientSecret() { + return this.googleClientSecret; + } + @Value("${FLIGHTLOG_AUTHENTICATION_OAUTH2_GOOGLE_CLIENT_SECRET:}") + void setGoogleClientSecret(String googleClientSecret) { + this.googleClientSecret = googleClientSecret; + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8c5cf8a..a1df0e8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -8,13 +8,6 @@ spring: open-in-view: false hibernate: ddl-auto: update - security: - oauth2: - client: - registration: - google: - client-id: ${FLIGHTLOG_AUTHENTICATION_OAUTH2_GOOGLE_CLIENT_ID:null} - client-secret: ${FLIGHTLOG_AUTHENTICATION_OAUTH2_GOOGLE_CLIENT_SECRET:null} servlet: multipart: max-file-size: 10MB @@ -40,10 +33,6 @@ server: force: true flightlog: - authentication: - type: ${FLIGHTLOG_AUTHENTICATION_TYPE:fixed} - fixed: - defaultEmailAddress: ${FLIGHTLOG_AUTHENTICATION_FIXED_DEFAULT_EMAIL_ADDRESS:example@example.com} registration: emailAddressesAllowlist: ${FLIGHTLOG_REGISTRATION_EMAIL_ADDRESSES_ALLOWLIST:} allowByDefault: ${FLIGHTLOG_REGISTRATION_ALLOW_BY_DEFAULT:false}