详解基于JWT的springboot权限验证技术实现

详解基于JWT的springboot权限验证技术实现攻略

前言

本篇攻略将讲解基于JWT身份验证技术实现SpringBoot权限验证的具体流程。JWT(Json Web Token)是一种跨域身份验证方式,它将一些基本的身份信息以Json格式的数据段形式加密成一个字符串,比如在大型网站的前后端分离架构中JWT技术被广泛应用。

JWT的优势

JWT作为一种跨域身份验证方式,有以下几个优势:

  • 纯前端实现
  • 无状态,可扩展
  • 安全性高,不需要暴露密码等敏感信息

JWT实现原理

JWT实现原理如下:

  1. 用户登录时,服务器将用户的标识(用户名或用户ID等信息)加密生成一个Token,并返回给用户。
  2. 用户在随后的请求中都需要携带这个Token。
  3. 服务器通过验证Token来识别用户身份。
  4. 在Token中加入有效期限制,可以使Token在过期前失效,增加了安全性。

实现步骤

以下将介绍具体实现步骤,包括环境搭建、依赖导入、JWT Token加密、权限验证等等。

环境搭建

在本地安装好JDK后,可以使用如下命令初始化一个SpringBoot项目:

$ curl https://start.spring.io/starter.zip \
  -d dependencies=web,devtools \
  -d javaVersion=11 \
  -d type=maven-project \
  -d packaging=jar \
  -o myproject.zip

执行如下命令解压缩myproject.zip包:

$ unzip myproject.zip -d myproject

进入myproject文件夹并打开项目环境,即可开始进行项目开发。

依赖导入

在pom.xml文件中添加如下依赖:

<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt</artifactId>
  <version>0.9.1</version>
</dependency>

JWT Token加密

在该项目中,使用JwtBuilder方法进行Token加密。

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtils {
  private static final String SECRET_KEY = "your-secret-key";

  public static String generateToken(String subject, long ttlMillis) {
    if (ttlMillis <= 0) {
      throw new RuntimeException("expiration time must be greater than 0.");
    }

    long nowMillis = System.currentTimeMillis();
    Date now = new Date(nowMillis);

    byte[] secretKeyBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY)

    JwtBuilder builder = Jwts.builder()
          .setId(UUID.randomUUID().toString())
          .setSubject(subject)
          .setIssuedAt(now)
          .signWith(SignatureAlgorithm.HS256, secretKeyBytes);

    if (ttlMillis > 0) {
      long expMillis = nowMillis + ttlMillis;
      Date exp = new Date(expMillis);
      builder.setExpiration(exp);
    }

    return builder.compact();
  }
}

权限验证

在该示例中使用JwtParser方法进行Token验证。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

public class JwtUtils {
  private static final String SECRET_KEY = "your-secret-key";

  public static Claims parseJwtToken(String token) {
    try {
      byte[] secretKeyBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY)

      Claims claims = Jwts.parser()
          .setSigningKey(secretKeyBytes)
          .parseClaimsJws(token)
          .getBody();

      return claims;
    } catch (Exception e) {
      // handle token validation exception
      return null;
    }
  }
}

以上就是JWT实现SpringBoot权限验证的详细流程。在实现过程中需要注意保证安全性,使用合适秘钥+算法加密,并设置Token有效期限制等。

示例

示例1:使用JWT实现用户登录

在用户登录接口中调用JwtUtils.generateToken方法生成Token,将Token返回给前端。

@PostMapping("/login")
public ResponseEntity<Map<String, String>> login(@RequestBody LoginForm loginForm) {
  // ... user login logic
  String token = JwtUtils.generateToken(subject, ttlMillis);
  Map<String, String> response = new HashMap<>();
  response.put("token", token);
  return ResponseEntity.ok().body(response);
}

示例2:使用JWT实现接口权限控制

使用Spring Security实现接口权限控制,判断请求中的Authorization头部是否包含JWT Token。

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/api/v1/public/**").permitAll()
        .antMatchers("/api/v1/private/**").authenticated()
        .and().addFilterBefore(new JwtTokenFilter(),
            UsernamePasswordAuthenticationFilter.class);
  }
}

JwtTokenFilter继承OncePerRequestFilter并重写doFilterInternal方法进行Token验证和权限控制。

public class JwtTokenFilter extends OncePerRequestFilter {

  @Override
  protected void doFilterInternal(HttpServletRequest request,
      HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    String token = extractToken(request);

    if (StringUtils.isBlank(token)) {
      chain.doFilter(request, response);
      return;
    }

    Claims claims = JwtUtils.parseJwtToken(token);
    if (claims == null) {
      response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
      return;
    }

    List<String> authorities = (List<String>) claims.get("authorities");
    List<SimpleGrantedAuthority> grantedAuthorities = authorities.stream()
        .map(SimpleGrantedAuthority::new)
        .collect(Collectors.toList());

    UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
        claims.getSubject(),
        null,
        grantedAuthorities);

    SecurityContextHolder.getContext().setAuthentication(auth);
    chain.doFilter(request, response);
  }

  private String extractToken(HttpServletRequest request) {
    String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
    if (StringUtils.isBlank(authHeader)) {
      return null;
    }
    return authHeader.replaceFirst("Bearer ", "");
  }
}

以上两个示例展示了如何在SpringBoot项目中使用JWT实现用户登录和接口权限控制。

结语

本篇文章介绍了JWT实现SpringBoot权限验证的详细流程,同时配合实例操作帮助理解,希望能够帮助到大家。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解基于JWT的springboot权限验证技术实现 - Python技术站

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

相关文章

  • JavaSpringBoot报错“NotFoundException”的原因和处理方法

    原因 “Not Found Exception” 错误通常是以下原因引起的: 路径错误:如果您的路径存在问题,则可能会出现此错误。在这种情况下,需要检查您的路径并确保它们正确。 数据库查询问题:如果您的数据库查询存在问题,则可能会出现此错误。在这种情况下,需要检查您的数据库查询并确保它们正确。 代码逻辑问题:如果您的代码逻辑存在问题,则可能会出现此错误。在这…

    Java 2023年5月4日
    00
  • Javaweb实现上传下载文件的多种方法

    Javaweb实现上传下载文件的多种方法攻略 在开发Javaweb应用时,文件的上传和下载是非常常见的需求。本文将介绍Javaweb实现上传下载文件的多种方法,并提供两个代码示例。 上传文件的几种方式 1. 使用Servlet API实现文件上传 使用Servlet API实现文件上传需要使用标准的 javax.servlet 库中配套的 HttpServl…

    Java 2023年5月19日
    00
  • Java 实战范例之员工管理系统的实现

    Java 实战范例之员工管理系统的实现攻略 1. 系统需求分析 1.1. 员工信息管理模块 根据需求分析,该员工管理系统需要提供对员工信息的增、删、改、查、排序等操作,并能够将员工信息保存在文件中。 1.2. 打印报表模块 该系统还需要提供打印报表的功能,可以根据不同的条件查询员工信息并打印报表。 2. 系统设计 2.1. 类的设计 需要设计Employee…

    Java 2023年5月19日
    00
  • 分析jackjson的安全漏洞CVE-2019-14379

    分析Jackjson的安全漏洞CVE-2019-14379可以通过以下几个步骤: 1.了解CVE-2019-14379漏洞的背景和影响 CVE-2019-14379是一个由Jackson-databind 库的反序列化漏洞引发的安全问题。这种漏洞可以让攻击者远程执行任意代码,从而导致服务器遭到攻击、数据丢失或泄露。 2.检查自己的应用程序是否受到漏洞的影响 …

    Java 2023年5月26日
    00
  • Java 文件解压缩实现代码

    以下是“Java 文件解压缩实现代码”的完整攻略。 1. 需求说明 在开发过程中,我们有时需要解压缩一些文件,这时我们可以使用Java提供的ZipInputStream类和ZipEntry类来实现解压缩功能。ZipInputStream和ZipEntry类位于java.util.zip包中。 2. 解压缩文件的步骤 解压缩文件的步骤一般如下: 定义ZipIn…

    Java 2023年5月20日
    00
  • java实现输出文件夹下某个格式的所有文件实例代码

    下面是详细的攻略: 1. 获取文件夹下所有文件 为了获取一个文件夹下的所有文件,我们可以使用Java中的File类和递归算法。可以先定义一个方法,传入文件夹的路径,使用该方法时传入希望查找的文件格式。 import java.io.File; public class FileUtil { /** * 获取指定文件夹下某一类型的所有文件 * * @param…

    Java 2023年5月20日
    00
  • .properties文件读取及占位符${…}替换源码解析

    下面我来给出“.properties文件读取及占位符${…}替换源码解析”的完整攻略,并提供两个示例说明。 .properties文件读取 在Java中,我们可以使用java.util.Properties类来解析.properties文件。具体的步骤如下: 使用java.io.FileInputStream类将.properties文件读取到输入流中,…

    Java 2023年5月27日
    00
  • java实现桌球小游戏

    下面开始详细讲解“Java实现桌球小游戏”的完整攻略。 1. 游戏规则 桌球小游戏是一种简单有趣的游戏,玩家需要通过控制球拍反弹球,让球进入对方的球门。本游戏的玩家分为两种,分别是左侧玩家和右侧玩家。玩家通过键盘操作控制自己的球拍,分别使用上下方向键控制球拍的运动方向。当其中一方的球进入对方的球门时,对应方即获得一分,游戏结束时,得分高的一方获胜。 2. 技…

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