如何为 JWT 生成和访问密钥
Posted
技术标签:
【中文标题】如何为 JWT 生成和访问密钥【英文标题】:How to generate and access key for JWT 【发布时间】:2017-07-30 03:37:10 【问题描述】:我正在开发一个 REST API,我决定使用 JWT 进行身份验证/安全性。有一个服务来处理登录验证,还有一个过滤器绑定到每个需要身份验证的服务。
LoginService.java:
@Path("login")
public class LoginService
private final static long EXPIRATION_TIME = 60000;
@POST
@Produces("application/json")
@Consumes("application/json")
public Response authenticateUser(Credentials c)
Users login;
UsersDAO u = new UsersDAO();
try
login = u.getAuthentication(c);
String token = generateToken(login.getIdUser(), login.getLogin(), login.getRole());
// Return the token on the response
return Response.ok().header(AUTHORIZATION, "Bearer " + token).build();
catch (Exception e)
System.out.println("Exception: " + e.toString());
return Response.status(Response.Status.UNAUTHORIZED).build();
private String generateToken(int id, String login, int role)
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//TODO generate key (or retrieve it from file/database?)
Key key;
String jwtToken = Jwts.builder()
.setSubject(login)
.setIssuer("my_company")
.setIssuedAt(now)
.setExpiration(new Date(nowMillis + EXPIRATION_TIME))
.claim("role", role)
.signWith(SignatureAlgorithm.HS512, key)
.compact();
return jwtToken;
JWTTokenFilter.java:
@Provider
@JWTTokenNeeded
@Priority(Priorities.AUTHENTICATION)
public class JWTTokenFilter implements ContainerRequestFilter
@Override
public void filter(ContainerRequestContext requestContext) throws IOException
String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
String token = authorizationHeader.substring("Bearer".length()).trim();
try
// TODO generate key (or retrieve it from file/database?)
Key key;
Jwts.parser().setSigningKey(key).parseClaimsJws(token);
catch (Exception e)
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
我一直在做一些研究,但我仍然不确定如何管理密钥生成/验证。我的疑惑:
如果我在身份验证时创建密钥,我如何将相同的密钥传递给过滤器?我看过一些代码示例,其中在使用随机数进行身份验证和验证时都会生成密钥,这对我来说毫无意义,因为生成的密钥不会相同。我在那里错过了什么? 其他选项是将密钥存储在文件系统中,因此身份验证和验证进程都可以访问相同的密钥。这会给实施带来什么不利因素(如果有的话)?是否有任何好的库或框架来管理文件系统(甚至数据库)中的密钥生成和访问?请注意,我不想将密钥传递给客户端,因此他们必须不时进行身份验证才能刷新令牌,因为他们无法访问到期日期。 This 主题不适合我的情况,this 相当完整但没有带来任何示例
【问题讨论】:
【参考方案1】:如果您在运行时生成对称密钥,您可以使用 spring 注入或静态变量在过滤器和登录类之间共享它
但请考虑重新启动服务器将使所有已发布的 JWT 无效。如果这不是您想要的行为,您需要将密钥保存在属性文件或数据库中
使用 Jjwt,您可以:
//generate a random HMAC
Key key = MacProvider.generateKey(SignatureAlgorithm.HS256);
//Get the key data
byte keyData[]= key.getEncoded();
//Store data in a file...
//Build key
Key key = new SecretKeySpec(keyData, SignatureAlgorithm.HS256.getJcaName());
【讨论】:
以上是关于如何为 JWT 生成和访问密钥的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Identity Server 4 生成和添加签名密钥?