Spring中如何实现同个接口根据用户角色返回不同演示文稿数据
实现方案
核心逻辑说明
不用在请求参数里传递用户身份,直接从Spring Security服务端上下文获取已认证的用户信息,完全不存在前端篡改参数导致越权的风险。
步骤1:调整Controller层代码
使用@AuthenticationPrincipal注解直接注入当前登录的用户对象:
@RestController @RequestMapping("/presentations") // 按你实际的接口根路径调整 public class PresentationController { @GetMapping("/{presentationId}") public PresentationDTO getPresentation(@PathVariable Long presentationId) { return presentationService.getPresentationById(presentationId); } @GetMapping public List<PresentationDTO> getAllPresentations(@AuthenticationPrincipal User currentUser) { return presentationService.getAllPresentations(currentUser); } }
@AuthenticationPrincipal会自动从Spring Security的安全上下文中取出认证通过的用户对象,全程不需要前端传递任何用户相关参数,完全安全。
步骤2:新增Repository查询方法
在Presentation的JPA Repository中新增按用户ID查询的方法:
public interface PresentationRepository extends JpaRepository<Presentation, Long> { List<Presentation> findByUserId(Long userId); }
步骤3:调整Service层业务逻辑
根据当前登录用户的角色返回对应的数据:
@Service public class PresentationServiceImpl implements PresentationService { @Autowired private PresentationRepository presentationRepository; @Override public List<PresentationDTO> getAllPresentations(User currentUser) { List<Presentation> presentations; // 按你实际的Role枚举值调整判断逻辑 if (Role.ADMIN.equals(currentUser.getRole())) { // 管理员返回全量数据 presentations = presentationRepository.findAll(); } else { // 普通用户只返回自己关联的演示文稿 presentations = presentationRepository.findByUserId(currentUser.getId()); } // 保留你原有实体转DTO的逻辑即可 return presentations.stream() .map(this::convertToDTO) .toList(); } // 你原有DTO转换方法 private PresentationDTO convertToDTO(Presentation presentation) { // 原有转换逻辑 } }
步骤4:补充权限配置
确保接口仅允许已认证用户访问,在Spring Security配置类中添加对应规则:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // 对应你的演示文稿接口路径,按实际调整 .requestMatchers("/presentations/**").authenticated() // 其他接口规则保留你原有配置即可 .anyRequest().permitAll() ) // 保留你原有登录方式、csrf等配置 .formLogin(Customizer.withDefaults()); return http.build(); } }
注意事项
- 如果你的Role枚举值带有Spring Security默认的
ROLE_前缀,对应调整角色判断逻辑即可 - 不需要新增额外接口,完全复用原有
GET /presentations路径,不同角色自动返回对应范围的数据
内容的提问来源于stack exchange,提问作者Aleksandar
相关产品推荐
相关产品推荐

