本文将为大家详细讲解如何使用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
是用于从数据库中获取用户信息的认证提供者,JwtAuthenticationFilter
和JwtAuthorizationFilter
是自定义的过滤器,在请求到达之前或响应返回之后实现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用于身份验证的类,AuthenticationRequest
和AuthenticationResponse
是用于登录请求和响应的类。
示例 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技术站