Spring Security+JWT简述(附源码)

yizhihongxing

Spring Security是一个强大的安全框架,可以支持高度可定制的身份验证和授权功能。而JWT(JSON Web Token)则是一种轻量级的认证和授权技术,可以在分布式系统中传递和验证用户身份信息。本文将介绍如何结合Spring Security和JWT来实现基于token的身份验证和授权。

1. Spring Security和JWT简介

1.1 Spring Security

Spring Security是一个基于Spring框架的安全框架,提供了全面的身份验证和授权功能。Spring Security可以轻松地与Spring框架集成,提供了一套完整的安全解决方案,可以应用于各种应用场景。

1.2 JWT

JSON Web Token(JWT)是一种轻量级的身份验证和授权技术,可以在分布式系统中传递和验证用户身份信息。JWT由三部分组成:头部(Header)、负载(Payload)和签名(Signature)。头部包含了数据的类型(即JWT),使用的算法等信息;负载包含了要传递的用户信息,例如用户ID、用户名等;签名用来验证数据的完整性,防止数据被篡改。

2. Spring Security和JWT结合实现步骤

2.1 引入依赖

在项目的pom文件中添加如下依赖:

<dependencies>
    <!-- Spring Boot Web Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Security Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <!-- JWT Starter -->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

2.2 实现Spring Security的配置

在配置类中继承WebSecurityConfigurerAdapter,并覆盖configure方法,如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/login").permitAll() // 所有用户均可访问的路径
            .anyRequest().authenticated(); // 除上述路径外,所有请求均需身份验证
    }
}

2.3 实现JWT的创建和验证

2.3.1 创建JWT

public class JwtUtil {
    private static final String SECRET_KEY = "mySecretKey";
    private static final long EXPIRATION_TIME = 3600000; // 1 hour
    private static final String TOKEN_PREFIX = "Bearer ";
    private static final String HEADER_STRING = "Authorization";

    public static String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("sub", userDetails.getUsername());
        claims.put("iat", new Date().getTime());

        return Jwts.builder()
            .setClaims(claims)
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
            .compact();
    }
}

2.3.2 验证JWT

public class JwtUtil {
    ...

    public static boolean validateToken(String token, UserDetails userDetails) {
        String username = extractUsername(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    public static String extractUsername(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
    }

    public static boolean isTokenExpired(String token) {
        Date expiration = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration();
        return expiration.before(new Date());
    }
}

2.4 实现登录接口

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

    @GetMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
            UserDetails userDetails = new User(username, password, new ArrayList<>());
            String jwt = JwtUtil.generateToken(userDetails);
            return jwt;
        } catch (AuthenticationException e) {
            throw new BadCredentialsException("Invalid username/password supplied");
        }
    }
}

2.5 实现需要身份验证的接口

@RestController
@RequestMapping("/api")
public class UserController {
    @GetMapping("/users")
    public List<User> getUsers() {
        return Arrays.asList(
            new User(1L, "Alice"),
            new User(2L, "Bob"),
            new User(3L, "Charlie")
        );
    }

    @GetMapping("/users/{userId}")
    public User getUser(@PathVariable Long userId) {
        return new User(userId, "Alice");
    }
}

以上代码片段中的User类可以自行实现,不再赘述。

2.6 测试

使用Postman或其他Http客户端,访问登录接口,GET请求http://host/api/login,并设置用户名和密码为请求参数。如果身份验证通过,将返回JWT;否则将返回401 Unauthorized。

接下来,访问需要身份验证的接口,例如GET请求http://host/api/users,将JWT添加到请求头Authorization中,格式为“Bearer token”。如果身份验证通过,将返回用户列表;否则将返回401 Unauthorized。

3. 示例

上述步骤已经讲解了如何结合Spring Security和JWT来实现基于token的身份验证和授权。下面将给出另外两个示例来进一步说明其使用方法。

3.1 示例1

本示例实现了一个简单的Spring Boot应用,使用Spring Security和JWT来完成基于token的身份验证和授权。具体代码实现请查看附带源码。

3.2 示例2

本示例实现了一个基于Spring Security和JWT的RESTful API,提供了用户注册、登录和获取用户信息的功能。具体代码实现请查看附带源码。

4. 总结

本文介绍了如何结合Spring Security和JWT来实现基于token的身份验证和授权。首先介绍了Spring Security和JWT的概念和原理,然后详细讲解了如何实现Spring Security和JWT的结合,包括创建和验证JWT、实现登录接口和需要身份验证的接口等。最后,给出了两个示例,供读者参考。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security+JWT简述(附源码) - Python技术站

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

相关文章

  • java 中Spring task定时任务的深入理解

    对于Java中Spring task定时任务的深入理解,我们可以通过以下步骤来进行实现: 1. 添加依赖 首先,我们需要在项目中添加Spring task的相关依赖,该依赖包括: <dependency> <groupId>org.springframework</groupId> <artifactId>sp…

    Java 2023年6月15日
    00
  • JSP中一些JSTL核心标签用法总结

    下面是关于“JSP中一些JSTL核心标签用法总结”的完整攻略: JSP中一些JSTL核心标签用法总结 JSTL是JSP标准标签库,提供了在JSP页面中进行流程控制、条件判断、数据遍历等操作的标签库。JSTL核心标签库是JSTL标签库的核心部分,包含了最基本、使用频率最高的标签。 1.引入JSTL标签库 在使用JSTL标签之前,需要先引入JSTL库,在JSP页…

    Java 2023年6月15日
    00
  • Spring Boot 整合持久层之MyBatis

    Spring Boot 整合持久层之MyBatis 介绍 在Spring Boot中,我们可以通过整合MyBatis,来实现对数据库的访问。本篇文章将会介绍如何使用Spring Boot来整合MyBatis,完成对数据库的访问。 第一步:配置pom.xml文件 在我们的应用中配置MyBatis,需要添加以下依赖: <dependency> &lt…

    Java 2023年5月19日
    00
  • Java中实现String字符串用逗号隔开

    实现Java中用逗号隔开字符串有多种方法,其中最常见的方法是使用String类提供的split()方法来实现。下面将提供两个示例来说明如何使用split()方法实现用逗号隔开字符串的功能。 示例一:使用split()方法 String str = "apple,banana,orange"; String[] strArr = str.s…

    Java 2023年5月26日
    00
  • SpringBoot下Mybatis的缓存的实现步骤

    SpringBoot下Mybatis的缓存实现步骤如下所述: 1. 配置缓存 在 Spring Boot 中,使用 Mybatis 需要先在 pom.xml 文件中引入相关的依赖和插件,然后在 application.yml 或 application.properties 文件中配置Mybatis即可。 在配置的时候,需要在 mybatis-config.…

    Java 2023年5月20日
    00
  • centos 7.5 部署varnish缓存服务器功能

    以下是“centos 7.5 部署varnish缓存服务器功能”的完整攻略。 安装Varnish 步骤1:添加 Varnish 源 在 CentOS7.5 系统上,Varnish 是通过第三方源安装的。因此,第一步是添加 Varnish 源和密钥。 sudo yum install epel-release sudo rpm –nosignature -i…

    Java 2023年6月15日
    00
  • SpringBoot使用JSP作为视图模板的方法

    下面是SpringBoot使用JSP作为视图模板的完整攻略: 1. 新建SpringBoot项目 首先,我们需要新建一个SpringBoot项目。可以通过SpringBoot官网提供的快速构建工具Spring Initializr来完成项目初始化。 2. 配置build.gradle文件 在项目的build.gradle文件中需要添加以下依赖项和插件: de…

    Java 2023年6月15日
    00
  • java怎么创建目录(删除/修改/复制目录及文件)代码实例

    要在Java中创建、删除、修改和复制目录及文件,可以使用Java中自带的File类和方法。下面将在markdown文本中详细讲解此过程。 1. 创建目录 要在Java中创建一个新目录,可以使用如下代码: File dir = new File("path/to/directory"); boolean isCreated = dir.mk…

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