JWTでスプリングブートを使用しています。
Application.properties
jwt.secret=xyz
Controller.Java
@PostMapping(path = "/authenticate")
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) throws Exception {
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new JwtResponse(token));
}
JwtTokenUtil.Java
@Value("${jwt.secret}")
private String secret;
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return doGenerateToken(claims, userDetails.getUsername());
}
private String doGenerateToken(Map<String, Object> claims, String subject) {
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY*1000)).signWith(SignatureAlgorithm.HS512, secret).compact();
}
の中に jwtTokenUtil.generateToken
コード次のエラーが発生します
ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is Java.lang.IllegalArgumentException: secret key byte array cannot be null or empty.] with root cause
Java.lang.IllegalArgumentException: secret key byte array cannot be null or empty.
at io.jsonwebtoken.lang.Assert.notEmpty(Assert.Java:204)
at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.Java:88)
at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.Java:100)
at net.javaguides.springboot.helloworldapp.config.JwtTokenUtil.doGenerateToken(JwtTokenUtil.Java:66)
at net.javaguides.springboot.helloworldapp.config.JwtTokenUtil.generateToken(JwtTokenUtil.Java:60)
at net.javaguides.springboot.helloworldapp.controller.BasicAuthController.createAuthenticationToken(BasicAuthController.Java:75)
at Java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
at Java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.base/Java.lang.reflect.Method.invoke(Method.Java:567)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.Java:189)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.Java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:800)
資格情報を指定すると、このエラーが発生します。アプリケーションはすでに資格情報を検証していますが、トークンの生成中にこのエラーが発生します。
更新:-
デバッグ中に、以下のような内部コードを見ました
@Override
public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) {
Assert.hasText(base64EncodedSecretKey, "base64-encoded secret key cannot be null or empty.");
Assert.isTrue(alg.isHmac(), "Base64-encoded key bytes may only be specified for HMAC signatures. If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
byte[] bytes = TextCodec.BASE64.decode(base64EncodedSecretKey);
return signWith(alg, bytes);
}
これでbytes
nullになります
私は同様の問題を抱えていましたが、私の理由は、コードがアプリケーションのプロパティで宣言されていて、それを読んでいたにもかかわらず、コードが秘密の値を取得できなかったことでした。秘密鍵のセットを実行しただけで、トークンを生成することができました。