spring-security-tistory/src/main/java/example/springsecuritytistory/security/JwtBeanGenerator.java at master · jsween5723/sprin
티스토리 블로깅을 위한 예제. Contribute to jsween5723/spring-security-tistory development by creating an account on GitHub.
github.com
개요
많은 경우에 JWT관련 예제를 보면 랜덤한 키를 생성하여 현재 로그인된 토큰들이 서버 재실행시 재사용이 불가능하도록 하는 경우가 대부분이다.
그렇다고 운영체제마다 다른 키 생성방법과 PKCS8 변환과정은 곤혹스럽기만하다.
따라서 공통이라고 볼 수 있는 자바 코드로 키 파일을 관리한다. resources 폴더는 런타임중 수정이 불가하니 일반 경로를 통해 참조하도록 한다.
로직
파일이 없으면 자바로 랜덤한 키를 생성 후 파일로 저장한다.
application.yml spring.application.name 값을 파일명으로 한다.
있다면 불러와 인스턴스로 만들어 빈을 생성한다.
코드
@Bean
public RSAKey rsaKey(KeyPair keyPair) {
return new Builder((RSAPublicKey) keyPair.getPublic()).privateKey(
(RSAPrivateKey) keyPair.getPrivate())
.keyID(UUID.randomUUID()
.toString())
// 만약 키를 여러개 사용한다면 key id를 관리해주어야 한다.
.build();
}
@Bean
public KeyPair keyPair(@Value("${spring.application.name:key}") String path)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
var privateKeyFile = new File(path);
String publicKeyPath = path + ".pub";
var publicKeyFile = new File(publicKeyPath);
if (privateKeyFile.exists() && publicKeyFile.exists()) {
return readKeyPairFromFile(path, publicKeyPath);
}
KeyPair keyPair = generateNewKeyPair();
saveFileKeyPair(keyPair, path, publicKeyPath);
return keyPair;
}
private KeyPair generateNewKeyPair() throws JOSEException {
RSAKeyGenerator rsaKeyGenerator = new RSAKeyGenerator(RSAKeyGenerator.MIN_KEY_SIZE_BITS);
RSAKey generated = rsaKeyGenerator.generate();
return new KeyPair(generated.toPublicKey(), generated.toPrivateKey());
}
private KeyPair readKeyPairFromFile(String path, String publicKeyPath)
throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
KeyFactory factory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = factory.generatePrivate(
new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(path))));
PublicKey publicKey = factory.generatePublic(
new X509EncodedKeySpec(Files.readAllBytes(Paths.get(publicKeyPath))));
return new KeyPair(publicKey, privateKey);
}
private void saveFileKeyPair(KeyPair keyPair, String path, String publicKeyPath)
throws IOException {
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
try (FileOutputStream fos = new FileOutputStream(path)) {
fos.write(privateKey.getEncoded());
}
try (FileOutputStream fos = new FileOutputStream(publicKeyPath)) {
fos.write(publicKey.getEncoded());
}
}
키페어 생성 코드
반응형
LIST
'Spring > Spring Security' 카테고리의 다른 글
Spring Security 6 - SDK, 보일러플레이트 코드 없이 파이어베이스 id토큰 식별하기 | OAuth2 Resource server (0) | 2024.10.01 |
---|---|
Spring Security 6 - 토큰 기반 인증 유지 | OAuth2 resource server | JWT (작성중) (0) | 2024.09.04 |
Spring Security 6 - 세션 기반 인증 유지 | Authentication Persistence (0) | 2024.09.01 |
부록: JPA 엔티티에 UserDetails, OAuth2User 구현하지 말기 (0) | 2024.09.01 |
부록: 빈 생성 기능과 필터체인 분리 (0) | 2024.09.01 |