From 78d0ed13f2745c0fd83debb76c15c34592206375 Mon Sep 17 00:00:00 2001 From: soohyun Date: Fri, 20 Dec 2024 14:44:27 +0900 Subject: [PATCH] =?UTF-8?q?feature:=20mfa=20=EA=B8=B0=EB=8A=A5=20=EB=94=B0?= =?UTF-8?q?=EB=A1=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A1=9C=20?= =?UTF-8?q?=EB=B9=BC=EC=84=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/config/QrMfaAuthenticator.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 linkmind/src/main/java/com/app/toaster/admin/config/QrMfaAuthenticator.java diff --git a/linkmind/src/main/java/com/app/toaster/admin/config/QrMfaAuthenticator.java b/linkmind/src/main/java/com/app/toaster/admin/config/QrMfaAuthenticator.java new file mode 100644 index 0000000..54007fd --- /dev/null +++ b/linkmind/src/main/java/com/app/toaster/admin/config/QrMfaAuthenticator.java @@ -0,0 +1,89 @@ +package com.app.toaster.admin.config; + +import com.app.toaster.admin.entity.VerifiedAdmin; +import com.app.toaster.admin.entity.ToasterAdmin; +import com.app.toaster.admin.infrastructure.VerifiedAdminRepository; +import com.app.toaster.exception.Error; +import com.app.toaster.exception.model.CustomException; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.warrenstrange.googleauth.GoogleAuthenticator; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.mock.web.MockMultipartFile; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +@Component +@Slf4j +public class QrMfaAuthenticator { + + private String secret; + private final GoogleAuthenticator googleAuthenticator = new GoogleAuthenticator(); + private final VerifiedAdminRepository verifiedAdminRepository; + + + public QrMfaAuthenticator(@Value("${admin.secret}") final String secret, final VerifiedAdminRepository verifiedAdminRepository) { + this.secret = secret; + this.verifiedAdminRepository = verifiedAdminRepository; + } + + + public MultipartFile generateQrCode(String userKey) { + String data = makeQrDataString(userKey); + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + try { + BitMatrix bitMatrix = qrCodeWriter.encode(data, BarcodeFormat.QR_CODE, 240, 240); + BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + ImageIO.write(image, "png", byteArrayOutputStream); + byteArrayOutputStream.close(); + + byte[] qrCodeBytes = byteArrayOutputStream.toByteArray(); + + return new MockMultipartFile("qrCode", "qrcode.png", "image/png", qrCodeBytes); + } catch (WriterException | IOException e) { + log.error(e.getMessage()); + } + return null; + } + + private String makeQrDataString(String userKey) { + return "otpauth://totp/toaster?secret=" + userKey + "&issuer=Google"; + } + + public ToasterAdmin verifyGoogleTotpCode(Integer verificationCode, Long id) { + + VerifiedAdmin admin = verifiedAdminRepository.findById(id).orElseThrow( + () -> new CustomException(Error.NOT_FOUND_USER_EXCEPTION, "어드민이 존재하지않는다.") + ); + System.out.println(admin.getAdmin().getUsername()); + + if (verificationCode != null) { + try { + if (!googleAuthenticator.authorize(admin.getOtpSecretKey(), verificationCode)) { + throw new CustomException(Error.BAD_REQUEST_VALIDATION, "유효하지 않은 인증코드입니다."); + } + admin.authorize(); + admin.verifiedAdmin(); + return admin.getAdmin(); + } catch (Exception e) { + log.error("인증 쪽에서 에러 발생."); + } + } else { + throw new CustomException(Error.TOKEN_TIME_EXPIRED_EXCEPTION, "만료된 코드 입니다."); + } + return null; + } + + +}