繁体   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