詳解SpringBoot如何使用JWT實(shí)現(xiàn)身份認(rèn)證和授權(quán)
JSON Web Token(JWT)是一種用于在網(wǎng)絡(luò)應(yīng)用之間安全傳遞信息的開放標(biāo)準(zhǔn)。它使用了一種緊湊且獨(dú)立于語言的方式在各方之間傳遞信息,通常用于在客戶端和服務(wù)器之間驗(yàn)證用戶身份和授權(quán)訪問資源。本文將介紹如何在Spring Boot中使用JWT實(shí)現(xiàn)身份認(rèn)證和授權(quán)。
什么是JWT
JWT是一個(gè)輕量級(jí)的令牌(token)協(xié)議,它使用JSON對(duì)象作為負(fù)載(payload)來傳遞信息,并使用數(shù)字簽名(digital signature)來驗(yàn)證其真實(shí)性。JWT通常包括以下三個(gè)部分:
- Header(頭部):包含了令牌的類型和使用的簽名算法。
- Payload(負(fù)載):包含了一些聲明(claims),例如用戶ID、過期時(shí)間等。
- Signature(簽名):用于驗(yàn)證令牌的真實(shí)性,確保它未被篡改。
JWT的主要優(yōu)勢(shì)在于它的輕量性、易于使用以及可擴(kuò)展性。它可以在不同的應(yīng)用程序之間安全傳遞信息,無需每次都訪問數(shù)據(jù)庫或使用其他形式的驗(yàn)證。
Spring Boot 中使用JWT的步驟
要在Spring Boot應(yīng)用程序中使用JWT,需要執(zhí)行以下步驟:
步驟1:添加依賴項(xiàng)
首先,您需要在pom.xml文件中添加以下依賴項(xiàng)以使用JWT庫:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
</dependency>步驟2:創(chuàng)建JWT工具類
接下來,您需要?jiǎng)?chuàng)建一個(gè)JWT工具類,用于生成和驗(yàn)證JWT令牌。以下是一個(gè)示例的JWT工具類:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtils {
private final String secret = "your_secret_key";
private final long expirationTime = 86400000; // 1 day in milliseconds
// 生成JWT令牌
public String generateToken(String username) {
Date now = new Date();
Date expirationDate = new Date(now.getTime() + expirationTime);
Map<String, Object> claims = new HashMap<>();
claims.put("sub", username);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
// 從JWT令牌中提取用戶名
public String extractUsername(String token) {
Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
return claims.getSubject();
}
// 驗(yàn)證JWT令牌
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}在上述代碼中,JwtUtils類負(fù)責(zé)生成、解析和驗(yàn)證JWT令牌。
步驟3:創(chuàng)建身份認(rèn)證和授權(quán)邏輯
您需要?jiǎng)?chuàng)建身份認(rèn)證和授權(quán)邏輯以確保只有合法用戶可以訪問受保護(hù)的資源??梢允褂肧pring Security等安全框架來實(shí)現(xiàn)這些功能。以下是一個(gè)示例的Spring Security配置類,用于使用JWT進(jìn)行身份認(rèn)證和授權(quán):
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtRequestFilter jwtRequestFilter;
private final UserDetailsService userDetailsService;
public SecurityConfig(JwtRequestFilter jwtRequestFilter, UserDetailsService userDetailsService) {
this.jwtRequestFilter = jwtRequestFilter;
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/authenticate").permitAll() // 放行認(rèn)證接口
.anyRequest().authenticated() // 所有其他請(qǐng)求需要認(rèn)證
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}在上述代碼中,SecurityConfig類配置了哪些端點(diǎn)需要進(jìn)行身份認(rèn)證,以及如何使用JWT進(jìn)行認(rèn)證。
步驟4:創(chuàng)建認(rèn)證控制器
創(chuàng)建一個(gè)認(rèn)證控制器,它負(fù)責(zé)生成JWT令牌并將其返回給客戶端。以下是一個(gè)示例的認(rèn)證控制器:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;
@RestController
public class AuthController {
private final AuthenticationManager authenticationManager;
private final JwtUtils jwtUtils;
private final UserDetailsService userDetailsService;
@Autowired
public AuthController(AuthenticationManager authenticationManager, JwtUtils jwtUtils, UserDetailsService userDetailsService) {
this.authenticationManager = authenticationManager;
this.jwtUtils = jwtUtils;
this.userDetailsService =
userDetailsService;
}
@PostMapping("/authenticate")
public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthRequest authenticationRequest) throws Exception {
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String jwt = jwtUtils.generateToken(userDetails.getUsername());
return ResponseEntity.ok(new AuthResponse(jwt));
}
private void authenticate(String username, String password) throws Exception {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
} catch (Exception e) {
throw new Exception("Invalid username or password");
}
}
}在上述代碼中,AuthController類包含了生成JWT令牌的邏輯。
步驟5:創(chuàng)建受保護(hù)的資源和授權(quán)邏輯
最后,您可以創(chuàng)建受保護(hù)的資源和相應(yīng)的授權(quán)邏輯。在Spring Security配置中,您可以使用@PreAuthorize注解來限制訪問資源的權(quán)限。以下是一個(gè)示例:
@RestController
public class ResourceController {
@GetMapping("/hello")
@PreAuthorize("hasRole('USER')")
public String helloUser() {
return "Hello, User!";
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String helloAdmin() {
return "Hello, Admin!";
}
}在上述代碼中,@PreAuthorize注解確保只有具有相應(yīng)角色的用戶可以訪問/hello和/admin端點(diǎn)。
測(cè)試JWT認(rèn)證和授權(quán)
現(xiàn)在,您可以測(cè)試JWT認(rèn)證和授權(quán)功能。首先,您可以使用/authenticate端點(diǎn)來獲取JWT令牌,然后將該令牌包含在請(qǐng)求的Authorization頭中,以訪問受保護(hù)的資源。如果令牌有效并且用戶具有所需的權(quán)限,將允許訪問資源。
結(jié)論
JWT是一種強(qiáng)大的工具,可用于實(shí)現(xiàn)身份認(rèn)證和授權(quán)功能。在Spring Boot中使用JWT可以簡(jiǎn)化安全性的實(shí)現(xiàn),使您能夠輕松地保護(hù)應(yīng)用程序的資源。通過遵循本文中的步驟,您可以在Spring Boot應(yīng)用程序中成功使用JWT。
到此這篇關(guān)于詳解SpringBoot如何使用JWT實(shí)現(xiàn)身份認(rèn)證和授權(quán)的文章就介紹到這了,更多相關(guān)SpringBoot JWT身份認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Mybatis-Plus時(shí)的SqlSessionFactory問題及處理
這篇文章主要介紹了使用Mybatis-Plus時(shí)的SqlSessionFactory問題及處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java BigDecimal類的使用和注意事項(xiàng)
這篇文章主要講解Java中BigDecimal類的用法,并簡(jiǎn)單介紹一些注意事項(xiàng),希望能給大家做一個(gè)參考。2016-06-06
Java基礎(chǔ)學(xué)習(xí)之ArrayList類概述與常用方法
這篇文章主要為大家簡(jiǎn)單的介紹Java中ArrayList類的概述、常用方法及存儲(chǔ)字符串并遍歷,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-08-08
Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印
這篇文章主要介紹了Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
使用RestTemplate調(diào)用RESTful?API的代碼示例
在開發(fā)?Web?應(yīng)用程序時(shí),調(diào)用?RESTful?API?是一個(gè)常見的任務(wù),本文將介紹如何使用?RestTemplate?調(diào)用?RESTful?API,并提供示例代碼,感興趣的同學(xué)可以跟著小編一起來看看2023-06-06

