String jwt = Jwts.builder() .setClaims(claims) //自定义内容(载荷) .signWith(SignatureAlgorithm.HS256, "wpf") //签名算法 .setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000)) //有效期 .compact();
时间: 2024-02-14 21:26:48 浏览: 379
您的第一个问题是关于JWT的创建和签名。这段代码使用了JJWT库来创建和签名JWT(JSON Web Token)。以下是对代码的解释:
- `Jwts.builder()`: 创建一个JWT构造器。
- `setClaims(claims)`: 设置自定义内容(载荷),`claims`是一个`Map`类型的对象,用于存储自定义的键值对。
- `signWith(SignatureAlgorithm.HS256, "wpf")`: 使用HS256算法和密钥"wpf"对JWT进行签名。HS256是一种常用的对称加密算法,密钥用于验证和生成签名。
- `setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000))`: 设置JWT的有效期为当前时间加上24小时(24*3600*1000毫秒)。
- `compact()`: 生成最终的JWT字符串。
因此,这段代码的作用是创建一个包含自定义内容、使用HS256算法签名、有效期为24小时的JWT,并将其转换为字符串表示形式。
相关问题
Jwts.builder().claim
JWT(JSON Web Tokens)是一种开放标准的安全令牌协议,常用于身份验证和授权。在使用JWTS(Java JWT)库构建JWT时,`.builder()`方法是一个静态工厂方法,它返回一个`JwtBuilder`对象,可以用来构造JWT的各个部分。
`.claim()`方法是`JwtBuilder`的一部分,用于添加声明(claims)到JWT头(header)或有效载荷(payload)。声明是一组键值对,它们包含了关于用户信息、权限或其他应用特定的数据。常见的claim有:
- `sub`: 用户标识(subject)
- `iat`: 签发时间(issued at)
- `exp`: 过期时间(expiration time)
- `aud`: 接受者(audience)
- `scope`: 权限范围
例如,以下代码展示了如何添加一些基本的claim:
```java
String secret = "your-secret-key";
Map<String, Object> claims = new HashMap<>();
claims.put("username", "john.doe");
claims.put("email", "john.doe@example.com");
Jwt签发者 builder = Jwts.builder()
.setClaims(claims)
.setSubject(claims.get("username"))
.signWith(SignatureAlgorithm.HS512, secret);
String jwt = builder.compact();
```
springboot 使用jwt
### 使用JWT在Spring Boot中实现用户认证与授权
#### 添加必要的依赖项
为了使Spring Boot应用程序支持基于JWT的身份验证和授权,在`pom.xml`文件里需添加如下两个主要的Maven依赖:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
```
这些依赖会自动激活Spring Security的相关配置并提供OAuth2以及JWT的支持功能[^2]。
#### 创建安全配置类
定义一个新的Java类用于设置应用的安全策略。此类应继承自`WebSecurityConfigurerAdapter`,并通过重写方法来指定哪些URL路径需要保护、如何处理未授权访问请求等细节。对于JWT而言,通常还需要注册一个过滤器用来解析HTTP头中的令牌信息。
```java
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll() // 允许所有人访问登录接口
.anyRequest().authenticated(); // 所有其他请求都需要经过身份验证
http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
```
此段代码关闭了CSRF防护机制(仅作为示例),允许匿名用户调用特定API端点,并确保其余资源受到保护。同时增加了自定义的`JwtAuthenticationFilter`实例到过滤链之前,以便于拦截每个传入请求并对其中携带的有效载荷执行初步检查[^1]。
#### 设计Token服务组件
创建名为`JwtUtils.java`的服务层对象负责生成及校验JSON Web Tokens (JWTs),这涉及到密钥管理、签名算法的选择等方面的知识。这里给出简化版的方法概览:
```java
@Component
public class JwtUtils {
private static final String SECRET_KEY = "your_secret_key"; // 应该保存在一个更安全的地方
public String generateAccessToken(UserDetails userDetails){
Map<String, Object> claims = new HashMap<>();
return Jwts.builder()
.setClaims(claims)
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis()+1000*60*60))// 设置过期时间为一小时
.signWith(SignatureAlgorithm.HS512,SECRET_KEY.getBytes()).compact();
}
public Boolean validateToken(String token, UserDetails userDetails){
final String username = getUsernameFromToken(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
private String getUsernameFromToken(String token){
Claims claims = getAllClaimsFromToken(token);
return claims.getSubject();
}
private boolean isTokenExpired(String token){
Claims claims = getAllClaimsFromToken(token);
Date expirationDate = claims.getExpiration();
return expirationDate.before(new Date());
}
private Claims getAllClaimsFromToken(String token){
return Jwts.parser().setSigningKey(SECRET_KEY.getBytes()).parseClaimsJws(token).getBody();
}
}
```
上述逻辑实现了基本的功能——通过用户名构建新的token字符串;接收现有token后提取其内部声明数据;判断给定token是否有效期内且对应当前用户的凭证记录一致。
#### 构建认证控制器
最后一步是编写RESTful API供客户端发起登录操作时提交账户名密码组合获取返回的新鲜token。假设存在一个简单的实体模型表示用户表单输入,则可以这样设计相应的处理器函数:
```java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
JwtUtils jwtUtil;
@PostMapping("/login")
public ResponseEntity<?> createAuthToken(@RequestBody LoginDto loginDto){
try{
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword()));
final UserDetails userDetails = userDetailsService.loadUserByUsername(loginDto.getUsername());
final String accessToken = jwtUtil.generateAccessToken(userDetails);
return ResponseEntity.ok(new JwtResponse(accessToken));
}catch(BadCredentialsException e){
throw new BadCredentialsException("Invalid credentials",e);
}
}
}
```
这段程序片段展示了当接收到POST类型的/login请求之后怎样利用内置工具完成实际的身份核对过程,成功则响应包含新产生的access_token的消息体;反之抛出异常告知前端错误原因。
阅读全文