资讯动态

SpringSecurity(BCryptr加密)

发布时间:2026/8/22 10:01:52 来源:尧图企业网站定制
Spring Security 是 Spring 生态的安全框架负责认证你是谁、授权你能干什么、防护csrf、跨域等。【登录】前端传账号密码无token↓UsernamePasswordAuthenticationToken到达 Controller 登录接口组装两参数↓authenticationManager.authenticate()↓UserDetailsService → 查询数据库 → UserDetails拿到加密密码↓Security比对密码↓认证成功手动生成JWT返回前端【后续请求】前端带上JWT token↓Jwt过滤器解析token↓存入SecurityContextHolder↓ SecurityConfig的authenticated校验通过放行接口maven 依赖 dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId version2.7.1/version /dependencySpringSecurity 框架不认识你自己写的 User POJO不知道你的数据库中存的值所以要写一个UserDetails接口的类Security 才能读取用户名密码做校验自定义用户详情public class UserDetailsImpl implements UserDetails { private User user;//导入user对象// 有参构造把user数据库的值拿出来public UserDetailsImpl(User user) { this.user user; } Override//是重写可以让idea在你函数名字写错时报错把user中的值拿出来public String getUsername() { return user.getUsername(); } Override public String getPassword() { return user.getPassword(); } Override public Collection? extends GrantedAuthority getAuthorities() {// 返回空集合避免空指针return Collections.emptyList(); } Override// 账号是否未过期 true没过期可以登录public boolean isAccountNonExpired() { return true; } Override// 账号是否未锁定 true没有被锁可以登录public boolean isAccountNonLocked() { return true; } Override// 凭证(密码)是否未过期 true密码没过期可以登录public boolean isCredentialsNonExpired() { return true; } Override// 账号是否启用 true账号正常可用public boolean isEnabled() { return true; }// 提供方法获取原始用户实体public User getUser() { return user; } }UserDetailsService 实现Security 根据用户名查询用户Service public class UserDetailsServiceImpl implements UserDetailsService { Autowired private UserMapper userMapper;//Mapper是MyBatis 的 Mapper 接口专门操作 user 用户 表。 //Mapper public interface UserMapper extends BaseMapperUser {// BaseMapper是mabit plus里的单表增删改查不用写 SQL //}Override//是maven中自带的唯一抽象方法可以自动在每一次登录时调用如果error会抛专属异常public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { QueryWrapperUser queryWrapper new QueryWrapper(); queryWrapper.eq(username, username); User user userMapper.selectOne(queryWrapper);//根据你传入的queryWrapper查询条件查询出一条记录封装成 User 对象返回。// 按Security规范抛异常 if (user null) { throw new UsernameNotFoundException(用户名不存在); } // 返回自定义的UserDetails实现类 return new UserDetailsImpl(user);//userdetailsimpl中的user就是这个,先UserDetailsService后UserDetailsImpl当时绕晕了0_0}Security 配置类 SecurityConfig注册过滤器告诉 Security把这个过滤器放到过滤链哪个位置执行真正调用执行是每次请求进来时由 Spring Security 过滤器链自动执行。Configuration//标记这是 Spring 配置类项目启动自动加载里面所有 BeanEnableWebSecurity//开启 SpringSecurity 的 Web 安全功能启用整套过滤器链public class SecurityConfig { Autowired private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;//作用每次请求解析 Header 中的 token完成登录鉴权。 // 需要注入自己实现的 UserDetailsServiceUserDetailsServiceImpl Autowired private UserDetailsService userDetailsService; Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder();//指定 BCrypt为加密算法} Bean public AuthenticationManager authenticationManager(PasswordEncoder passwordEncoder) {//定位SpringSecurity 顶层认证核心接口职责是执行认证校验账号密码DaoAuthenticationProvider provider new DaoAuthenticationProvider();//DaoAuthenticationProvider是内置的认证核心类provider.setUserDetailsService(userDetailsService);//作用告诉 DaoAuthenticationProvider去哪里查询用户信息provider.setPasswordEncoder(passwordEncoder);//作用指定密码比对工具return new ProviderManager(provider); } Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 关闭csrf .csrf(AbstractHttpConfigurer::disable) // 无状态不使用session .sessionManagement(session - session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth - auth // 放行登录注册接口 .requestMatchers(/user/account/token/, /user/account/register/).permitAll() // 限制本机访问 .requestMatchers(/pk/start/game/,/pk/receive/bot/move/).hasIpAddress(127.0.0.1) // OPTIONS预检请求放行 .requestMatchers(HttpMethod.OPTIONS).permitAll() // 其余请求必须认证 .anyRequest().authenticated() );// 注册自定义JWT过滤器含义请求进来先解析 JWT如果 token 有效提前完成认证不用走账号密码登录流程http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } }JwtAuthenticationTokenFilterjwt过滤器Component public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {//OncePerRequestFilter 是Spring 提供的基础过滤器保证一次请求只会执行一次 doFilterInternal防止多次执行Autowired private UserMapper userMapper; Override protected void doFilterInternal(HttpServletRequest request, NotNull HttpServletResponse response, NotNull FilterChain filterChain) throws ServletException, IOException {//request请求对象 response响应对象 filterChain过滤器链String token request.getHeader(Authorization);//从请求头 Authorization 获取 tokenif (!StringUtils.hasText(token) || !token.startsWith(Bearer )) { filterChain.doFilter(request, response); return; }判断token 为空或者不是以 Bearer 开头标准 JWT 前缀token token.substring(7); String userid; try { Claims claims JwtUtil.parseJWT(token);//JwtUtil是解析验证token的合法性userid claims.getSubject(); } catch (Exception e) { throw new RuntimeException(e); } User user userMapper.selectById(Integer.parseInt(userid));//selectById 根据主键查询数据库完整 User 对象if (user null) { throw new RuntimeException(用户名未登录); } UserDetailsImpl loginUser new UserDetailsImpl(user); UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(loginUser, null, null); SecurityContextHolder.getContext().setAuthentication(authenticationToken);//把认证对象存入Security 上下文filterChain.doFilter(request, response); } }

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价