SpringSecurity 简单使用,实现登录认证,通过过滤器实现自定义异常处理

1.基本配置
@Configuration
@EnableWebSecurity
@Slf4j
public class SecurityConfig {
    //自定义过滤器
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    //登录认证服务
    @Autowired
    private UserDetailsService userDetailsService;
    //自定义权限失败处理
    @Autowired
    private AccessDeniedExceptionHandler accessDeniedExceptionHandler;
    //自定义认证失败处理
    @Autowired
    private AuthenticationExceptionHandler authenticationExceptionHandler;

    //密码加密器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        log.info("执行authenticationManager");
        return authConfig.getAuthenticationManager();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        log.info("filterChain 执行");
         // 基于token,不需要csrf
        http.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 基于token,不需要session
                .authorizeHttpRequests((authz) -> authz
                        .requestMatchers("/auth/user/login",  "/auth/user/regist").permitAll()
                        .requestMatchers(HttpMethod.OPTIONS).permitAll()
                        .anyRequest().authenticated()
                )
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling(exception ->{
                    exception.authenticationEntryPoint(authenticationExceptionHandler)
                    .accessDeniedHandler(accessDeniedExceptionHandler);
                });
        http.csrf(csrf -> csrf.disable());
        return http.build();
    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder());
        return provider;
    }
}
2.AuthenticationExceptionHandler
@Component
public class AuthenticationExceptionHandler implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        CustomAuthenticationException su = (CustomAuthenticationException) authException;
        // 设置响应的字符编码和内容类型
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(new ObjectMapper().writeValueAsString(BaseVo.fail(su.getMessage())));
        writer.flush();
    }
}
3.AccessDeniedExceptionHandler
@Component
public class AccessDeniedExceptionHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        //todo  和 AuthenticationExceptionHandler  类似
    }
}
4. UserDetailsImpl
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDetailsImpl implements UserDetails {

    private User user;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of();
    }

    @Override
    public String getPassword() {
        return user.getPassWord();
    }

    @Override
    public String getUsername() {
        return user.getUserName();
    }

}

4. UserService

public interface UserService extends IService<User>, UserDetailsService {
    Page<User> getPage(Page<User> page, User user);
}
5. UserServiceImpl
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public Page<User> getPage(Page<User> page, User user) {
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
        query.like(ObjectUtil.isNotEmpty(user.getUserName()), User::getUserName, user.getUserName());
        query.like(ObjectUtil.isNotEmpty(user.getEmail()), User::getEmail, user.getEmail());
        query.like(ObjectUtil.isNotEmpty(user.getPhoneNumber()), User::getPhoneNumber, user.getPhoneNumber());
        query.like(ObjectUtil.isNotEmpty(user.getDeptNo()), User::getDeptNo, user.getDeptNo());
        query.eq(ObjectUtil.isNotEmpty(user.getIsActive()), User::getIsActive, user.getIsActive());
        query.orderByDesc(User::getCreateTime);
        return this.page(page, query);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("执行loadUserByUsername方法");
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
        query.eq(User::getUserName, username)
                .or()
                .eq(User::getEmail, username)
                .or()
                .eq(User::getPhoneNumber, username);
        User user = this.getOne(query);
        if(ObjectUtil.isEmpty(user)){
            log.info("不存在该用户");
        }
        return new UserDetailsImpl(user);
    }
}
6. UserController
@RestController
@RequestMapping("/auth/user")
public class UserController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Value("${jwt.expires}")
    private Integer expiresIn;

    @Autowired
    private UserService userService;
    @PostMapping("/regist")
    public Boolean register(@RequestBody UserDto userDto){
        User user = UserConvert.INSTANCE.targetToSource(userDto);
        if(ObjectUtil.isNotEmpty(user)){
            user.setPassWord(passwordEncoder.encode(user.getPassWord()));
        }
        return userService.save(user);
    }
    @PostMapping("/login")
    public UserVo login(@RequestBody UserDto userDto){
        String loginName = userDto.getLoginName();
        Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginName, userDto.getPassWord()));
//        SecurityContext context = SecurityContextHolder.getContext();
//        Authentication authentication = context.getAuthentication();
        UserDetailsImpl userDetail = (UserDetailsImpl) authenticate.getPrincipal();
        UserVo userVo = UserConvert.INSTANCE.sourceToVo(userDetail.getUser());
        Map<String, String> userInfo = new HashMap<>();
        userInfo.put("userName",userVo.getUserName());
        userInfo.put("userId",String.valueOf(userVo.getId()));
        String token = jwtUtil.getToken(userInfo, expiresIn);
        userVo.setToken(token);
        return userVo;
    }

    @PostMapping("/update")
    public Boolean updateUser(@RequestBody UserDto userDto){
        User user = UserConvert.INSTANCE.targetToSource(userDto);
        return userService.saveOrUpdate(user);
    }
    @PostMapping("/detail")
    public UserVo getUser(@RequestParam("id") Long id){
        User user = userService.getById(id);
        return UserConvert.INSTANCE.sourceToVo(user);
    }
    @PostMapping("/page")
    public IPage<UserVo> getUserPage(@RequestBody UserDto userDto){
        User user = UserConvert.INSTANCE.targetToSource(userDto);
        Page<User> page = new Page<>(userDto.getPageNo(), userDto.getPageSize());
        page = userService.getPage(page,user);
        return UserConvert.INSTANCE.sourceToVo(page);
    }
    @PostMapping("/delete")
    public Boolean deleteUser(Long id){
        return userService.removeById(id);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/900411.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CSS3】css开篇基础(4)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

二百七十一、Kettle——ClickHouse增量导入数据清洗记录表

一、目的 在完成错误数据表任务后&#xff0c;需要对每条错误数据的错误字段及其字段值进行分析 Hive中原有SQL语句和ClickHouse现有SQL语句很大不同 二、Hive中原有代码 2.1 表结构 --31、静态排队数据清洗记录表 create table if not exists hurys_db.dwd_data_clean_…

洞察前沿趋势!2024深圳国际金融科技大赛——西丽湖金融科技大学生挑战赛技术公开课指南

在当前信息技术与“互联网”深度融合的背景下&#xff0c;金融行业的转型升级是热门话题&#xff0c;创新与发展成为金融科技主旋律。随着区块链技术、人工智能技术、5G通信技术、大数据技术等前沿科技的飞速发展&#xff0c;它们与金融领域的深度融合&#xff0c;正引领着新型…

uniapp:sqlite最详细教程,小白可直接粘贴复制

新建uniapp项目,需要4个页面, loading 启动页:打开数据库,判断数据表是否存在,表内是否有数据,创建数据表的逻辑。 register 注册页:数据表已存在,但是没有数据,需要进入该页面注册第一条数据 index 首页:展示数据列表内的数据,可修改默认,添加新数据 edit 编辑:编…

linux面试题复习

前言 现在只是初版&#xff0c;很多格式我还没有改好&#xff0c;会慢慢修改订正。 可能用到的网址&#xff1a;在线 EXCEL 到 MARKDOWN 转换器。 参考了很多网上的面试题和外网上的面试题&#xff1a; 参考文档&#xff1a; 程序员的50大Linux面试问题及答案 Top 60 Linux …

机床发那科转profinet IO项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 网关采集发那科机床数据 2 5 用PROFINET IO协议转发数据 5 6 案例总结 7 1 案例说明 设置网关采集发那科机床数据把采集的数据转成profinet IO协议转发给其他系统。 2 VFBOX网关工作原理 VFBOX网关是协议转换网关&a…

【安当产品应用案例100集】024-BYOE及BYOK在IaaS场景中的应用

在云计算环境中&#xff0c;尤其是涉及到敏感数据时&#xff0c;企业用户可能会选择自带加密工具或密钥&#xff08;即BYOE或BYOK&#xff09;&#xff0c;以确保数据在传输和存储过程中的安全性。这种方式可以防止云服务提供商访问或泄露加密数据&#xff0c;增强数据保护。 …

OpenCV视觉分析之目标跟踪(1)计算密集光流的类DISOpticalFlow的介绍

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 这个类实现了 Dense Inverse Search (DIS) 光流算法。更多关于该算法的细节可以在文献 146中找到。该实现包含了三个预设参数集&#xff0c;以提…

基于Java+Springboot+Vue开发的鲜花商城管理系统

项目简介 该项目是基于JavaSpringbootVue开发的鲜花商城管理系统&#xff08;前后端分离&#xff09;&#xff0c;这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能&#xff0c;同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜…

网络服务请求流程简单理解

网络流程&#xff1a; DNS负责将域名解析为IP地址&#xff0c;ALB可以在多个服务实例之间分配流量&#xff0c;APISIX作为API网关处理更细粒度的流量管理&#xff0c;Service在Kubernetes中为Pod提供稳定的访问入口&#xff0c;而Kubernetes则负责整个应用的部署、扩展和运维。…

基于STM32F103的LED闪烁仿真-定时器中断方式

基于STM32F103的LED闪烁仿真 仿真软件&#xff1a; Proteus 8.17 编程软件&#xff1a; Keil 5 定时器简介&#xff1a; 高级控制定时器(TIM1和TIM8)由一个16位的自动装载计数器组成&#xff0c;它由一个可编程的预分频器驱动。 它适合多种用途&#xff0c;包含测量输入信…

FastGPT学习(2)- 本地开发通过Navicat管理MongoDB、PostgreSQL数据库

1. 背景 前期已经完成FastGPT的本地化部署工作&#xff0c;通过Docker启动FastGPT的相关容器即可运行。&#xff08;共6个容器&#xff09; 2.本地化开发 2.1 前置依赖 2.2 源码拉取 git clone gitgithub.com:labring/FastGPT.git2.3 数据库管理 本地化运行的FastGPT使用…

007、链表的回文结构

0、题目描述 链表回文结构 1、法1 一个复杂的问题可以拆解成几个简单的问题&#xff0c;找中间节点和逆置链表&#xff08;翻转链表&#xff09;之前都做过。 class PalindromeList { public://1、找中间节点ListNode* FindMid(ListNode* A){if (A nullptr || A->next …

博客搭建之路:hexo搜索引擎收录

文章目录 hexo搜索引擎收录以百度为例 hexo搜索引擎收录 hexo版本5.0.2 npm版本6.14.7 next版本7.8.0 写博客的目的肯定不是就只有自己能看到&#xff0c;想让更多的人看到就需要可以让搜索引擎来收录对应的文章。hexo支持生成站点地图sitemap 在hexo下的_config.yml中配置站点…

‘perl‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

‘perl’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 明明已经根据教程安装了perl环境,但是在cmd中依赖报该错误,本章教程提供解决办法。 一、激活perl环境 state shell ActiveState-Perl-5.36.0此时输入perl -v 是可以直接输出perl版本号的。 二、找到perl的执…

跨域的几种情况和如何解决跨域问题

在网站开发中&#xff0c;经常会遇到跨域问题&#xff0c;下面总结一下集中常见的跨域问题。 1. 不同域名属于跨域&#xff0c;如&#xff1a;www.a.com 和www.b.com&#xff0c;另外www.a.com 和www.a.com.cn也属于不同域名。 2. 主域名和子域名&#xff08;二级域名、三级域…

192×144像素是几寸照片?如何手机拍照制作

在数字摄影时代&#xff0c;像素是衡量照片质量的重要指标之一。那么&#xff0c;192144像素的照片相当于多少英寸呢&#xff1f;又如何使用手机拍摄并制作这样的照片呢&#xff1f;本文将为您解答。 首先&#xff0c;我们需要了解像素和英寸之间的关系。像素是图像的最小单位&…

分布式篇(分布式事务)(持续更新迭代)

一、事务 1. 什么是事务 2. 事务目的 3. 事务的流程 4. 事务四大特性 原子性&#xff08;Atomicity&#xff09; 一致性&#xff08;Consistency&#xff09; 持久性&#xff08;Durability&#xff09; 隔离性&#xff08;Isolation&#xff09; 5. MySQL VS Oracle …

14款被严重低估的安全红队测试工具推荐,网络攻防|网络安全必看的工具合集推荐!

大家好&#xff0c;我是小强 工具往往可以决定网络安全渗透测试或红队演练活动的成败。虽然Kali中的许多工具都已经过验证且稳定可靠&#xff0c;但并不能适合所有渗透测试场景。对于安全红队而言&#xff0c;需要在不同测试需求下&#xff0c;确保有足够的装备来实现测试目标…

洞见数据未来,StarRocks Summit Asia 2024 即将启幕!

在 AI 时代&#xff0c;我们需要怎样的数据基础软件&#xff1f; 数据量和数据类型的需求飞速上涨&#xff0c;我们不仅需要将历史上各种基础设施中的数据进行分析使用&#xff0c;还要关注性能、灵活性、性价比&#xff0c;以及确保单一可信数据源。这一切构成了当前大数据领…