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

1.基本配置
java 复制代码
@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
java 复制代码
@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
java 复制代码
@Component
public class AccessDeniedExceptionHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        //todo  和 AuthenticationExceptionHandler  类似
    }
}
4. UserDetailsImpl
java 复制代码
@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();
    }

}
  1. UserService
java 复制代码
public interface UserService extends IService<User>, UserDetailsService {
    Page<User> getPage(Page<User> page, User user);
}
5. UserServiceImpl
java 复制代码
@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
java 复制代码
@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);
    }
}
相关推荐
hello早上好1 分钟前
JDK 代理原理
java·spring boot·spring
何苏三月1 小时前
SpringCloud系列 - Sentinel 服务保护(四)
spring·spring cloud·sentinel
纳兰青华1 小时前
bean注入的过程中,Property of ‘java.util.ArrayList‘ type cannot be injected by ‘List‘
java·开发语言·spring·list
魔芋红茶2 小时前
spring-initializer
python·学习·spring
zzywxc7873 小时前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
llwszx8 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
麦兜*11 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
CHENWENFEIc15 小时前
SpringBoot论坛系统安全测试实战报告
spring boot·后端·程序人生·spring·系统安全·安全测试
高兴达15 小时前
RPC--Netty客户端实现
java·spring·rpc
要开心吖ZSH18 小时前
《Spring 中上下文传递的那些事儿》Part 4:分布式链路追踪 —— Sleuth + Zipkin 实践
java·分布式·spring