feat(security): implement JWT-based authentication and authorization

- Configured JWT token validation filter in security chain
- Added user role mapping with new t_user_role table and UserRole entity
- Implemented custom authentication entry point and access denied handler
- Updated UserDetailService to load user roles from database
- Added @PreAuthorize annotation support for method-level security
- Refactored build scripts to use java-library plugin and proper dependency scope
- Enhanced SQL schema with user role table and improved table comments
- Added global exception handler for AccessDeniedException
- Introduced ResponseCodeEnum constants for unauthorized and forbidden access
- Integrated TokenAuthenticationFilter into Spring Security filter chain
This commit is contained in:
2025-11-29 15:19:35 +08:00
parent de52e2816c
commit 0a126eb520
17 changed files with 339 additions and 28 deletions

View File

@@ -1,15 +1,14 @@
plugins {
java
`java-library`
}
dependencies {
// Spring Security
implementation("org.springframework.boot:spring-boot-starter-security")
// Test
testImplementation("org.springframework.boot:spring-boot-starter-test")
api("org.springframework.boot:spring-boot-starter-security")
implementation(project(":weblog-module-common"))
implementation(project(":weblog-module-jwt"))
api(project(":weblog-module-jwt"))
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
}
}

View File

@@ -1,12 +1,15 @@
package com.hanserwei.admin.config;
import com.hanserwei.jwt.config.JwtAuthenticationSecurityConfig;
import com.hanserwei.jwt.handler.RestAccessDeniedHandler;
import com.hanserwei.jwt.handler.RestAuthenticationEntryPoint;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
@@ -17,11 +20,18 @@ import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig {
@Resource
private JwtAuthenticationSecurityConfig jwtAuthenticationSecurityConfig;
@Resource
private RestAccessDeniedHandler restAccessDeniedHandler;
@Resource
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
@@ -38,7 +48,12 @@ public class WebSecurityConfig {
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
// 5. 应用自定义配置 (核心变化)
// 5. 自定义未登录/权限不足的响应
.exceptionHandling(exception -> exception
.authenticationEntryPoint(restAuthenticationEntryPoint)
.accessDeniedHandler(restAccessDeniedHandler)
)
// 6. 应用自定义配置 (核心变化)
.with(jwtAuthenticationSecurityConfig, Customizer.withDefaults());
return http.build();
}