行业知识
SpringBoot3 整合SpringSecurity
2026-11-04 16:15:26
来源:互联网转载
Maven
org.springframework.boot spring-boot-starter-parent 3.2.2 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-security
JwtFilter
package com.system.security;import cn.hutool.core.util.StrUtil;import com.auth0.jwt.interfaces.DecodedJWT;import com.system.common.exception.ServerException;import com.system.common.utlis.jwt.JwtUtils;import com.system.common.utlis.result.Prefix;import jakarta.annotation.Resource;import jakarta.servlet.FilterChain;import jakarta.servlet.ServletException;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter;import java.io.IOException;/** * @author kuaiting */@Componentpublic class JwtFilter extends OncePerRequestFilter { @Resource private JwtUtils jwtUtils; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 实现过滤逻辑 String authorization = request.getHeader(Prefix.TOKEN_KEY); System.out.println(authorization); if (authorization != null && authorization.startsWith(Prefix.TOKEN_BEARER)) { // 验证JWT并设置用户信息到SecurityContextHolder中 DecodedJWT jwt = jwtUtils.resolveToken(authorization); if (jwt != null) { Long uid = jwtUtils.getUid(jwt); SecurityUser details = jwtUtils.getUserDetails(jwt); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(details, null, details.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); request.setAttribute("uid", uid); } } filterChain.doFilter(request, response); } public void validate(HttpServletRequest request) throws ServerException { //请求中传来的验证码 String code = request.getParameter("code"); String sessionCode = request.getSession().getAttribute("session_code").toString(); if (StrUtil.isEmpty(code)) { throw new ServerException("验证码不能为空!"); } if (StrUtil.isEmpty(sessionCode)) { throw new ServerException("验证码已经失效!"); } if (!sessionCode.equalsIgnoreCase(code)) { throw new ServerException("验证码输入错误!"); } }} SecurityConfig
package com.system.security;import com.system.common.utlis.jwt.JwtUtils;import com.system.common.utlis.result.Prefix;import com.system.common.utlis.result.ResData;import com.system.common.utlis.result.ResEnum;import com.system.system.dao.RoleDao;import com.system.system.entity.vo.AuthVO;import jakarta.annotation.Resource;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.SecurityFilterChain;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import java.io.IOException;import java.io.PrintWriter;import java.util.HashSet;import java.util.List;import java.util.Set;/** * @author kuaiting */@Configurationpublic class SecurityConfig { @Resource JwtUtils jwtUtils; @Resource private JwtFilter jwtFilter; @Resource private RoleDao roleDao; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } private final String[] paths = { "/druid/**", "/system/captcha/line", "/druid/login.html/**", "/system/login", "/js/**", "/*/*.json", "/*/*.yml", "/prims/**", "/type/**", "/system/file/**", "/diagram-viewer/**", "/images/**", "/api/login/**", "/api/file/**", "/css/**", "/*/*.ico", "/swagger-resources/**", "/swagger/**", "/swagger-ui/**", "/webjars/**", "/v3/**", "/v2/**", "/doc.html/**" }; @Bean public SecurityFilterChain securityChain(HttpSecurity http) throws Exception { return http.authorizeHttpRequests(conf -> conf.requestMatchers(paths).permitAll() .anyRequest().authenticated()) .formLogin(conf -> conf.loginProcessingUrl("/system/login") .usernameParameter("username") .passwordParameter("password") .successHandler(this::onAuthenticationSuccess) .failureHandler(this::onAuthenticationFailure)) .exceptionHandling(conf -> conf.authenticationEntryPoint(this::noLogin) .accessDeniedHandler(this::noPermission)) .logout(conf -> conf.logoutUrl("/system/logout") .logoutSuccessHandler(this::onLogoutSuccess)) .csrf(AbstractHttpConfigurer::disable) .sessionManagement(conf -> conf.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) .build(); } private void noPermission(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException { response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_FORBIDDEN); PrintWriter writer = response.getWriter(); jsonWriter(writer, ResEnum.FORBIDDEN.getCode(), ResEnum.FORBIDDEN.getMsg()); } public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { SecurityUser user = (SecurityUser) authentication.getPrincipal(); Long uid = user.getId(); Set permissions = new HashSet(); for (GrantedAuthority authority : user.getAuthorities()) { String auth = authority.getAuthority(); permissions.add(auth); } String token = jwtUtils.createToken(user, uid, user.getUsername(),user.getPassword()); AuthVO authVo = new AuthVO(); authVo.setRole(roleDao.getUserRoles(uid)); authVo.setPermission(permissions); authVo.setKey(Prefix.TOKEN_KEY); authVo.setToken(token); authVo.setExpire(jwtUtils.expireTime().getTime()); response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_OK); PrintWriter writer = response.getWriter(); jsonWriter(writer, ResEnum.SUCCESS.getCode(), ResEnum.SUCCESS.getMsg(), authVo); } public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_OK); PrintWriter writer = response.getWriter(); jsonWriter(writer, ResEnum.UNAUTHORIZED.getCode(), exception.getMessage()); } public void noLogin(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_OK); PrintWriter writer = response.getWriter(); jsonWriter(writer, ResEnum.UNAUTHORIZED.getCode(), ResEnum.UNAUTHORIZED.getMsg()); } public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { String authorization = request.getHeader("Authorization"); response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_OK); PrintWriter writer = response.getWriter(); // 登出时,删除redis中的token if (jwtUtils.invalidateToken(authorization)) { jsonWriter(writer, ResEnum.SUCCESS.getCode(), ResEnum.SUCCESS.getMsg()); } else { jsonWriter(writer, ResEnum.FAIL.getCode(), ResEnum.FAIL.getMsg()); } } private void jsonWriter(PrintWriter writer, Integer code, String message) { jsonWriter(writer, code, message, null); } private void jsonWriter(PrintWriter writer, Integer code, String message, Object data) { writer.write(ResData.asJson(code, message, data)); writer.flush(); writer.close(); } private List getRoleIds(Long uid) { return roleDao.getRoleIds(uid); } private List getUserRoles(Long uid) { return roleDao.getUserRoles(uid); } private Set getPermissions(List roleIds) { Set all = new HashSet(); for (Long id : roleIds) { List permissions = getUserPermissions(id); all.addAll(permissions); } return all; } private List getUserPermissions(Long rid) { return roleDao.getPermissions(rid); }} User
package com.system.security;import lombok.Data;import lombok.NoArgsConstructor;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import java.io.Serializable;import java.util.Collection;import java.util.Set;import java.util.stream.Collectors;/** * @author kuaiting */@Data@NoArgsConstructorpublic class SecurityUser implements UserDetails, Serializable { private Long id; private String username; private String password; private Integer status; private Set permissions; private Collection