From 31b54f6aac115fecfb7084360d8a9708589bacd9 Mon Sep 17 00:00:00 2001 From: Tim <135014430+nagisa77@users.noreply.github.com> Date: Mon, 30 Jun 2025 18:59:11 +0800 Subject: [PATCH] Add role-based authorization --- README.md | 2 ++ .../java/com/openisle/config/SecurityConfig.java | 3 ++- .../com/openisle/controller/AdminController.java | 16 ++++++++++++++++ src/main/java/com/openisle/model/Role.java | 6 ++++++ src/main/java/com/openisle/model/User.java | 10 ++++++++++ .../java/com/openisle/service/UserService.java | 2 ++ 6 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/openisle/controller/AdminController.java create mode 100644 src/main/java/com/openisle/model/Role.java diff --git a/README.md b/README.md index 642499050..741fe2d0e 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ OpenIsle 是一个基于 Spring Boot 的社区后端平台示例,提供注册 - **JWT 认证**:登录成功后返回 JWT,后续请求需在 `Authorization` 头中携带 `Bearer` token。 - **邮件通知**:示例通过 Resend API 发送欢迎邮件,可根据需要修改。 - **灵活配置**:数据库地址、账户密码、Resend API Key 等均可通过环境变量或 `application.properties` 配置。 +- **角色权限**:内置 `ADMIN` 和 `USER` 两种角色,`/api/admin/**` 接口仅管理员可访问。 ## 快速开始 @@ -45,6 +46,7 @@ mvn spring-boot:run ``` - `POST /api/auth/login`:登录,返回 `{ "token": "..." }`。 - 其他受保护接口示例:`GET /api/hello`,需在请求头加入 `Authorization: Bearer `。 +- 管理员接口示例:`GET /api/admin/hello`,需要具备 `ADMIN` 角色。 ## 目录结构 diff --git a/src/main/java/com/openisle/config/SecurityConfig.java b/src/main/java/com/openisle/config/SecurityConfig.java index 18df57da8..d6a6f681a 100644 --- a/src/main/java/com/openisle/config/SecurityConfig.java +++ b/src/main/java/com/openisle/config/SecurityConfig.java @@ -43,7 +43,7 @@ public class SecurityConfig { .map(user -> org.springframework.security.core.userdetails.User .withUsername(user.getUsername()) .password(user.getPassword()) - .authorities("USER") + .authorities(user.getRole().name()) .build()) .orElseThrow(() -> new UsernameNotFoundException("User not found")); } @@ -63,6 +63,7 @@ public class SecurityConfig { .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth .requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll() + .requestMatchers("/api/admin/**").hasAuthority("ADMIN") .anyRequest().authenticated() ) .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); diff --git a/src/main/java/com/openisle/controller/AdminController.java b/src/main/java/com/openisle/controller/AdminController.java new file mode 100644 index 000000000..2084ea196 --- /dev/null +++ b/src/main/java/com/openisle/controller/AdminController.java @@ -0,0 +1,16 @@ +package com.openisle.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import java.util.Map; + +/** + * Simple admin demo endpoint. + */ +@RestController +public class AdminController { + @GetMapping("/api/admin/hello") + public Map adminHello() { + return Map.of("message", "Hello, Admin User"); + } +} diff --git a/src/main/java/com/openisle/model/Role.java b/src/main/java/com/openisle/model/Role.java new file mode 100644 index 000000000..b2d24e646 --- /dev/null +++ b/src/main/java/com/openisle/model/Role.java @@ -0,0 +1,6 @@ +package com.openisle.model; + +public enum Role { + ADMIN, + USER +} diff --git a/src/main/java/com/openisle/model/User.java b/src/main/java/com/openisle/model/User.java index ef2997d79..42fbafe70 100644 --- a/src/main/java/com/openisle/model/User.java +++ b/src/main/java/com/openisle/model/User.java @@ -5,6 +5,12 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import com.openisle.model.Role; + +/** + * Simple user entity with basic fields and a role. + */ + @Entity @Getter @Setter @@ -28,4 +34,8 @@ public class User { private boolean verified = false; private String verificationCode; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private Role role = Role.USER; } diff --git a/src/main/java/com/openisle/service/UserService.java b/src/main/java/com/openisle/service/UserService.java index 92ff79db6..c481e0adc 100644 --- a/src/main/java/com/openisle/service/UserService.java +++ b/src/main/java/com/openisle/service/UserService.java @@ -1,6 +1,7 @@ package com.openisle.service; import com.openisle.model.User; +import com.openisle.model.Role; import com.openisle.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -50,6 +51,7 @@ public class UserService { user.setUsername(username); user.setEmail(email); user.setPassword(passwordEncoder.encode(password)); + user.setRole(Role.USER); user.setVerified(false); user.setVerificationCode(genCode()); return userRepository.save(user);