Remove api gateway

This commit is contained in:
Miroslav Vasilev 2024-02-07 14:16:36 +02:00
parent d7c3cbbc69
commit c7750e1662
9 changed files with 0 additions and 359 deletions

View file

@ -1,21 +0,0 @@
PROFILE= production/development
AUTHENTIK_CLIENT_ID= authentik oauth2 client id
AUTHENTIK_CLIENT_SECRET= authentik oauth2 client secret
AUTHENTIK_ISSUER_URL= authentik issuer url ( dev: https://auth.mvvasilev.dev/application/o/personal-finances/ )
AUTHENTIK_BACK_CHANNEL_LOGOUT_URL= authentik back channel logout url ( dev: https://auth.mvvasilev.dev/application/o/personal-finances/end-session/ )
GATEWAY_URI= http://localhost:8080
CORE_API_URI= http://localhost:8081
STATEMENTS_API_URI= http://localhost:8082
WIDGETS_API_URI= http://localhost:8083
FRONTEND_URI= http://localhost:5173
SSL_ENABLED= true if generated an ssl cert ( keytool -genkeypair -alias local -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore local.p12 -validity 3650 )
SSL_KEY_STORE_TYPE= type of key store ( PKCS12 )
SSL_KEY_STORE= where to find the key store ( classpath:keystore/local.p12 if located in main/resources/keystore/local.p12 )
SSL_KEY_STORE_PASSWORD= the password for the key store
SSL_KEY_ALIAS= the key store alias
REDIS_HOST= the address of the redis host
REDIS_PORT= the port of redis ( 6379 by default )

View file

@ -1,37 +0,0 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/

View file

@ -1,7 +0,0 @@
FROM eclipse-temurin:21-jdk-alpine
COPY ./build/libs/pefi-api-gateway-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8081
ENTRYPOINT exec java $JAVA_OPTS -jar /app.jar $ARGS

View file

@ -1,44 +0,0 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'dev.mvvasilev'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '21'
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
ext {
set('springCloudVersion', "2023.0.0")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.session:spring-session-core'
implementation 'org.springframework.session:spring-session-data-redis'
implementation 'io.lettuce:lettuce-core'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}

View file

@ -1 +0,0 @@
rootProject.name = 'pefi-api-gateway'

View file

@ -1,15 +0,0 @@
package dev.mvvasilev.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}

View file

@ -1,133 +0,0 @@
package dev.mvvasilev.gateway;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestCustomizers;
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationEntryPoint;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;
import org.springframework.web.server.WebSession;
import java.time.Duration;
@Configuration
@EnableWebFluxSecurity
@EnableRedisWebSession
public class SecurityConfiguration implements BeanClassLoaderAware {
public static final String IS_LOGGED_IN_COOKIE = "isLoggedIn";
@Value("${spring.security.oauth2.client.provider.authentik.back-channel-logout-url}")
private String backChannelLogoutUrl;
@Value("${server.reactive.session.cookie.max-age}")
private Duration springSessionDuration;
@Value("${server.reactive.session.cookie.path}")
private String springSessionPath;
private ClassLoader loader;
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ServerOAuth2AuthorizationRequestResolver resolver) {
http
.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.authorizeExchange(c -> {
c.pathMatchers("/**").permitAll();
c.pathMatchers("/api/**").authenticated();
})
.oauth2Login(c -> {
c.authenticationSuccessHandler((exchange, auth) -> {
ServerHttpResponse response = exchange.getExchange().getResponse();
response.getCookies().set(
IS_LOGGED_IN_COOKIE,
ResponseCookie.from(IS_LOGGED_IN_COOKIE)
.value("true")
.path(springSessionPath)
.maxAge(springSessionDuration)
.httpOnly(false)
.secure(false)
.build()
);
return new RedirectServerAuthenticationSuccessHandler("/").onAuthenticationSuccess(exchange, auth);
});
c.authorizationRequestResolver(resolver);
})
.logout(c -> {
c.logoutSuccessHandler((ex, a) -> {
ServerHttpResponse response = ex.getExchange().getResponse();
response.setStatusCode(HttpStatus.SEE_OTHER);
response.getHeaders().set("Location", backChannelLogoutUrl);
response.getCookies().remove("JSESSIONID");
response.getCookies().remove("SESSION");
response.getCookies().set(
IS_LOGGED_IN_COOKIE,
ResponseCookie.from(IS_LOGGED_IN_COOKIE)
.value("false")
.path(springSessionPath)
.maxAge(springSessionDuration)
.httpOnly(false)
.secure(false)
.build()
);
return ex.getExchange().getSession().flatMap(WebSession::invalidate);
});
})
.exceptionHandling(e -> e.authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)));
return http.build();
}
@Bean
public ServerOAuth2AuthorizationRequestResolver pkceResolver(ReactiveClientRegistrationRepository repo) {
var resolver = new DefaultServerOAuth2AuthorizationRequestResolver(repo);
resolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());
return resolver;
}
@Bean
public ServerAuthenticationEntryPoint authenticationEntryPoint() {
return new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED);
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer(objectMapper());
}
private ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModules(SecurityJackson2Modules.getModules(this.loader));
return mapper;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.loader = classLoader;
}
}

View file

@ -1,33 +0,0 @@
spring:
cloud:
gateway:
routes:
- id: statements-api
uri: ${STATEMENTS_API_URI}
order: 1
predicates:
- Path=/api/statements/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- TokenRelay=
- id: widgets-api
uri: ${WIDGETS_API_URI}
order: 2
predicates:
- Path=/api/widgets/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- TokenRelay=
- id: core-api
uri: ${CORE_API_URI}
order: 3
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- TokenRelay=
- id: spa
order: 4
uri: ${FRONTEND_URI}
predicates:
- Path=/**

View file

@ -1,68 +0,0 @@
logging:
level:
web: trace
core: trace
spring:
profiles:
active: ${PROFILE}
data:
redis:
host: ${REDIS_HOST}
port: ${REDIS_PORT}
security:
oauth2:
client:
registration:
authentik:
client-id: ${AUTHENTIK_CLIENT_ID}
client-secret: ${AUTHENTIK_CLIENT_SECRET}
redirect-uri: "{baseUrl}/login/oauth2/code/authentik"
provider:
authentik:
back-channel-logout-url: ${AUTHENTIK_BACK_CHANNEL_LOGOUT_URL} # spring doesn't support back-channel logouts by default
issuer-uri: ${AUTHENTIK_ISSUER_URL}
cloud:
gateway:
set-status:
original-status-header-name: Original-Status
routes:
- id: statements-api
uri: ${STATEMENTS_API_URI}
order: 1
predicates:
- Path=/api/statements/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- TokenRelay=
- id: widgets-api
uri: ${WIDGETS_API_URI}
order: 2
predicates:
- Path=/api/widgets/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- TokenRelay=
- id: core-api
uri: ${CORE_API_URI}
order: 3
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- TokenRelay=
server:
ssl:
enabled: ${SSL_ENABLED}
key-store-type: ${SSL_KEY_STORE_TYPE}
key-store: ${SSL_KEY_STORE}
key-store-password: ${SSL_KEY_STORE_PASSWORD}
key-alias: ${SSL_KEY_ALIAS}
reactive:
session:
cookie:
http-only: true
secure: true
same-site: lax
max-age: 30m
path: "/"