SpringSecurity构建登录模块

引入依赖

引入依赖(实现拦截):

java 复制代码
<!--引入springsecurity的依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- JWT相关 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
</dependency>

自定义登录逻辑

实现框架默认的UserDetailsService 自定义登录逻辑:

java 复制代码
@Service
public class MyDetailsService implements UserDetailsService {

    @Resource
    private SysUserMapper sysUserMapper;

    // 自定义认证逻辑
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.构造查询条件
        QueryWrapper<SysUserDO> wrapper = new QueryWrapper<SysUserDO>().eq("user_account", username);
        // 2.查询用户
        SysUserDO user = sysUserMapper.selectOne(wrapper);
        // 3.封装为UserDetails对象
        UserDetails userDetails = User
                .withUsername(user.getUserName())
                .password(user.getUserPassword())
                .authorities("admin")
                .build();
        // 4.返回封装好的UserDetails对象
        return userDetails;
    }
}

配置主配置类

配置主配置类(实现鉴权):

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    MyDetailsService myDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
          return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myDetailsService)
                .passwordEncoder(passwordEncoder());
//        auth.inMemoryAuthentication()
//                .withUser("user").password("{noop}password").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .formLogin()
                .successHandler(new LoginAuthenticationSuccessHandler())
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                //跨站点请求伪造
                .csrf()
                .disable()
                .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
        ;
    }

    /** 拦截器 **/
    @Bean
    public TokenAuthenticationFilter tokenAuthenticationFilter() {
        return new TokenAuthenticationFilter();
    }
}

配置鉴权成功处理类

配置鉴权成功处理类(AuthenticationSuccessHandler)实现返回token:

java 复制代码
@Component
@Slf4j
public class LoginAuthenticationSuccessHandler implements AuthenticationSuccessHandler {


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();

        // 生成 token
        String username = userDetails.getUsername();
        String token = JwtUtil.createJWT(UUID.randomUUID().toString(), userDetails.getUsername(),
                3600L * 1000 * 6);

        // 返回结果
        log.info("==> 用户认证成功, username: {}, token: {}", username, token);

        // 将token存储到HTTP响应头中
        response.setHeader(HttpConstant.X_ACCESS_TOKEN, token);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);

        // 返回响应体
        PrintWriter writer = response.getWriter();

        //构造响应
        Map<String, Object> stringObjectMap = BeanUtil.beanToMap(userDetails);
        stringObjectMap.put("token",token);

        writer.write(new ObjectMapper().writeValueAsString(Result.buildSuccess(stringObjectMap)));
        writer.flush();
        writer.close();
    }
}

配置Filter

配置Filter实现token:

java 复制代码
@Slf4j
public class TokenAuthenticationFilter extends OncePerRequestFilter {

    @Resource
    private MyDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        ObjectMapper objectMapper = new ObjectMapper();
        response.setCharacterEncoding("UTF-8");
        String token = request.getHeader(HttpConstant.X_ACCESS_TOKEN);
        String userName = null;
        if (StringUtils.isNotBlank(token)) {
            try {
                userName = JwtUtil.parseJWT(token).getSubject();
            } catch (Exception e) {
                response.getWriter().write(objectMapper.writeValueAsString(Result.buildError("token校验失败!")));
                return;
            }
            if (StringUtils.isNotBlank(userName)) {
                // && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())

                UserDetails userDetails = null;
                userDetails = userDetailsService.loadUserByUsername(userName);

                // 将用户信息存入 authentication ThreadLocal,方便后续校验
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null,
                        userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                // 用于鉴权
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        // 继续执行下一个过滤器
        filterChain.doFilter(request, response);
    }
}
相关推荐
写点啥呢3 天前
GLM HUD用量实时显示
claude·token·hud·glm
折哥的程序人生 · 物流技术专研4 天前
Java 23 种设计模式:从踩坑到精通 | 组合模式 —— 树形结构处理,部分与整体一视同仁
java·组合模式·java面试·springsecurity·结构型模式·java设计模式·从踩坑到精通
理人综艺好会6 天前
双Token机制在实际项目中的应用与实践
中间件·token
XLYcmy7 天前
一个基于 Python 的轻量级 LLM(大语言模型)API 客户端程序:从API交互到LLM应用架构
服务器·python·ai·llm·prompt·agent·token
小七-七牛开发者9 天前
AI Agent 的 4 个工程关键词:Prompt、Context、Loop、Harness 到底是什么?
ai·大模型·agent·token·context·loop·codex·harness
百度搜知知学社9 天前
抖音双模块架构:兼容全安卓版本并支持登录
android·架构·安卓·登录·兼容性·抖音
ZorChi11 天前
AI API 调用优化实战:统一入口与超时处理指南
人工智能·aigc·接口·api·agent·token·中转站
极连AI13 天前
国产大模型譬如DeepSeek接入codex教程分享
人工智能·gpt·chatgpt·api·token·极连ai·zovelox.com
摸鱼同学16 天前
LLM 是什么?从 API 调用到 Token 机制
ai·大模型·llm·token·claudecode
阿昌喜欢吃黄桃17 天前
大模型常见参数学习笔记
人工智能·ai·llm·prompt·token