init
This commit is contained in:
35
backend/gateway/pom.xml
Normal file
35
backend/gateway/pom.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.k12study</groupId>
|
||||
<artifactId>k12study-backend</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>gateway</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.k12study</groupId>
|
||||
<artifactId>common-security</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.k12study.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = {"com.k12study.gateway", "com.k12study.common"})
|
||||
public class GatewayApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GatewayApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.k12study.gateway.filter;
|
||||
|
||||
import com.k12study.common.core.constants.SecurityConstants;
|
||||
import com.k12study.common.security.config.AuthProperties;
|
||||
import com.k12study.common.security.jwt.JwtTokenProvider;
|
||||
import com.k12study.common.security.jwt.JwtUserPrincipal;
|
||||
import java.util.List;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Component
|
||||
public class JwtRelayFilter implements GlobalFilter, Ordered {
|
||||
private final AuthProperties authProperties;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||
|
||||
public JwtRelayFilter(AuthProperties authProperties, JwtTokenProvider jwtTokenProvider) {
|
||||
this.authProperties = authProperties;
|
||||
this.jwtTokenProvider = jwtTokenProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
String path = exchange.getRequest().getURI().getPath();
|
||||
if (!authProperties.isEnabled() || matches(path, authProperties.getWhitelist())) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
String authorization = exchange.getRequest().getHeaders().getFirst(authProperties.getTokenHeader());
|
||||
if (authorization == null || !authorization.startsWith(authProperties.getTokenPrefix())) {
|
||||
return unauthorized(exchange, "Missing token");
|
||||
}
|
||||
|
||||
try {
|
||||
String token = authorization.substring(authProperties.getTokenPrefix().length());
|
||||
JwtUserPrincipal principal = jwtTokenProvider.parse(token);
|
||||
var mutatedRequest = exchange.getRequest().mutate()
|
||||
.header(SecurityConstants.HEADER_USER_ID, principal.userId())
|
||||
.header(SecurityConstants.HEADER_USERNAME, principal.username())
|
||||
.header(SecurityConstants.HEADER_DISPLAY_NAME, principal.displayName())
|
||||
.header(SecurityConstants.HEADER_TENANT_ID, principal.tenantId())
|
||||
.header(SecurityConstants.HEADER_DEPT_ID, principal.deptId())
|
||||
.build();
|
||||
return chain.filter(exchange.mutate().request(mutatedRequest).build());
|
||||
} catch (Exception exception) {
|
||||
return unauthorized(exchange, "Invalid token");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return -100;
|
||||
}
|
||||
|
||||
private boolean matches(String path, List<String> patterns) {
|
||||
return patterns.stream().anyMatch(pattern -> antPathMatcher.match(pattern, path));
|
||||
}
|
||||
|
||||
private Mono<Void> unauthorized(ServerWebExchange exchange, String message) {
|
||||
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
exchange.getResponse().getHeaders().set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
|
||||
byte[] body = ("{\"code\":401,\"message\":\"" + message + "\",\"data\":null}").getBytes();
|
||||
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse()
|
||||
.bufferFactory()
|
||||
.wrap(body)));
|
||||
}
|
||||
}
|
||||
34
backend/gateway/src/main/resources/application.yml
Normal file
34
backend/gateway/src/main/resources/application.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: k12study-gateway
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: auth
|
||||
uri: http://localhost:8081
|
||||
predicates:
|
||||
- Path=/api/auth/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
- id: upms
|
||||
uri: http://localhost:8082
|
||||
predicates:
|
||||
- Path=/api/upms/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info
|
||||
|
||||
auth:
|
||||
enabled: true
|
||||
whitelist:
|
||||
- /api/auth/login
|
||||
- /api/auth/refresh
|
||||
- /actuator/**
|
||||
Reference in New Issue
Block a user