我正在開發REST API,並決定使用JWT進行身份驗證/安全性。有一個服務可以處理登錄驗證,並有一個過濾器綁定到每個需要驗證的服務。如何爲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是相當完整的,但沒有帶來任何例子