最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringSecurity+JWT簡單集成的實現(xiàn)

 更新時間:2026年04月01日 08:58:38   作者:Zzxy  
本文主要介紹了SpringSecurity+JWT簡單集成的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1、認(rèn)證與授權(quán)

  • 認(rèn)證Authentication):驗證用戶身份
  • 授權(quán)Authorization):允許用戶訪問那些資源,驗證用戶權(quán)限

2、JWT無狀態(tài)認(rèn)證

JWT(JSON Web Token):無狀態(tài)認(rèn)證,是一種緊湊安全的開放標(biāo)準(zhǔn),用于在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明(claims)。

JWT = Header +Payload + Signature

  • Header:頭部,包含令牌類型(通常是 "JWT")和簽名算法(如 HMAC SHA256)。
  • Payload:有效載荷,包含用戶信息和其他元數(shù)據(jù)(如過期時間等)。
  • Signature:簽名部分,用于驗證token的完整性。

服務(wù)端不保存Session,Token包含用戶信息,客戶端每次請求攜帶。

  • Token 通常指的是整個 JWT 字符串,它是由頭部、負(fù)載和簽名組成,經(jīng)過編碼并用點 (.) 分隔開
  • Http請求中:
(授權(quán))Authorization: Bearer <token>

3、Spring Security + JWT 集成

3.1 添加依賴 pom.xml

<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT 相關(guān) -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>

3.2 JWT 相關(guān)配置

JWT 工具類:生成和解析Token

package com.example.utils;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtil {
    @Value("${jwt.secret:mySecretKey12345678901234567890123456789012}")
    private String secret;
    @Value("${jwt.expiration:86400000}")
    private Long expiration;  // 默認(rèn)1天
    private Key getSigningKey() {
        return Keys.hmacShaKeyFor(secret.getBytes()); //生成 HMAC SHA 密鑰
    }
    /**
     * 生成JWT Token
     */
    public String generateToken(Integer userId, String username) {
        Map<String, Object> claims = new HashMap<>();
        //claims映射,存儲用戶信息
        claims.put("userId", userId);
        claims.put("username", username);
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(getSigningKey(), SignatureAlgorithm.HS256)
                .compact();
    }
    /**
     * 從Token中獲取用戶ID
     */
    public Integer getUserIdFromToken(String token) {
        //創(chuàng)建解析器,設(shè)置簽名密鑰,解析token,獲取claims
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token) //解析Token
                .getBody();
        return claims.get("userId", Integer.class);
    }
    /**
     * 從Token中獲取用戶名
     */
    public String getUsernameFromToken(String token) {
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
        return claims.getSubject();
    }
    /**
     驗證Token是否有效
     * 驗證給定的JWT是否有效,通過解析和驗證 Token 的簽名來實現(xiàn)這一點。
     */
    public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder().setSigningKey(getSigningKey()).build().parseClaimsJws(token);
            return true;
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }
}

3.3 Spring Security 相關(guān)配置

自定義UserDetailsService:實現(xiàn)基于數(shù)據(jù)庫的用戶認(rèn)證與授權(quán)。

允許應(yīng)用程序靈活地從任何數(shù)據(jù)源(如數(shù)據(jù)庫)加載用戶信息,并確保在用戶登錄時能夠正確地驗證身份及授權(quán)訪問權(quán)限。

package com.example.security;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 根據(jù)用戶名查詢用戶
        User user = userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                        .eq(User::getUsername, username)
        );
        if (user == null) {
            throw new UsernameNotFoundException("用戶不存在");
        }
        // 返回Spring Security的User對象
        return org.springframework.security.core.userdetails.User
                .withUsername(username)
                .password(user.getPassword())  // 注意:密碼應(yīng)為加密后的
                .authorities(user.getRole())           // 權(quán)限
                .build();
    }
}

3.4 Spring Security + JWT 集成

創(chuàng)建JWT認(rèn)證過濾器(JwtAuthenticationFilter):JWT認(rèn)證通常是通過Authorization header傳遞的,需要自定義過濾器來攔截請求并驗證JWT

package com.example.security;
import com.example.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private CustomUserDetailsService userDetailsService;
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        //從請求中獲取token
        String token = getTokenFromRequest(request);
        if (token != null && jwtUtil.validateToken(token)) {
            //提取用戶名并加載用戶信息
            String username = jwtUtil.getUsernameFromToken(token);
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            //創(chuàng)建認(rèn)證對象并設(shè)置到安全上下文
            //創(chuàng)建認(rèn)證token
            UsernamePasswordAuthenticationToken authentication =
                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            //設(shè)置認(rèn)證詳情
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            //設(shè)置Security上下文        
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(request, response);
    }
    private String getTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}

配置Spring Security:SecurityConfig

  • 認(rèn)證管理器AuthenticationManager:處理認(rèn)證請求,登錄接口使用
  • 安全過濾器鏈SecurityFilterChain:配置請求權(quán)限,CSRF設(shè)置
  • 密碼加密PasswordEncoder:使用Bcrypt加密
package com.example.config;
import com.example.security.CustomUserDetailsService;
import com.example.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Autowired
    private CustomUserDetailsService userDetailsService;
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;
    //安全過濾器鏈
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                //禁用CSRF(跨站請求偽造)保護(hù)
                .csrf().disable()
                //配置為無狀態(tài)會話
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                //配置請求的授權(quán)規(guī)則
                .authorizeRequests()
                .antMatchers("/api/users/login", "/api/users/register").permitAll()
                .antMatchers("/doc.html", "/webjars/**", "/swagger-resources/**", "/v2/api-docs", "/v3/api-docs").permitAll()
                .anyRequest().authenticated() //其他接口需要認(rèn)證
                .and()
                .userDetailsService(userDetailsService) //指定自定義的用戶信息服務(wù)
                //將自定義的 JWT 過濾器添加到 UsernamePasswordAuthenticationFilter 之前
                // 確保在處理用戶名和密碼的認(rèn)證之前先進(jìn)行 JWT 的驗證。
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
    //認(rèn)證管理器AuthenticationManager:負(fù)責(zé)處理身份驗證邏輯
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception{
        return authenticationConfiguration.getAuthenticationManager();
    }
    //密碼加密
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

修改UserServiceImpl,密碼加密

// 在UserServiceImpl中添加
@Autowired
private PasswordEncoder passwordEncoder;
@Override
@Transactional
public boolean register(User user) {
    // 檢查用戶名是否已存在
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(User::getUsername, user.getUsername());
    if (userMapper.selectCount(wrapper) > 0) {
        return false;
    }
    // 密碼加密
    user.setPassword(passwordEncoder.encode(user.getPassword()));
    int rows = userMapper.insert(user);
    return rows > 0;
}

修改控制器controller:處理用戶登錄、注冊等請求并生成JWT

// 在UserController中添加
//Spring Security 認(rèn)證管理器,驗證用戶的憑證(如用戶名和密碼)是否有效
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public Result<Map<String, Object>> login(@RequestBody Map<String, String> loginInfo) {
    String username = loginInfo.get("username");
    String password = loginInfo.get("password");
    // 使用Spring Security進(jìn)行認(rèn)證
    //基于用戶名,密碼的身份認(rèn)證請求
    UsernamePasswordAuthenticationToken authToken = 
            new UsernamePasswordAuthenticationToken(username, password);
    //驗證用戶憑據(jù)
    Authentication authentication = authenticationManager.authenticate(authToken);
    //設(shè)置認(rèn)證上下文
    SecurityContextHolder.getContext().setAuthentication(authentication);
    // 生成JWT令牌
    User user = userService.findByUsername(username); // 需要新增該方法
    String token = jwtUtil.generateToken(user.getId(), username);
    Map<String, Object> data = new HashMap<>();
    data.put("token", token);
    data.put("userId", user.getId());
    data.put("username", user.getUsername());
    return Result.success(data);
}

到此這篇關(guān)于SpringSecurity+JWT簡單集成的實現(xiàn)的文章就介紹到這了,更多相關(guān)SpringSecurity JWT集成內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java微信支付之公眾號支付、掃碼支付實例

    Java微信支付之公眾號支付、掃碼支付實例

    微信支付已經(jīng)成為生活中必不可少的付款方式,本篇文章主要介紹了Java微信支付之公眾號支付、掃碼支付,有需要的小伙伴可以了解一下。
    2016-11-11
  • SpringBoot 集成 Redis實現(xiàn)緩存與分布式鎖的全過程(提升系統(tǒng)性能與并發(fā)能力)

    SpringBoot 集成 Redis實現(xiàn)緩存與分布式鎖的全過程(提升系統(tǒng)性能與并發(fā)能力)

    本文介紹了SpringBoot與Redis的實戰(zhàn)應(yīng)用,涵蓋了環(huán)境搭建、緩存注解使用、手動緩存操作、分布式鎖實現(xiàn)以及常見緩存問題解決方案,通過實際代碼示例,幫助讀者快速掌握Redis的核心應(yīng)用,提升系統(tǒng)性能和并發(fā)處理能力,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Spring時間戳(日期)格式轉(zhuǎn)換方式

    Spring時間戳(日期)格式轉(zhuǎn)換方式

    這篇文章主要介紹了Spring時間戳(日期)格式轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Spring如何通過注解引入外部資源(PropertySource?Value)

    Spring如何通過注解引入外部資源(PropertySource?Value)

    這篇文章主要為大家介紹了Spring通過注解@PropertySource和@Value引入外部資源的方法實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • RestTemplate報錯400 Bad Request的解決方案

    RestTemplate報錯400 Bad Request的解決方案

    在使用Spring Boot時,若直接通過@Autowired注入RestTemplate可能會遇到400BadRequest錯誤,原因在于Spring Boot官方文檔指出,由于RestTemplate實例通常需要在使用前進(jìn)行定制,因此Spring Boot不會自動配置單個RestTemplate Bean
    2024-11-11
  • IDEA生成patch和使用patch的方法實現(xiàn)

    IDEA生成patch和使用patch的方法實現(xiàn)

    比如你本地修復(fù)的 bug,需要把增量文件發(fā)給客戶,很多場景下大家都需要手工整理修改的文件,并整理好目錄,這個很麻煩,那有沒有簡單的技巧呢?本文主要介紹了IDEA生成patch和使用patch的方法實現(xiàn),感興趣的可以了解一下
    2023-08-08
  • Java Kafka 消費積壓監(jiān)控的示例代碼

    Java Kafka 消費積壓監(jiān)控的示例代碼

    這篇文章主要介紹了Java Kafka 消費積壓監(jiān)控,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • java-流的使用完結(jié)與異常處理機(jī)制(詳解)

    java-流的使用完結(jié)與異常處理機(jī)制(詳解)

    下面小編就為大家?guī)硪黄猨ava-流的使用完結(jié)與異常處理機(jī)制(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • .NET Core使用SignalR實現(xiàn)實時通訊的示例代碼

    .NET Core使用SignalR實現(xiàn)實時通訊的示例代碼

    SignalR是一個ASP.NETCore庫,用于在客戶端和服務(wù)器之間實現(xiàn)實時通訊,本文主要介紹了.NETCore中使用SignalR實現(xiàn)實時通訊,感興趣的可以了解一下
    2024-11-11
  • Netty分布式客戶端接入流程初始化源碼分析

    Netty分布式客戶端接入流程初始化源碼分析

    這篇文章主要介紹了Netty分布式客戶端接入流程初始化源碼分析,有關(guān)channelConfig有關(guān)的初始化過程剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-03-03

最新評論

清镇市| 苏州市| 墨竹工卡县| 雷山县| 临湘市| 鲁山县| 明光市| 修武县| 蛟河市| 尚义县| 杭锦后旗| 科尔| 营山县| 茂名市| 抚顺县| 江达县| 潜江市| 利辛县| 阿坝| 天全县| 临沂市| 图木舒克市| 马鞍山市| 卓资县| 望谟县| 灵川县| 碌曲县| 保康县| 贵阳市| 前郭尔| 托克托县| 霍邱县| 沈丘县| 甘洛县| 日土县| 南丰县| 都匀市| 清涧县| 长治市| 绥芬河市| 荔浦县|