利用Springboot实现Jwt认证的示例代码

本文将为大家详细讲解如何使用Spring Boot实现JWT认证,并提供两个示例说明。请按照下面的步骤操作。

前置条件

在开始之前,您需要了解:

  • Java及其相关技术(Java web开发、Spring Boot框架等);
  • JWT(JSON Web Token)认证方式的基本概念和使用方法。

步骤

1. 添加依赖

请在您的项目中添加Spring Security和JWT相关的依赖项,例如:

<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>

2. 添加JWT配置

application.properties中添加JWT相关配置,例如:

jwt.secret=secret-key
jwt.expiration=86400000

其中jwt.secret是用于创建和解析JWT的密钥,jwt.expiration是JWT过期时间(单位为毫秒)。

3. 创建JWT工具类

创建一个用于创建和解析JWT的工具类JwtUtils,该类的代码如下:

@Component
public class JwtUtils {
    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long expiration;

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

    public String generateToken(Map<String, Object> claims) {
        Date expirationDate = new Date(System.currentTimeMillis() + expiration);
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    public boolean validateToken(String token, UserDetails userDetails) {
        try {
            String username = getClaimsFromToken(token).getSubject();
            return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
        } catch (Exception ex) {
            return false;
        }
    }

    private boolean isTokenExpired(String token) {
        Date expirationDate = getClaimsFromToken(token).getExpiration();
        return expirationDate.before(new Date());
    }
}

其中包括以下方法:

  • getClaimsFromToken:从JWT字符串中获取声明(Claims);
  • generateToken:创建一个新的JWT并添加声明;
  • validateToken:验证JWT是否有效;
  • isTokenExpired:检查JWT是否过期。

4. 实现认证授权

SecurityConfig中配置Spring Security,实现认证授权,例如:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder());
        provider.setUserDetailsService(userDetailsService);
        return provider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(new JwtAuthenticationFilter(authenticationManager(), jwtUtils))
                .addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUtils))
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

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

其中,DaoAuthenticationProvider是用于从数据库中获取用户信息的认证提供者,JwtAuthenticationFilterJwtAuthorizationFilter是自定义的过滤器,在请求到达之前或响应返回之后实现JWT的创建和验证。

示例 1:实现登录逻辑

我们将实现一个简单的登录逻辑,该逻辑将使用JWT身份验证。示例代码如下:

@RestController
@RequestMapping("/api")
public class LoginController {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtils jwtUtils;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody AuthenticationRequest authenticationRequest) {
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        authenticationRequest.getUsername(),
                        authenticationRequest.getPassword()
                )
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);

        Map<String, Object> claims = new HashMap<>();
        claims.put("roles", authentication.getAuthorities());

        String token = jwtUtils.generateToken(claims);

        return ResponseEntity.ok(new AuthenticationResponse(token));
    }
}

其中,AuthenticationManager是Spring Security用于身份验证的类,AuthenticationRequestAuthenticationResponse是用于登录请求和响应的类。

示例 2:实现访问控制

我们将实现一个访问控制的示例,目的是测试JWT是否有效。通过将一个注释添加到UserController上,我们将防止未经身份验证的用户访问它。示例代码如下:

@RestController
@RequestMapping("/api")
public class UserController {
    @GetMapping("/user")
    @PreAuthorize("hasRole('ROLE_USER')")
    public ResponseEntity<String> getUser() {
        return ResponseEntity.ok("Hello, user!");
    }
}

@PreAuthorize("hasRole('ROLE_USER')")注释添加到getUser()方法上,只有带有“ROLE_USER”角色的用户才能访问该API。

总结

本文介绍了如何使用Spring Boot实现JWT认证,并提供了两个示例说明。实现身份验证的重点在于创建和验证JWT,而使用Spring Security可以轻松地将其集成到现有的Web应用程序中。通过学习并应用JWT认证方式,您可以更加安全、高效地维护和管理Web应用程序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:利用Springboot实现Jwt认证的示例代码 - Python技术站

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

相关文章

  • 详解Java5、Java6、Java7的新特性

    详解 Java5、Java6、Java7 的新特性 随着 Java 技术的不断发展,每个新版本都带来了新的特性和改进,从 Java5 到 Java7,Java 技术得到了很多重大的改进和新增功能。本文将详细讲解 Java5、Java6、Java7 的新特性。 Java5 Java5 中引入了很多重要的特性,这些特性极大地改进了 Java 语言和虚拟机的性能和…

    Java 2023年5月26日
    00
  • 什么是Java单元测试?

    Java单元测试是在软件开发中的测试过程,它用于测试程序的单个单元或模块是否能够按照预期工作。这个单元可以是一个方法、一个类、一组类或整个应用程序等。单元测试的目的是帮助开发人员识别和修复软件中的缺陷,以确保软件在生产环境中能够正常运行。 使用攻略 选择测试框架 Java有许多单元测试框架,包括JUnit、TestNG、Spock等。推荐使用最为常用的JUn…

    Java 2023年5月11日
    00
  • JavaWeb的监听器和过滤器你了解吗

    让我来详细讲解一下JavaWeb的监听器和过滤器。 监听器 介绍 在JavaWeb中,监听器是用来监听应用程序中发生的事件的组件。事件可以是请求的到来、属性的改变以及session创建和销毁等。监听器可以在事件发生时执行预先定义好的业务逻辑,从而实现对应用程序的控制。JavaWeb中定义了多种类型的监听器,如ServletContextListener、Ht…

    Java 2023年6月15日
    00
  • JavaMail实现发送超文本(html)格式邮件的方法

    JavaMail是一个用于处理电子邮件的Java API,可发送和接收邮件。要发送HTML格式的邮件,可以按照以下步骤进行: 步骤1: 导入包 import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.P…

    Java 2023年6月15日
    00
  • Springboot启动原理详细讲解

    下面我将为你详细讲解 SpringBoot 启动原理。 SpringBoot 启动原理详细讲解 加载 SpringBoot 依赖 SpringBoot 通过 Maven 或 Gradle 等构建工具来管理依赖,将常用的依赖称为 Starter,Starter 包含了对应模块的依赖和配置。在启动时,SpringBoot 会根据 Maven 或 Gradle 的…

    Java 2023年5月15日
    00
  • JSP跨iframe如何传递参数实现代码

    JSP是一种在服务端生成HTML的技术,它能够在生成HTML前进行一些运算和编写,进而方便动态生成页面。在一些特定场景中,如果我们需要在iframe之间传递参数并改变其显示内容,就需要使用JSP来实现 实现方法 在这里,我们可以使用GET方式传递参数,具体实现步骤如下: 在当前iframe中的a标签中编写一个函数,使其在被点击时触发传参的操作,传递参数的同时…

    Java 2023年6月15日
    00
  • java 字符串池的深入理解

    Java字符串池的深入理解 Java中的字符串池是Java语言的一个重要特性,它允许字符串对象在池中共享,从而减少内存的使用。在本文中,我们将深入理解Java字符串池的概念、原理和使用。 字符串池的概念 字符串池是一种特殊的内存区域,存储着Java中的字符串常量。在Java中,如果两个字符串常量的值相同,它们将指向同一个地址,从而实现了字符串的共享,避免了许…

    Java 2023年5月26日
    00
  • java基于数据库实现全局唯一ID的示例

    以下是“java基于数据库实现全局唯一ID的示例”的完整攻略及两条示例: 一、前置条件 在进行本教程之前,请确保以下条件已经满足: 你已熟悉Java编程语言,并且能够独立编写Java代码; 你已经安装了MySQL数据库,并掌握了基本操作; 你已经安装了Java开发环境和相关依赖库。 二、方案选择 目前常见的实现全局唯一ID的方案有雪花算法、UUID等。本教程…

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