Parcourir la source

# feat: 配置分页插件、开放公开浏览接口并暴露当前用户ID

yangyi il y a 2 mois
Parent
commit
5ed5d189c0

+ 1 - 0
build.gradle.kts

@@ -28,6 +28,7 @@ dependencies {
     implementation("org.springframework.boot:spring-boot-starter-actuator")
     // Source: https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter
     implementation ("com.baomidou:mybatis-plus-spring-boot3-starter:3.5.15")
+    implementation("com.baomidou:mybatis-plus-jsqlparser:3.5.15")
 //    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
     implementation("org.springframework.boot:spring-boot-starter-security")
     implementation("org.springframework.boot:spring-boot-starter-validation")

+ 2 - 0
src/main/java/space/anyi/serve/ServeApplication.java

@@ -2,7 +2,9 @@ package space.anyi.serve;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
+@EnableScheduling
 @SpringBootApplication
 public class ServeApplication {
 

+ 18 - 0
src/main/java/space/anyi/serve/config/MybatisPlusConfig.java

@@ -0,0 +1,18 @@
+package space.anyi.serve.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MybatisPlusConfig {
+
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
+        return interceptor;
+    }
+}

+ 1 - 0
src/main/java/space/anyi/serve/config/SecurityConfig.java

@@ -53,6 +53,7 @@ public class SecurityConfig {
                 .authorizeHttpRequests(authorize -> authorize
                         .requestMatchers("/auth/login", "/auth/register").permitAll()
                         .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-ui.html").permitAll()
+                        .requestMatchers(HttpMethod.GET, "/problem", "/problem/{id}", "/category", "/contest").permitAll()
                         .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                         .anyRequest().authenticated()
                 )

+ 4 - 0
src/main/java/space/anyi/serve/entity/auth/JwtUserPrincipal.java

@@ -0,0 +1,4 @@
+package space.anyi.serve.entity.auth;
+
+public record JwtUserPrincipal(Long userId, String account, String username, String role) {
+}

+ 6 - 1
src/main/java/space/anyi/serve/filter/JwtAuthenticationFilter.java

@@ -11,6 +11,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 import org.springframework.web.filter.OncePerRequestFilter;
+import space.anyi.serve.entity.auth.JwtUserPrincipal;
 import space.anyi.serve.handler.security.JwtTokenProvider;
 
 import java.io.IOException;
@@ -34,12 +35,16 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
         if (StringUtils.hasText(token) && jwtTokenProvider.validateToken(token)) {
             Claims claims = jwtTokenProvider.parseToken(token);
             String account = claims.getSubject();
+            Long userId = claims.get("userId", Long.class);
+            String username = claims.get("username", String.class);
             String role = claims.get("role", String.class);
 
+            JwtUserPrincipal principal = new JwtUserPrincipal(userId, account, username, role);
+
             List<SimpleGrantedAuthority> authorities = List.of(new SimpleGrantedAuthority("ROLE_" + role));
 
             UsernamePasswordAuthenticationToken authentication =
-                    new UsernamePasswordAuthenticationToken(account, null, authorities);
+                    new UsernamePasswordAuthenticationToken(principal, null, authorities);
             SecurityContextHolder.getContext().setAuthentication(authentication);
         }
 

+ 42 - 0
src/main/java/space/anyi/serve/util/SecurityUtils.java

@@ -0,0 +1,42 @@
+package space.anyi.serve.util;
+
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import space.anyi.serve.entity.auth.JwtUserPrincipal;
+
+public final class SecurityUtils {
+
+    private SecurityUtils() {
+    }
+
+    public static boolean isAnonymous() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication == null || !authentication.isAuthenticated()) {
+            return true;
+        }
+        return authentication instanceof AnonymousAuthenticationToken;
+    }
+
+    public static Long getCurrentUserId() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication == null || authentication.getPrincipal() == null) {
+            return null;
+        }
+        if (authentication.getPrincipal() instanceof JwtUserPrincipal principal) {
+            return principal.userId();
+        }
+        return null;
+    }
+
+    public static String getCurrentRole() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication == null || authentication.getPrincipal() == null) {
+            return null;
+        }
+        if (authentication.getPrincipal() instanceof JwtUserPrincipal principal) {
+            return principal.role();
+        }
+        return null;
+    }
+}