簡體   English   中英

JSON Web令牌在Spring Boot中如何工作?

[英]How JSON web token works in Spring boot?

我想編寫REST服務,並且選擇JWT來保護此Rest服務。
我聲明1分鍾的令牌,之后該怎么辦?
我必須刷新令牌或其他內容嗎?

如果必須刷新令牌,用戶可以使用此令牌調用服務的方法嗎?

代幣代碼

package com.example.demo.config;

import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.ArrayList;
import java.util.Arrays;

public class TokenAuthenticationService {

    //field of conf
    static final long EXPIRATIONTIME = 60_000; // 1 min
    static final String SECRET = "msg";
    static final String TOKEN_PREFIX = "Bearer";
    static final String HEADER_STRING = "Authorization";

    //generate token
    public static void addAuthentication(HttpServletResponse res, Authentication auth) {
        String concattedRoles = "";
        for (GrantedAuthority ga : auth.getAuthorities()) {
            if (!"".equals(concattedRoles))
                 concattedRoles += "," + ga.getAuthority();
             else
                 concattedRoles += ga.getAuthority();
        }
        String JWT = Jwts.builder().setSubject(auth.getName()).claim("roles", concattedRoles)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                .signWith(SignatureAlgorithm.HS512, SECRET).compact();
        res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
    }

    //get token from request header.
    public static Authentication getAuthentication(HttpServletRequest request) {
        try {
            System.out.println("(Authentication getAuthentication(HttpServletRequest request)");
            String token = request.getHeader(HEADER_STRING);
            System.out.println("token=>"+token);
            if (token != null) {
                Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody();
                String user = claims.getSubject();
                String roles = (String) claims.get("roles");

                if(claims.getExpiration().before(new Date(System.currentTimeMillis())))
                    throw new Exception(); //Here trow exception.
                List<String> roleList = Arrays.asList(roles.split("\\s*,\\s*"));
                List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
                for (int i = 0; i < roleList.size(); i++) {
                    System.out.println(roleList.get(i));
                    SimpleGrantedAuthority abv = new SimpleGrantedAuthority(roleList.get(i));
                    grantedAuths.add(abv);
                }
                System.out.println(grantedAuths);
                return user != null ? new UsernamePasswordAuthenticationToken(user, null, grantedAuths) : null;
            }
            return null;
        }catch (Exception e){
            System.out.println(e);
            return null;
        }
    }

}

我們的實施方式是-

  1. 首次用戶登錄時,我們向他們發送一個令牌和一個刷新令牌。
  2. 然后,客戶端使用標頭中的“令牌”進行進一步的API調用。
  3. 在客戶端,我們保持15分鍾的倒計時(比主令牌的到期時間短),然后從客戶端向服務器發送帶有令牌和刷新令牌的請求。
  4. 在獲得有效的刷新令牌以及主令牌之后,服務器將以增加的過期時間發送回新令牌。

希望這可以幫助。

基本上, refresh_token用於根據請求將有效的access_token返還給用戶。 而且refresh_tokens通常是長期的,而不是短期的。

就我個人而言,我保護RESTful API的設計只是讓他們每次都向我的端點(即https://api.example.com/oauth/token請求access_token ,我不提供refresh_token因為對我來說這個想法是只是為了讓他們進入資源,別無其他。 通常,請求資源在特定會話中不會停留太長時間。 對於服務器在同一用戶/會話上收到太多請求的其他問題,您可以對服務器或令牌端點實施rate-limiting

我的API安全性實現基於PayPalJHipster 他們沒有為各自的RESTful API實現提供refresh_tokens ,因為最后, refresh_tokens是可選使用的,而這只是在保護RESTful端點時要實現的問題。

有關refresh_token更多信息,您可以通過以下鏈接: 何時使用JWT令牌了解刷新令牌

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM