SpringBoot使用token简单鉴权的具体实现方法

一、Token简单鉴权的原理

Token鉴权是一种前后端分离的权限验证方式,具体的原理如下:

  1. 用户登录时请求后端API,后端验证用户名和密码是否正确,如果正确,将返回一个Token给前端。

  2. 前端将Token保存在本地(通常是localStorage或sessionStorage),后续请求时需要将Token附带在请求头中发送给后端。

  3. 后端验证请求头中的Token是否存在、是否正确以及是否过期,如果鉴权通过,将返回请求所需的数据,否则返回401未授权状态码。

二、实现步骤

  1. 引入依赖
    在pom.xml文件中引入以下依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

其中,spring-boot-starter-security是用于Spring Security的基本配置,jjwt是用于生成和验证Token的库。

  1. 配置Spring Security
    在Spring Boot的配置文件application.yml中添加以下配置:
spring:
  security:
    user:
      name: admin
      password: admin
    jwt:
      secret: 123456

其中,security.user.name和security.user.password分别为Spring Security的默认用户名和密码,jwt.secret为Token的签名密钥。

然后在Spring Boot的启动类上添加@EnableWebSecurity注解,并继承WebSecurityConfigurerAdapter类,并重写configure(HttpSecurity http)方法:

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final String[] AUTH_WHITELIST = {
        // -- swagger ui
        "/v2/api-docs",
        "/swagger-resources",
        "/swagger-resources/**",
        "/configuration/ui",
        "/configuration/security",
        "/swagger-ui.html",
        "/webjars/**"
    };

    @Autowired
    private TokenFilter tokenFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers(AUTH_WHITELIST).permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class)
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

该配置将所有请求都要求必须要通过认证后才能访问,同时配置了一个TokenFilter,用于鉴别请求头中的Token的有效性。

  1. 实现Token的生成和验证
    首先在TokenUtils类中实现Token的生成和验证方法:
@Service
public class TokenUtils {

    @Value("${spring.security.jwt.secret}")
    private String secret;

    public String generateToken(String username) {
        Date now = new Date();
        Date expirationDate = new Date(now.getTime() + 1440 * 60 * 1000);

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    public String getUsernameFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(secret).parse(token);
            return true;
        } catch (JwtException e) {
            return false;
        }
    }
}

其中,generateToken方法用于生成Token,getUsernameFromToken方法用于获取Token中的用户名,validateToken方法用于验证Token是否有效。

然后在TokenFilter类中实现Token的验证逻辑:

public class TokenFilter extends OncePerRequestFilter {

    @Autowired
    private TokenUtils tokenUtils;

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

        final String headerToken = request.getHeader("Authorization");
        String token = null;
        String username = null;

        if (headerToken != null && headerToken.startsWith("Bearer ")) {
            // 解析token
            token = headerToken.substring(7);
            username = tokenUtils.getUsernameFromToken(token);

            // 验证token
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtils.validateToken(token)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, null);
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }

        filterChain.doFilter(request, response);
    }
}

该Filter会在所有请求到达后先从请求头中获取Token,然后经过验证后继续请求。Token的验证通过UsernamePasswordAuthenticationToken进行。将其存储到安全上下文中,保证后续的方法在需要用户信息时可以获取并调用。

三、示例

下面通过两个示例来演示如何使用Token简单鉴权:

  1. 登录接口示例
    添加一个登录接口,用于用户登录时获取Token:
@RestController
@RequestMapping("/api")
public class LoginController {

    @Autowired
    private TokenUtils tokenUtils;

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody Map<String, String> loginData) {
        String username = loginData.get("username");
        String password = loginData.get("password");
        if (username.equals("admin") && password.equals("admin")) {
            String token = tokenUtils.generateToken(username);
            return ResponseEntity.ok(token);
        } else {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
    }
}

该接口会根据传入的用户名和密码来判断是否登录成功,如果成功,则通过TokenUtils生成一个Token并返回。否则返回401未授权状态码。

  1. 示例接口
    在Spring Boot的Controller类中添加示例接口,用于测试Token的验证:
@RestController
@RequestMapping("/api")
public class TestController {

    @GetMapping("/test")
    public ResponseEntity<String> test() {
        return ResponseEntity.ok("Hello World!");
    }
}

该接口需要Token鉴权,如果请求头中不存在或无效的Token,将返回401未授权状态码。

那么当用户请求/api/test接口时,其请求头中应该包含有效的Token信息,否则无法通过鉴权,获取数据,该接口配置如下:

@RestController
@RequestMapping("/api")
public class TestController {

    @GetMapping("/test")
    public ResponseEntity<String> test() {
        return ResponseEntity.ok("Hello World!");
    }
}

这两个示例即可完整演示使用Token简单鉴权的实现方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot使用token简单鉴权的具体实现方法 - Python技术站

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

相关文章

  • Maven pom.xml 添加本地jar包依赖以及打包方法

    下面是Maven pom.xml添加本地jar包依赖以及打包方法的完整攻略。 1. 添加本地Jar包依赖 1.1 使用systemPath属性添加本地Jar包 在Maven pom.xml文件的dependencies节点下添加如下代码: <dependency> <groupId>local</groupId> <…

    Java 2023年5月19日
    00
  • Docker-利用dockerfile来搭建tomcat服务的方法

    Docker是一种容器化技术,可以使用Dockerfile文件来描述应用程序及其依赖项的构建过程,同时提供了简单且易于复制、移动、并在环境中部署的容器。 以下是搭建Tomcat服务的Dockerfile文件示例: # 基础镜像 FROM openjdk:8-jre-alpine # 设置Tomcat版本 ENV TOMCAT_MAJOR=8 \ TOMCAT…

    Java 2023年6月2日
    00
  • Struts2的配置 struts.xml Action详解

    当我们用Struts2来开发Web应用程序时,需要进行相关的配置,其中最主要的配置文件就是struts.xml。在这个文件中,我们需要配置Action以及对应的Result、Interceptor等等。 下面是struts.xml的一个简单示例: <?xml version="1.0" encoding="UTF-8&qu…

    Java 2023年5月20日
    00
  • Spring框架初始化解析

    Spring框架初始化解析 Spring框架是由Java编写的一个轻量级的开源框架,主要用于开发企业级应用程序。Spring框架核心是IoC(控制反转)和AOP(面向切面编程)。在使用Spring框架之前,需要先对Spring框架的初始化有一定的认识。 Spring框架初始化步骤 Spring框架的初始化步骤如下: 创建BeanFactory对象 解析Bea…

    Java 2023年5月19日
    00
  • Java手写持久层框架的详细代码

    为了写好一个Java手写持久层框架,我们需要掌握以下的知识点: 数据库连接池的使用 反射机制 注解技术 面向接口开发 在手写持久层框架中,我们需要为每一个实体类编写相应的映射文件,这个映射文件一般是编写在XML配置文件中。在配置文件中,我们需要指定实体类对应的数据库表名、各个属性与数据库表中字段的对应关系等信息。 以下是实现手写持久层框架的常用步骤: 编写核…

    Java 2023年5月20日
    00
  • Java 安全模型,你了解了吗

    Java 安全模型,你了解了吗? Java是一种广泛用于应用程序和互联网的编程语言,其安全模型可确保Java代码执行时的安全性和完整性,从而使Java成为一种极具安全性的编程语言。下面来介绍Java安全模型的完整攻略。 Java安全模型基础 Java安全模型是由Java运行环境提供的一种安全机制,它通过控制Java程序访问资源的方式来保护主机和网络中的资源。…

    Java 2023年5月24日
    00
  • Java使用Calendar类实现动态日历

    下面是关于使用Java中的Calendar类实现动态日历的攻略。 1. Calendar类简介 Calendar类是Java中的日期时间操作类,可以获取时间、修改时间、处理时间等操作。Calendar类位于java.util包中,用来处理日期和时间信息。它提供了与系统独立的方式操作日期和时间。您可以将Calendar的实例看作是一个时钟,它不仅知道当前的时间…

    Java 2023年5月20日
    00
  • Java操作Excel的示例详解

    Java操作Excel的示例详解 在 Java 工程中,对 Excel 进行操作是一个比较常见的需求。下面将会详细讲解如何使用 Java 操作 Excel 文档。 前置条件 在开始操作 Excel 文件前,需要先将相应的依赖项添加到 Maven 或 Gradle 项目中: Maven 在 pom.xml 文件中添加以下依赖项: <dependency&…

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