news 2026/3/17 2:39:48

Spring Security入门:构建安全应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Security入门:构建安全应用

Spring Security入门:构建安全应用

在Java开发领域,Spring Security是实现应用安全的首选框架。深入了解这个强大的安全框架,掌握认证与授权的核心技术。

一、什么是Spring Security?

Spring Security是Spring生态系统中最强大的安全框架,它为Java应用提供全面的安全服务。无论是传统Web应用,还是RESTful API,甚至是微服务架构,Spring Security都能提供可靠的安全保障。

为什么选择Spring Security?

  • 功能全面:涵盖认证、授权、防护等所有安全需求
  • 高度可定制:灵活扩展,满足各种业务场景
  • 社区活跃:Spring官方维护,文档完善
  • 与Spring深度集成:无缝衔接Spring Boot

二、核心概念

2.1 认证 vs 授权

  • 认证:确认"你是谁",如登录验证
  • 授权:确认"你能做什么",如权限控制

2.2 核心组件

三、项目搭建

3.1 添加依赖

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.0</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>

3.2 基础配置类

@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/public/**").permitAll() .anyRequest().authenticated() ) .formLogin(form -> form .loginPage("/login") .defaultSuccessUrl("/home") ); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }

四、认证流程详解

Spring Security的认证流程是一个精心设计的链式处理过程:

  1. 用户提交认证信息:用户名和密码
  2. 创建Authentication对象:封装认证信息
  3. AuthenticationManager验证:委托给Provider
  4. 加载用户详情:通过UserDetailsService
  5. 验证成功:存入SecurityContext

4.1 自定义用户详情服务

@Service public class CustomUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) { User user = userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("用户不存在")); return User.builder() .username(user.getUsername()) .password(user.getPassword()) .roles(user.getRoles().toArray(new String[0])) .build(); } }

4.2 自置认证提供者

@Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Autowired private UserDetailsService userDetailsService; @Autowired private PasswordEncoder passwordEncoder; @Override public Authentication authenticate(Authentication authentication) { String username = authentication.getName(); String password = authentication.getCredentials().toString(); UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (passwordEncoder.matches(password, userDetails.getPassword())) { return new UsernamePasswordAuthenticationToken( username, password, userDetails.getAuthorities() ); } throw new BadCredentialsException("密码错误"); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }

五、授权机制

授权是指确定用户是否有权访问特定资源的过程。Spring Security支持多种授权方式。

5.1 URL级别授权

@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // 公开接口 .requestMatchers("/api/public/**").permitAll() // 管理员专属 .requestMatchers("/api/admin/**").hasRole("ADMIN") // 需要特定权限 .requestMatchers("/api/write/**").hasAuthority("WRITE") // 已认证用户 .anyRequest().authenticated() ); return http.build(); }

5.2 方法级授权

@RestController @RequestMapping("/api") public class ApiController { // 需要USER角色 @GetMapping("/user") @PreAuthorize("hasRole('USER')") public String userEndpoint() { return "用户专属内容"; } // 需要ADMIN角色 @GetMapping("/admin") @PreAuthorize("hasRole('ADMIN')") public String adminEndpoint() { return "管理员专属内容"; } // 复杂表达式 @GetMapping("/secure") @PreAuthorize("hasRole('ADMIN') and #username == authentication.name") public String secureEndpoint(String username) { return "只能访问自己的数据"; } // 返回后过滤 @GetMapping("/data/{id}") @PostAuthorize("returnObject.owner == authentication.name") public Data getData(@PathVariable Long id) { return dataService.findById(id); } }

5.3 自定义权限注解

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @PreAuthorize("hasRole('ADMIN') or hasRole('SUPERVISOR')") public @interface IsAdminOrSupervisor { }

六、JWT令牌认证

JWT(JSON Web Token)是目前最流行的跨域认证解决方案。

6.1 JWT服务类

@Service public class JwtService { @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; public String generateToken(String username, List<String> roles) { Map<String, Object> claims = new HashMap<>(); claims.put("roles", roles); return Jwts.builder() .claims(claims) .subject(username) .issuedAt(new Date()) .expiration(new Date(System.currentTimeMillis() + expiration)) .signWith(getSigningKey()) .compact(); } public String extractUsername(String token) { return extractClaims(token).getSubject(); } public boolean validateToken(String token, String username) { String extractedUsername = extractUsername(token); return extractedUsername.equals(username) && !isTokenExpired(token); } private Claims extractClaims(String token) { return Jwts.parser() .verifyWith(getSigningKey()) .build() .parseSignedClaims(token) .getPayload(); } }

6.2 JWT认证过滤器

@Component public class JwtAuthenticationFilter extends OncePerRequestFilter { @Autowired private JwtService jwtService; @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = extractTokenFromRequest(request); if (token != null && SecurityContextHolder.getContext().getAuthentication() == null) { String username = jwtService.extractUsername(token); if (username != null) { List<String> roles = jwtService.extractRoles(token); UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( username, null, roles.stream() .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) .collect(Collectors.toList()) ); SecurityContextHolder.getContext().setAuthentication(authToken); } } filterChain.doFilter(request, response); } private String extractTokenFromRequest(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); if (bearerToken != null && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; } }

6.3 登录控制器

@RestController @RequestMapping("/api/auth") public class AuthController { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtService jwtService; @PostMapping("/login") public LoginResponse login(@RequestBody LoginRequest request) { Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( request.getUsername(), request.getPassword() ) ); User user = (User) authentication.getPrincipal(); String token = jwtService.generateToken( user.getUsername(), user.getAuthorities().stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.toList()) ); return new LoginResponse(token, user.getUsername()); } }

七、过滤器链机制

Spring Security通过过滤器链处理所有HTTP请求,理解过滤器链的工作原理对定制安全功能至关重要。

7.1 常用过滤器

7.2 自定义过滤器

public class CustomFilter extends OncePerRequestFilter { @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 前置处理 String requestId = UUID.randomUUID().toString(); request.setAttribute("requestId", requestId); // 继续过滤器链 filterChain.doFilter(request, response); // 后置处理 logger.info("Request {} completed", requestId); } } // 注册自定义过滤器 @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) { http.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); }

八、异常处理

@Component public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence( HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json;charset=UTF-8"); ApiResponse<?> apiResponse = ApiResponse.unauthorized("未登录或登录已过期"); response.getWriter().write(new ObjectMapper().writeValueAsString(apiResponse)); } } @Component public class CustomAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle( HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.setContentType("application/json;charset=UTF-8"); ApiResponse<?> apiResponse = ApiResponse.error("权限不足"); response.getWriter().write(new ObjectMapper().writeValueAsString(apiResponse)); } }

九、应用场景

9.1 企业后台系统

典型的RBAC(基于角色的访问控制)场景:

  • 用户表、角色表、权限表
  • 用户-角色、角色-权限多对多关系
  • 支持动态权限配置

9.2 API网关

统一认证授权中心:

  • JWT令牌签发与验证
  • 单点登录支持
  • 第三方登录集成

十、总结

Spring Security是企业级Java应用的安全基石:

  • 核心功能:认证与授权
  • 扩展能力:过滤器链、自定义提供者
  • 现代方案:JWT、OAuth2
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/16 2:56:03

穿搭技巧:让衣品瞬间提升一个档次,时髦又高级

圣罗兰曼哈顿 每个人的审美肯定会有所不同~首先&#xff0c;穿搭最重要的是先让自己满意&#xff0c;要让自己看着都很开心&#xff01;虽然我上学的时候不讲究穿搭&#xff0c;但只要出门玩了我就一定会好好穿搭。 分享一些自己琢磨出来的穿搭小技巧&#xff1a; 1、先确定自己…

作者头像 李华
网站建设 2026/3/5 11:45:35

机箱界的西装暴徒,能打的硬核小钢炮:机械大师C34 Pro装机实测

机箱界的西装暴徒&#xff0c;能打的硬核小钢炮&#xff1a;机械大师C34 Pro装机实测哈喽小伙伴们好&#xff0c;我是Stark-C~话说我分享了那么多的主机电脑机箱&#xff0c;什么海景房、静音侠、模块化、小钢炮……但真正能让我在开箱那一刻就露出“哎哟&#xff0c;这东西有点…

作者头像 李华
网站建设 2026/3/9 15:35:53

深度测评!继续教育必用9个AI论文网站TOP9全解析

深度测评&#xff01;继续教育必用9个AI论文网站TOP9全解析 2026年继续教育AI论文工具测评维度解析 在当前继续教育日益普及的背景下&#xff0c;越来越多的学员需要撰写高质量的学术论文。然而&#xff0c;面对繁重的工作任务与有限的时间&#xff0c;如何高效完成论文写作成为…

作者头像 李华
网站建设 2026/3/15 1:39:37

YOLOv8性能优化实战:CPU推理提速50%的参数详解

YOLOv8性能优化实战&#xff1a;CPU推理提速50%的参数详解 1. 引言&#xff1a;工业级目标检测的性能挑战 在边缘计算和工业视觉场景中&#xff0c;实时性是目标检测系统的核心指标。尽管YOLOv8凭借其高精度与快速推理能力成为主流选择&#xff0c;但在无GPU支持的纯CPU环境下…

作者头像 李华
网站建设 2026/3/13 8:37:24

python自助健身房智能管理系统

目录自助健身房智能管理系统摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;自助健身房智能管理系统摘要 自助健身房智能管理系统通过物联网技术与人工智能算法&#xff0c;实现健身场所…

作者头像 李华
网站建设 2026/3/13 14:11:40

基于大数据的校园网用户行为分析系统的设计与实现_58431u18

目录摘要关键词开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 校园网作为高校信息化建设的重要组成部分&#xff0c;积累了海量用户行为数据。设计并实现基于大数据的校园网用户行为分…

作者头像 李华