-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
14 changed files
with
288 additions
and
100 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
src/main/java/sopt/makers/authentication/application/auth/api/AuthKeyApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package sopt.makers.authentication.application.auth.api; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
|
||
public interface AuthKeyApi { | ||
|
||
ResponseEntity<?> retrievePublicJwks(); | ||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/sopt/makers/authentication/application/auth/api/AuthKeyApiController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package sopt.makers.authentication.application.auth.api; | ||
|
||
import sopt.makers.authentication.usecase.auth.port.in.JwksRetrieveUsecase; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@RestController | ||
@RequestMapping("/.well-known") | ||
@RequiredArgsConstructor | ||
public class AuthKeyApiController implements AuthKeyApi { | ||
|
||
private final JwksRetrieveUsecase jwksRetrieveUsecase; | ||
|
||
@Override | ||
@GetMapping(value = "/jwks.json") | ||
public ResponseEntity<?> retrievePublicJwks() { | ||
return ResponseEntity.status(HttpStatus.OK).body(jwksRetrieveUsecase.retrievePublicKey()); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/sopt/makers/authentication/support/code/support/failure/ResourceFailure.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package sopt.makers.authentication.support.code.support.failure; | ||
|
||
import static lombok.AccessLevel.PRIVATE; | ||
|
||
import sopt.makers.authentication.support.code.base.FailureCode; | ||
|
||
import org.springframework.http.HttpStatus; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor(access = PRIVATE) | ||
public enum ResourceFailure implements FailureCode { | ||
INVALID_LOCATION(HttpStatus.BAD_REQUEST, "키 파일 위치가 잘못되었습니다."), | ||
INVALID_SUBJECT(HttpStatus.BAD_REQUEST, "주체 정보가 잘못되었습니다."), | ||
INVALID_ALGORITHM(HttpStatus.BAD_REQUEST, "알고리즘이 잘못되었습니다."), | ||
; | ||
private final HttpStatus status; | ||
private final String message; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
src/main/java/sopt/makers/authentication/support/config/LocalRSAKeyManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package sopt.makers.authentication.support.config; | ||
|
||
import static sopt.makers.authentication.support.code.support.failure.ResourceFailure.INVALID_ALGORITHM; | ||
import static sopt.makers.authentication.support.code.support.failure.ResourceFailure.INVALID_LOCATION; | ||
import static sopt.makers.authentication.support.code.support.failure.ResourceFailure.INVALID_SUBJECT; | ||
|
||
import sopt.makers.authentication.support.exception.support.ResourceException; | ||
import sopt.makers.authentication.support.jwt.RSAKeyManager; | ||
import sopt.makers.authentication.support.value.JwtProperty; | ||
|
||
import java.io.IOException; | ||
import java.io.StringReader; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.KeyFactory; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.interfaces.RSAPrivateKey; | ||
import java.security.interfaces.RSAPublicKey; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.security.spec.PKCS8EncodedKeySpec; | ||
import java.security.spec.X509EncodedKeySpec; | ||
|
||
import org.bouncycastle.util.io.pem.PemObject; | ||
import org.bouncycastle.util.io.pem.PemReader; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.core.io.ResourceLoader; | ||
import org.springframework.stereotype.Component; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Component | ||
@EnableConfigurationProperties(JwtProperty.class) | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class LocalRSAKeyManager implements RSAKeyManager { | ||
|
||
private final JwtProperty jwtProperty; | ||
private final ResourceLoader resourceLoader; | ||
|
||
@Override | ||
public RSAPublicKey getPublicKey() { | ||
try { | ||
Resource resource = loadPublicKeyResource(); | ||
PemObject pemObject = readPublicPemFile(resource); | ||
return parsePublicKey(pemObject); | ||
} catch (IOException e) { | ||
throw new ResourceException(INVALID_LOCATION); | ||
} catch (NoSuchAlgorithmException e) { | ||
throw new ResourceException(INVALID_ALGORITHM); | ||
} catch (InvalidKeySpecException e) { | ||
throw new ResourceException(INVALID_SUBJECT); | ||
} | ||
} | ||
|
||
@Override | ||
public RSAPrivateKey getPrivateKey() { | ||
try { | ||
Resource resource = loadPrivateKeyResource(); | ||
PemObject pemObject = readPrivatePemFile(resource); | ||
return generatePrivateKey(pemObject); | ||
} catch (IOException e) { | ||
throw new ResourceException(INVALID_LOCATION); | ||
} catch (NoSuchAlgorithmException e) { | ||
throw new ResourceException(INVALID_ALGORITHM); | ||
} catch (InvalidKeySpecException e) { | ||
throw new ResourceException(INVALID_SUBJECT); | ||
} | ||
} | ||
|
||
private Resource loadPublicKeyResource() { | ||
return resourceLoader.getResource(jwtProperty.secret().rsa().publicKey()); | ||
} | ||
|
||
private PemObject readPublicPemFile(final Resource resource) throws IOException { | ||
try (PemReader pemReader = | ||
new PemReader(new StringReader(resource.getContentAsString(StandardCharsets.UTF_8)))) { | ||
return pemReader.readPemObject(); | ||
} | ||
} | ||
|
||
private RSAPublicKey parsePublicKey(final PemObject pemObject) | ||
throws NoSuchAlgorithmException, InvalidKeySpecException { | ||
byte[] publicKeyBytes = pemObject.getContent(); | ||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); | ||
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | ||
return (RSAPublicKey) keyFactory.generatePublic(keySpec); | ||
} | ||
|
||
private Resource loadPrivateKeyResource() { | ||
return resourceLoader.getResource(jwtProperty.secret().rsa().privateKey()); | ||
} | ||
|
||
private PemObject readPrivatePemFile(final Resource resource) throws IOException { | ||
try (PemReader pemReader = | ||
new PemReader(new StringReader(resource.getContentAsString(StandardCharsets.UTF_8)))) { | ||
return pemReader.readPemObject(); | ||
} | ||
} | ||
|
||
private RSAPrivateKey generatePrivateKey(final PemObject pemObject) | ||
throws NoSuchAlgorithmException, InvalidKeySpecException { | ||
byte[] privateKeyBytes = pemObject.getContent(); | ||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); | ||
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | ||
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/main/java/sopt/makers/authentication/support/exception/support/ResourceException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package sopt.makers.authentication.support.exception.support; | ||
|
||
import sopt.makers.authentication.support.code.support.failure.ResourceFailure; | ||
import sopt.makers.authentication.support.exception.base.BaseException; | ||
|
||
public class ResourceException extends BaseException { | ||
|
||
public ResourceException(final ResourceFailure failure) { | ||
super(failure); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/sopt/makers/authentication/support/jwt/RSAKeyManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package sopt.makers.authentication.support.jwt; | ||
|
||
import java.security.interfaces.RSAPrivateKey; | ||
import java.security.interfaces.RSAPublicKey; | ||
|
||
public interface RSAKeyManager { | ||
|
||
RSAPublicKey getPublicKey(); | ||
|
||
RSAPrivateKey getPrivateKey(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.