This commit is contained in:
2026-04-14 16:27:47 +08:00
commit 4b38a4c952
134 changed files with 7478 additions and 0 deletions

50
backend/auth/pom.xml Normal file
View File

@@ -0,0 +1,50 @@
<?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>auth</artifactId>
<dependencies>
<dependency>
<groupId>com.k12study</groupId>
<artifactId>common-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.k12study</groupId>
<artifactId>common-security</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.k12study</groupId>
<artifactId>common-redis</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.k12study</groupId>
<artifactId>api-auth</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,11 @@
package com.k12study.auth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {"com.k12study.auth", "com.k12study.common"})
public class AuthApplication {
public static void main(String[] args) {
SpringApplication.run(AuthApplication.class, args);
}
}

View File

@@ -0,0 +1,14 @@
package com.k12study.auth.config;
import com.k12study.auth.AuthApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan(
basePackages = "com.k12study.auth",
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AuthApplication.class)
)
public class AuthModuleConfiguration {
}

View File

@@ -0,0 +1,40 @@
package com.k12study.auth.controller;
import com.k12study.api.auth.dto.CurrentUserResponse;
import com.k12study.api.auth.dto.LoginRequest;
import com.k12study.api.auth.dto.TokenResponse;
import com.k12study.auth.service.AuthService;
import com.k12study.common.api.response.ApiResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/auth")
public class AuthController {
private final AuthService authService;
public AuthController(AuthService authService) {
this.authService = authService;
}
@PostMapping("/login")
public ApiResponse<TokenResponse> login(@RequestBody LoginRequest request) {
return ApiResponse.success("登录成功", authService.login(request));
}
@PostMapping("/refresh")
public ApiResponse<TokenResponse> refresh(@RequestParam("refreshToken") String refreshToken) {
return ApiResponse.success("刷新成功", authService.refresh(refreshToken));
}
@GetMapping("/current-user")
public ApiResponse<CurrentUserResponse> currentUser(
@RequestHeader(value = "Authorization", required = false) String authorizationHeader) {
return ApiResponse.success(authService.currentUser(authorizationHeader));
}
}

View File

@@ -0,0 +1,66 @@
package com.k12study.auth.service;
import com.k12study.api.auth.dto.CurrentUserResponse;
import com.k12study.api.auth.dto.LoginRequest;
import com.k12study.api.auth.dto.TokenResponse;
import com.k12study.common.security.context.RequestUserContextHolder;
import com.k12study.common.security.jwt.JwtTokenProvider;
import com.k12study.common.security.jwt.JwtUserPrincipal;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class AuthService {
private final JwtTokenProvider jwtTokenProvider;
public AuthService(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
public TokenResponse login(LoginRequest request) {
String username = request.username() == null || request.username().isBlank() ? "admin" : request.username();
JwtUserPrincipal principal = new JwtUserPrincipal(
"U10001",
username,
"K12Study 管理员",
request.tenantId() == null || request.tenantId().isBlank() ? "SCH-HQ" : request.tenantId(),
"DEPT-HQ-ADMIN"
);
String accessToken = jwtTokenProvider.createAccessToken(principal);
String refreshToken = jwtTokenProvider.createAccessToken(principal);
return new TokenResponse(accessToken, refreshToken, "Bearer", 12 * 60 * 60);
}
public TokenResponse refresh(String refreshToken) {
JwtUserPrincipal principal = jwtTokenProvider.parse(refreshToken);
String accessToken = jwtTokenProvider.createAccessToken(principal);
return new TokenResponse(accessToken, refreshToken, "Bearer", 12 * 60 * 60);
}
public CurrentUserResponse currentUser(String authorizationHeader) {
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
JwtUserPrincipal principal = jwtTokenProvider.parse(authorizationHeader.substring("Bearer ".length()));
return new CurrentUserResponse(
principal.userId(),
principal.username(),
principal.displayName(),
"330000",
"330100",
principal.tenantId(),
principal.deptId(),
List.of("SUPER_ADMIN", "ORG_ADMIN")
);
}
var context = RequestUserContextHolder.get();
return new CurrentUserResponse(
context == null ? "U10001" : context.userId(),
context == null ? "admin" : context.username(),
context == null ? "K12Study 管理员" : context.displayName(),
"330000",
"330100",
context == null ? "SCH-HQ" : context.tenantId(),
context == null ? "DEPT-HQ-ADMIN" : context.deptId(),
List.of("SUPER_ADMIN", "ORG_ADMIN")
);
}
}

View File

@@ -0,0 +1,28 @@
server:
port: 8081
spring:
application:
name: k12study-auth
data:
redis:
host: ${K12STUDY_REDIS_HOST:localhost}
port: ${K12STUDY_REDIS_PORT:6379}
password: ${K12STUDY_REDIS_PASSWORD:}
management:
health:
redis:
enabled: false
endpoints:
web:
exposure:
include: health,info
auth:
enabled: true
gateway-mode: true
whitelist:
- /auth/login
- /auth/refresh
- /actuator/**