2017-03-09 10 views
0

私は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は完全ではありますが、例はありません。

答えて

1

ホイールを再発明しようとしているように聞こえます。 OpenID connectはJWTを使用するオプションを提供しますが、独自のものを使用することを主張する場合、MitreID connect(https://github.com/mitreid-connect/)はJWTを提供するopensource java openid connect実装を見るのに悪い場所ではありません。

2

あなたは、実行時に対称鍵を生成する場合は、春の注入を使用してフィルタし、ログインクラス間、または静的変数

とそれを共有するが、再起動するサーバーがすべての発行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()); 
関連する問題