diff --git a/reacthookspring/application/src/main/java/de/starwit/application/config/CustomClientRegistration.java b/reacthookspring/application/src/main/java/de/starwit/application/config/CustomClientRegistration.java new file mode 100644 index 0000000..19a84a6 --- /dev/null +++ b/reacthookspring/application/src/main/java/de/starwit/application/config/CustomClientRegistration.java @@ -0,0 +1,101 @@ +package de.starwit.application.config; + +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +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 org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.validation.annotation.Validated; + +import jakarta.validation.constraints.NotBlank; + +@Configuration +@Profile("auth") +@ConfigurationProperties(prefix = "oidc-client-registration", ignoreUnknownFields = false) +@Validated +public class CustomClientRegistration { + + @NotBlank + private String authorizationUri; + @NotBlank + private String tokenUri; + @NotBlank + private String userInfoUri; + @NotBlank + private String jwkSetUri; + @NotBlank + private String endSessionEndpoint; + @NotBlank + private String userNameAttribute; + @NotBlank + private String scope; + @NotBlank + private String clientId; + @NotBlank + private String clientSecret; + @NotBlank + private String redirectUri; + + @Bean + public ClientRegistrationRepository clientRegistrationRepository() { + return new InMemoryClientRegistrationRepository(ClientRegistration.withRegistrationId("keycloak") + .authorizationUri(authorizationUri) + .tokenUri(tokenUri) + .userInfoUri(userInfoUri) + .jwkSetUri(jwkSetUri) + .userNameAttributeName(userNameAttribute) + .scope(scope) + .clientId(clientId) + .clientSecret(clientSecret) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .redirectUri(redirectUri) + .providerConfigurationMetadata(Map.of("end_session_endpoint", endSessionEndpoint)) + .build()); + } + + public void setAuthorizationUri(String authorizationUri) { + this.authorizationUri = authorizationUri; + } + + public void setTokenUri(String tokenUri) { + this.tokenUri = tokenUri; + } + + public void setUserInfoUri(String userInfoUri) { + this.userInfoUri = userInfoUri; + } + + public void setJwkSetUri(String jwkSetUri) { + this.jwkSetUri = jwkSetUri; + } + + public void setEndSessionEndpoint(String endSessionEndpoint) { + this.endSessionEndpoint = endSessionEndpoint; + } + + public void setUserNameAttribute(String userNameAttribute) { + this.userNameAttribute = userNameAttribute; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public void setRedirectUri(String redirectUri) { + this.redirectUri = redirectUri; + } + +} diff --git a/reacthookspring/application/src/main/java/de/starwit/application/config/SecurityConfig.java b/reacthookspring/application/src/main/java/de/starwit/application/config/SecurityConfig.java index 3a3811d..154a015 100644 --- a/reacthookspring/application/src/main/java/de/starwit/application/config/SecurityConfig.java +++ b/reacthookspring/application/src/main/java/de/starwit/application/config/SecurityConfig.java @@ -36,7 +36,7 @@ import java.util.function.Supplier; -@Profile("auth") +@Profile({"auth", "auth-dev"}) @Configuration @EnableWebSecurity public class SecurityConfig { @@ -53,7 +53,7 @@ LogoutSuccessHandler oidcLogoutSuccessHandler() { // Sets the location that the End-User's User Agent will be redirected to // after the logout has been performed at the Provider // oidcLogoutSuccessHandler.setPostLogoutRedirectUri(contextPath+"/"); - + oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}"); return oidcLogoutSuccessHandler; } diff --git a/reacthookspring/application/src/main/resources/application-auth-dev.properties b/reacthookspring/application/src/main/resources/application-auth-dev.properties new file mode 100644 index 0000000..baae72f --- /dev/null +++ b/reacthookspring/application/src/main/resources/application-auth-dev.properties @@ -0,0 +1,5 @@ +# Authentication +spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8080/auth/realms/reacthookspring +spring.security.oauth2.client.registration.keycloak.client-id=reacthookspring +spring.security.oauth2.client.registration.keycloak.client-secret=reacthookspring +spring.security.oauth2.client.registration.keycloak.scope=openid \ No newline at end of file diff --git a/reacthookspring/application/src/main/resources/application-auth.properties b/reacthookspring/application/src/main/resources/application-auth.properties index 39e320e..29492ad 100644 --- a/reacthookspring/application/src/main/resources/application-auth.properties +++ b/reacthookspring/application/src/main/resources/application-auth.properties @@ -1,5 +1,12 @@ -# Authentication -spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8080/auth/realms/reacthookspring -spring.security.oauth2.client.registration.keycloak.client-id=reacthookspring -spring.security.oauth2.client.registration.keycloak.client-secret=reacthookspring -spring.security.oauth2.client.registration.keycloak.scope=openid +# Profile "auth" is meant to be used in production setting. This is for reference. + +# oidc-client-registration.authorization-uri=http://localhost:8080/auth/realms/reacthookspring/protocol/openid-connect/auth +# oidc-client-registration.token-uri=http://localhost:8080/auth/realms/reacthookspring/protocol/openid-connect/token +# oidc-client-registration.user-info-uri=http://localhost:8080/auth/realms/reacthookspring/protocol/openid-connect/userinfo +# oidc-client-registration.jwk-set-uri=http://localhost:8080/auth/realms/reacthookspring/protocol/openid-connect/certs +# oidc-client-registration.end-session-endpoint=http://localhost:8080/auth/realms/reacthookspring/protocol/openid-connect/logout +# oidc-client-registration.usernameattribute=preferred_username +# oidc-client-registration.scope=openid +# oidc-client-registration.client-id=reacthookspring +# oidc-client-registration.client-secret=reacthookspring +# oidc-client-registration.redirect-uri={baseUrl}/login/oauth2/code/{registrationId} \ No newline at end of file diff --git a/reacthookspring/application/src/main/resources/application.properties b/reacthookspring/application/src/main/resources/application.properties index 7a80f4c..6f2d67b 100644 --- a/reacthookspring/application/src/main/resources/application.properties +++ b/reacthookspring/application/src/main/resources/application.properties @@ -1,4 +1,4 @@ -spring.profiles.active=auth +spring.profiles.active=auth-dev spring.banner.location=classpath:banner.txt server.servlet.context-path=/reacthookspring rest.base-path=/api diff --git a/reacthookspring/deployment/localenv-docker-compose.yml b/reacthookspring/deployment/auth-docker-compose.yml similarity index 61% rename from reacthookspring/deployment/localenv-docker-compose.yml rename to reacthookspring/deployment/auth-docker-compose.yml index 4a94cb1..78234c5 100644 --- a/reacthookspring/deployment/localenv-docker-compose.yml +++ b/reacthookspring/deployment/auth-docker-compose.yml @@ -1,29 +1,8 @@ version: "3.9" -services: - reacthookspring-db: - image: mariadb:latest - restart: on-failure - environment: - MYSQL_DATABASE: 'reacthookspring' - # So you don't have to use root, but you can if you like - MYSQL_USER: 'reacthookspring' - # You can use whatever password you like - MYSQL_PASSWORD: 'reacthookspring' - # Password for root access - MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' - ports: - # : < MySQL Port running inside container> - - '3306:3306' - healthcheck: - test: ["CMD", "mysql" ,"-h", "localhost", "-P", "3306", "-u", "root", "-e", "select 1", "reacthookspring"] - interval: 5s - timeout: 60s - retries: 30 - volumes: - - reacthookspringv2-db-data:/var/lib/mysql - networks: # Networks to join (Services on the same network can communicate with each other using their name) - - backend +include: + - ./noauth-docker-compose.yml +services: reacthookspring-db-keycloak: image: mariadb:latest restart: on-failure @@ -68,7 +47,6 @@ services: # Names our volume volumes: - reacthookspringv2-db-data: reacthookspring-keycloak-db-data: # Networks to be created to facilitate communication between containers diff --git a/reacthookspring/deployment/noauth-docker-compose.yml b/reacthookspring/deployment/noauth-docker-compose.yml new file mode 100644 index 0000000..fec2b6c --- /dev/null +++ b/reacthookspring/deployment/noauth-docker-compose.yml @@ -0,0 +1,46 @@ +version: "3.9" +services: + reacthookspring-db: + image: mariadb:latest + restart: on-failure + environment: + MYSQL_DATABASE: 'reacthookspring' + # So you don't have to use root, but you can if you like + MYSQL_USER: 'reacthookspring' + # You can use whatever password you like + MYSQL_PASSWORD: 'reacthookspring' + # Password for root access + MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' + ports: + # : < MySQL Port running inside container> + - '3306:3306' + healthcheck: + test: ["CMD", "mysql" ,"-h", "localhost", "-P", "3306", "-u", "root", "-e", "select 1", "reacthookspring"] + interval: 5s + timeout: 60s + retries: 30 + volumes: + - reacthookspringv2-db-data:/var/lib/mysql + networks: # Networks to join (Services on the same network can communicate with each other using their name) + - backend + + pgadmin: + container_name: pgadmin_container + image: dpage/pgadmin4 + environment: + PGADMIN_DEFAULT_EMAIL: pgadmin4@pgadmin.org + PGADMIN_DEFAULT_PASSWORD: admin + PGADMIN_CONFIG_SERVER_MODE: 'False' + volumes: + - reacthookspring-pgadmin:/var/lib/pgadmin + ports: + - "5050:80" + networks: + - backend + +networks: + backend: + +volumes: + reacthookspring-db: + reacthookspring-pgadmin: \ No newline at end of file