springsecurity基于token的认证方式

下面我将详细讲解一下“Spring Security基于Token的认证方式”的完整攻略。

什么是Token认证方式

Token认证方式,是一种基于令牌(Token)的身份认证方式。在客户端成功登录后,服务端会生成一个Token,这个Token会放到HTTP响应头中或者响应体中返回给客户端,客户端需要在后续的请求中携带该Token才能访问资源。

Token认证的优点

  • 无状态性:在服务端不需要记录用户的状态,避免了Session数据空间的浪费。
  • 有效期管理:能够简单高效地在服务端对Token的有效期进行管理,从而减少了服务端的资源消耗。
  • 部署部署:能够方便、快捷地进行服务端间的数据传输,例如:在分布式系统中。

实现Token认证的步骤

  1. 实现用户登录
  2. 接收登录成功后返回的Token并存储
  3. 根据Token判断用户是否已经登录
  4. 实现Token过期时间
  5. 实现Token注销

实现方式

1.使用Spring Security实现Token认证

在Spring Security中,可以使用UsernamePasswordAuthenticationFilter来拦截登录请求,生成Token并返回给客户端。而在后续请求中,可以使用BearerTokenAuthenticationFilter来对Token进行认证。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Bean(BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers("/api/auth/**").permitAll()
                .antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability").permitAll()
                .antMatchers(HttpMethod.GET, "/api/polls/**").permitAll()
                .anyRequest().authenticated();

        // Add custom JWT security filter
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

}

上面的代码中,我们通过@Bean注解来创建JwtAuthenticationFilter和PasswordEncoder的Bean。在configure(AuthenticationManagerBuilder)方法中设置了我们自定义的UserDetailsService,并使用BCryptPasswordEncoder加密密码。在AuthenticationManager的Bean中使用@Bean(BeanIds.AUTHENTICATION_MANAGER)来覆盖默认的org.springframework.security.authentication.AuthenticationManager

2.使用Spring框架手动实现Token认证

下面是一个手动实现Token认证的示例。其中,我们使用了OncePerRequestFilter来对请求进行过滤,从而在请求被处理前进行认证操作。

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JwtRequestFilter.class);

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;

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

        final String requestTokenHeader = request.getHeader("Authorization");

        String username = null;
        String jwtToken = null;

        // 去掉Bearer
        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                logger.error("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                logger.error("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with Bearer String");
        }

        // 验证Token是否有效
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }
}

在上面的代码中,通过JwtTokenUtil对Token进行操作,如果Token有效,则对请求进行认证。

总结

总的来说,基于Token的认证是一种非常灵活、安全、高效的认证方式,使用Spring Security进行实现非常简单。如果需要手动实现,也不是很困难,需要在Filter中对请求进行拦截和校验即可。需要注意的是,Token的有效期一定要管理好,避免出现安全风险。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springsecurity基于token的认证方式 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java流操作之数据流实例代码

    Java中的流操作可以帮助我们更加高效地处理数据。其中,数据流是一种特殊类型的流,可以用于操作原始数据类型值的流(例如 int,double,long 等)。在这里,我将为大家详细介绍“Java流操作之数据流实例代码”的完整攻略。 数据流简介 数据流是 Java 中用于操作原始数据类型的流。数据流实现了 DataInput 和 DataOutput 接口,可…

    Java 2023年5月23日
    00
  • Spring Security权限管理小结

    Spring Security 权限管理小结 Spring Security 是一个强大的安全框架,提供了许多功能来帮助我们保护应用程序,其中最重要的功能之一是权限管理。在这篇文章中,我们将深入了解 Spring Security 的权限管理机制。 权限管理的概述 在 Spring Security 中,权限管理是通过访问控制列表(Access Contro…

    Java 2023年6月3日
    00
  • Windows+Apache+resin配置

    下面是Windows+Apache+Resin配置的完整攻略。 环境准备 在进行配置前,需要确保以下环境已经准备好: Windows操作系统 JDK Apache Resin 其中,JDK用于运行Java应用程序,Apache为Web服务器,Resin则是用于运行Java Web应用程序的容器。 安装与配置Apache 首先需要下载并安装Apache,具体步…

    Java 2023年6月15日
    00
  • java实现图片上传至本地实例详解

    Java实现图片上传至本地实例详解 在Web开发中,经常会遇到用户需要上传图片的需求。本文将详细讲解Java如何实现图片上传至本地的操作。 基本原理 实现图片上传的基本原理是将客户端上传的二进制数据流保存到服务器端的某个文件夹中,然后将图片的URL返回给客户端,客户端通过URL获取到图片并显示。 实现步骤 创建一个上传文件的表单,设置enctype属性为“m…

    Java 2023年5月19日
    00
  • Lambda表达式的使用及注意事项

    Lambda表达式是Java8新引入的一种语法形式,可以用于简洁地定义匿名函数,常用于对集合进行筛选、映射等操作。下面将详细讲解Lambda表达式的使用及注意事项。 Lambda表达式的语法 Lambda表达式由三部分组成:参数列表、箭头符号和表达式或语句块。其基本格式为: (参数列表) -> {表达式或语句块} 例如,下面是一个Lambda表达式的例…

    Java 2023年5月19日
    00
  • Java入门7(异常处理,list集合)

    异常处理(try-catch) 错误的种类 一般来讲,程序出现错误的时候,大致情况有三种: 语法错误 运行时错误,指的是各程序运行的时候,出现的一些没有想到的问题,比如除数为0,比如数组下标越界等等 逻辑错误,运行结果和与其结果不一致,俗称bug ⭐Java中的异常处理机制主要用于处理运行时错误 异常的定义 ​ 运行时发生的错误,叫做异常,处理这些异常的代码…

    Java 2023年5月8日
    00
  • MyBatis复杂Sql查询实现示例介绍

    下面我来为您详细讲解“MyBatis复杂Sql查询实现示例介绍”的攻略。 一、什么是MyBatis复杂Sql查询? MyBatis是一种基于Java的持久层框架,它的目的主要是简化数据库访问过程,允许用户通过XML或注解的方式来配置SQL语句,使得编写和维护数据库访问相关的代码变得更加容易。MyBatis复杂Sql查询是指在查询数据库时,使用MyBatis框…

    Java 2023年5月19日
    00
  • 排序算法图解之Java归并排序的实现

    我很乐意为您详细讲解“排序算法图解之Java归并排序的实现”的完整攻略。 算法概述 归并排序(Merge Sort)是一种比较常见的排序算法,它采用了分治策略,将要排序的数组分成若干个子问题,先解决子问题,再合并子问题的结果得到最终结果。 具体实现,就是将数组不断地拆分成两个子数组,直到子数组中只有一个元素,然后再将有序的子数组合并成一个大的有序数组。 实现…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部