【发布时间】:2018-06-14 09:55:18
【问题描述】:
我想编写 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;
}
}
}
【问题讨论】:
-
也许尝试在每次请求后刷新用户的当前令牌并将其发回?
-
如果我刷新用户的当前令牌,为什么我必须发送回?用户可以继续使用第一个令牌调用我的服务吗?如果是,用户将如何获得新令牌?
-
好吧,我知道这如何与标头一起使用,但与 cookie 一起使用时效果很好。当用户提出请求时,您检查他的 JWT-cookie。如果没问题,在请求之后你只需放置另一个同名的 JWT cookie,但修改了过期时间。结果,用户将在其 cookie 中更新 JWT。
-
用户不会使用浏览器。我想如下。首先,用户将使用用户数据(用户名,密码)向我的 htt://blablba/v1.0/login 发送请求,然后我将为该用户发送令牌。第二次或另一次用户通过此令牌调用我的服务的方法。你说刷新令牌。那个时候用户必须为不同的请求获取新的令牌。这是正常的方式吗?
-
我检查令牌过期时间的预览示例,如果令牌过期,则抛出异常,用户将得到 403“拒绝访问”。但我不知道这是否正常?
标签: java spring spring-boot spring-security jwt