日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Spring Security 構建基于 JWT 的登錄認證

作者:DawidZhu 更新時間: 2023-08-13 編程語言

一言以蔽之,JWT 可以攜帶非敏感信息,并具有不可篡改性。可以通過驗證是否被篡改,以及讀取信息內容,完成網絡認證的三個問題:“你是誰”、“你有哪些權限”、“是不是冒充的”。??
為了安全,使用它需要采用 Https 協議,并且一定要小心防止用于加密的密鑰泄露。

采用 JWT 的認證方式下,服務端并不存儲用戶狀態信息,有效期內無法廢棄,有效期到期后,需要重新創建一個新的來替換。?
所以它并不適合做長期狀態保持,不適合需要用戶踢下線的場景,不適合需要頻繁修改用戶信息的場景。因為要解決這些問題,總是需要額外查詢數據庫或者緩存,或者反復加密解密,強扭的瓜不甜,不如直接使用 Session。不過作為服務間的短時效切換,還是非常合適的,就比如 OAuth 之類的。

目標功能點

  • 通過填寫用戶名和密碼登錄。

    • 驗證成功后, 服務端生成 JWT 認證 token, 并返回給客戶端。
    • 驗證失敗后返回錯誤信息。
    • 客戶端在每次請求中攜帶 JWT 來訪問權限內的接口。
  • 每次請求驗證 token 有效性和權限,在無有效 token 時拋出 401 未授權錯誤。
  • 當發現請求帶著的 token 有效期快到了的時候,返回特定狀態碼,重新請求一個新 token。
  • 2.png

    ???????Spring Security是Spring家族中的安全框架,可以用來做用戶驗證和權限管理等。Spring Security是一款重型框架,不過功能十分強大。一般來說,如果項目中需要進行權限管理,具有多個角色和多種權限,我們可以使用Spring Security。SpringSecurity 采用的是責任鏈的設計模式,是一堆過濾器鏈的組合,它有一條很長的過濾器鏈。

準備工作

引入 Maven 依賴

針對這個登錄驗證的實現,需要引入 Spring Security、jackson、java-jwt 三個包。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.12.1</version>
</dependency>
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.12.1</version>
</dependency>

配置 DAO 數據層

要驗證用戶前,自然是先要創建用戶實體對象,以及獲取用戶的服務類。不同的是,這兩個類需要實現 Spring Security 的接口,以便將它們集成到驗證框架中。

User

用戶實體類需要實現 ”UserDetails“ 接口,這個接口要求實現?getUsernamegetPasswordgetAuthorities?三個方法,用以獲取用戶名、密碼和權限。以及?isAccountNonExpired`isAccountNonLockedisCredentialsNonExpiredisEnabled?這四個判斷是否是有效用戶的方法,因為和驗證無關,所以先都返回?true。這里圖方便,用了?lombok

@Data
public class User implements UserDetails {

  private static final long serialVersionUID = 1L;

  private String username;

  private String password;

  private Collection<? extends GrantedAuthority> authorities;

  ...
}

UserService

用戶服務類需要實現 “UserDetailsService” 接口,這個接口非常簡單,只需要實現?loadUserByUsername(String username)?這么一個方法。這里使用了 MyBatis 來連接數據庫獲取用戶信息。

@Service
public class UserService implements UserDetailsService {
  
  @Autowired
  UserMapper userMapper;

  @Override
  @Transactional
  public User loadUserByUsername(String username) {
      return userMapper.getByUsername(username);
  }

  ...
}

創建 JWT 工具類

這個工具類主要負責 token 的生成,驗證,從中取值。

@Component
public class JwtTokenProvider {

  private static final long JWT_EXPIRATION = 5 * 60 * 1000L; // 五分鐘過期

  public static final String TOKEN_PREFIX = "Bearer "; // token 的開頭字符串

  private String jwtSecret = "XXX 密鑰,打死也不能告訴別人";

  ...
}

生成 JWT:從以通過驗證的認證對象中,獲取用戶信息,然后用指定加密方式,以及過期時間生成 token。這里簡單的只加了用戶名這一個信息到 token 中:

public String generateToken(Authentication authentication) {
    User userPrincipal = (User) authentication.getPrincipal(); // 獲取用戶對象
    Date expireDate = new Date(System.currentTimeMillis() + JWT_EXPIRATION); // 設置過期時間
    try {
        Algorithm algorithm = Algorithm.HMAC256(jwtSecret); // 指定加密方式
        return JWT.create().withExpiresAt(expireDate).withClaim("username", userPrincipal.getUsername()) 
                .sign(algorithm); // 簽發 JWT
    } catch (JWTCreationException jwtCreationException) {
        return null;
    }
}

驗證 JWT:指定和簽發相同的加密方式,驗證這個 token 是否是本服務器簽發,是否篡改,或者已過期。

public boolean validateToken(String authToken) {
    try {
        Algorithm algorithm = Algorithm.HMAC256(jwtSecret); // 和簽發保持一致
        JWTVerifier verifier = JWT.require(algorithm).build();
        verifier.verify(authToken);
        return true;
    } catch (JWTVerificationException jwtVerificationException) {
        return false;
    }
}

獲取荷載信息:從 token 的荷載部分里解析用戶名信息,這部分是 md5 編碼的,屬于公開信息。

public String getUsernameFromJWT(String authToken) {
    try {
        DecodedJWT jwt = JWT.decode(authToken);
        return jwt.getClaim("username").asString();
    } catch (JWTDecodeException jwtDecodeException) {
        return null;
    }
}

登錄

登錄部分需要創建三個文件:負責登錄接口處理的攔截器,登陸成功或者失敗的處理類。

LoginFilter

Spring Security 默認自帶表單登錄,負責處理這個登錄驗證過程的過濾器叫“UsernamePasswordAuthenticationFilter”,不過它只支持表單傳值,這里用自定義的類繼承它,使其能夠支持 JSON 傳值,負責登錄驗證接口。

這個攔截器只需要負責從請求中取值即可,驗證工作 Spring Security 會幫我們處理好。

滑動驗證頁面

SpringBoot整合Spring Security + JWT實現用戶認證-阿里云開發者社區?

原文鏈接:https://blog.csdn.net/zdwzzu2006/article/details/131742698

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新