Java로 2단계 인증
Overview
예전부터 두 단계의 인증을 실시하고 싶었지만 좋은 프로그램 라이브러리가 있기 때문에 간단하게 실현할 수 있었다.
GoogleAuth (2단계 인증 서버 사이드 라이브러리)
Google Auth는 RFC6238 에서 정의한 서버 쪽을 위한 자바 라이브러리로 Time-based One-time Password (TOTP) 를 만들 수 있습니다.
위의 프로그램 라이브러리를 사용하여 서버 측면을 설치하는 경우 Google에서 제공하는 Google Authenticator와 같은 애플리케이션에서 발행하는 일회용 토큰을 사용하여 사용자가 인증할 수 있습니다.
iOS 버전 Google Authenticator
Android 버전 Google Authenticator
Google Authenticator도 TOTP 규격으로 타임 토큰을 제작하여 사용할 수 있습니다.
※ 본 기사는 사용자가 Google Authenticator가 설치된 터미널을 분실한 경우는 고려하지 않았습니다.본격적으로 도입되는 상황에서 이런 상황의 운용을 사전에 구상할 필요도 있다.
2단계 인증의 대략적인 절차
나는 대략 아래의 절차라고 생각한다.
샘플 코드
위의 시퀀스 다이어그램에서 설명한 서버 섹션의 실제 설치 코드입니다.
언어는 Java를 사용합니다.
사용자 정보의 저장 처리는 DB가 아니라 Singleton의 맵으로 흐리멍덩합니다.
샘플 코드 설명
샘플 코드의 해설이라기보다는 라이브러리 사용법이다.
시크릿 키의 릴리스 & 저장
다음 코드로 "user id"용 SecretKey를 발행하여 데이터베이스 등에 저장할 수 있습니다.GoogleAuthenticator gAuth = new GoogleAuthenticator();
GoogleAuthenticatorKey key = gAuth.createCredentials("user_id");
또한 상기 코드를 실행하기 전에 다음과 같은 준비를 해야 한다.
ICredential Repository 구현 클래스 준비
위의createCredentials를 실행한 후 GoogleAuth는 ICredential Repository의 구현 클래스인saveUserCredentials 방법을 호출하여secret Key의 저장 처리를 실행합니다.
※ 호출된 ICredential Repository의 설치 클래스 지정 방법은 Java Service Loader용 준비 참조public class MyCredentialRepository implements ICredentialRepository {
// ...
@Override
public void saveUserCredentials(String userId, String secretKey, int validationCode, List<Integer> scratchCodes) {
// userIdをkeyにしてsecretKeyを保存する処理を記述
}
}
참고로 scratchCodes는 사용자가 터미널을 잃어버렸을 때 사용하는 코드로 기본적으로 5개를 발행한다.
https://github.com/wstrange/GoogleAuth#scratch-codes
validationCode가 어떤 용도를 구상했는지 잘 이해할 수 없습니다.혹시 아시는 분 있으면 꼭 가르쳐 주세요
샘플 코드는 하지 않았지만 이 값들의 처리도 필요에 따라 실시하는 것이 좋다고 생각합니다.
Java ServiceLoader용 준비
createCredentials를 실행할 때 GoogleAuth는 Java ServiceLoader API ICredential Repository의 실행 클래스를 가져와 secret Key를 저장합니다.
src/resource 산하의 등류 경로가 통과하는 곳에서META-INF/services 폴더com을 제작합니다.warrenstrange.googleauth.ICredential Repository라는 텍스트 파일을 만듭니다.
제작된 파일에서 다음과 같이 ICredential Repository의 실제 클래스 이름을 기술하면 Google Auth에서 이 클래스를 사용합니다.io.github.yuizho.twofactorauth.MyCredentialRepository
시크릿 정보 반환
생성된 시크릿 키를 포함한 시크릿 정보를 Google Authenticator로 읽을 때 다음 형식의 URI를 생성하여 QR 코드로 변환합니다.otpauth://totp/<userId>?secret=<secretKey>&issuer=<applicationName>
e.g. otpauth://totp/test_user?secret=ZYWAZKOQLG3YHBSZ&issuer=two-factor-auth-sample
URI 형식의 자세한 내용은 다음을 참조하십시오.
https://github.com/google/google-authenticator/wiki/Key-Uri-Format
토큰 인증
저장된 위치에서 "user id"에 사용되는 secretKey를 가져와 토큰을 생성한 다음 Google Authenticator를 통해 받은 토큰과 일치하는지 확인할 수 있습니다.GoogleAuthenticator gAuth = new GoogleAuthenticator();
boolean isCodeValid = gAuth.authorizeUser("user_id", token);
Google Auth는 secretKey를 저장할 때와 같이 ICredential Repository 구현 클래스의 get Secret Key 방법을 호출하여 secretKey를 처리합니다.
※ 호출된 ICredential Repository의 설치 클래스 지정 방법은 Java Service Loader용 준비 참조public class MyCredentialRepository implements ICredentialRepository {
// ...
@Override
public String getSecretKey(String userId) {
// userIdをキーにテーブルからsecretKeyを取得し、返却する処理を実装
}
}
그런 다음 Google Auth에서 받은 secretkey와 현재timestamp에 따라 영패를 생성하여 Google Authenticator#authorize User에 전달된 두 번째 파라미터의 영패와 비교합니다.
총결산
따라서 비교적 간단하게 두 단계의 인증을 실현했다.
이번에는 서버 쪽 라이브러리에서 Google Auth를 사용했습니다. 물론 라이브러리를 사용하지 않아도 직접 설치할 수 있습니다.
이 경우 아래의 RFC 등을 참조하여 영패 TOTP의 생성 처리를 실시할 수 있다(샘플 코드도 있다).
https://tools.ietf.org/html/rfc6238
Reference
이 문제에 관하여(Java로 2단계 인증), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuizho/items/553f1aac138143d8f8d9
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
나는 대략 아래의 절차라고 생각한다.
샘플 코드
위의 시퀀스 다이어그램에서 설명한 서버 섹션의 실제 설치 코드입니다.
언어는 Java를 사용합니다.
사용자 정보의 저장 처리는 DB가 아니라 Singleton의 맵으로 흐리멍덩합니다.
샘플 코드 설명
샘플 코드의 해설이라기보다는 라이브러리 사용법이다.
시크릿 키의 릴리스 & 저장
다음 코드로 "user id"용 SecretKey를 발행하여 데이터베이스 등에 저장할 수 있습니다.GoogleAuthenticator gAuth = new GoogleAuthenticator();
GoogleAuthenticatorKey key = gAuth.createCredentials("user_id");
또한 상기 코드를 실행하기 전에 다음과 같은 준비를 해야 한다.
ICredential Repository 구현 클래스 준비
위의createCredentials를 실행한 후 GoogleAuth는 ICredential Repository의 구현 클래스인saveUserCredentials 방법을 호출하여secret Key의 저장 처리를 실행합니다.
※ 호출된 ICredential Repository의 설치 클래스 지정 방법은 Java Service Loader용 준비 참조public class MyCredentialRepository implements ICredentialRepository {
// ...
@Override
public void saveUserCredentials(String userId, String secretKey, int validationCode, List<Integer> scratchCodes) {
// userIdをkeyにしてsecretKeyを保存する処理を記述
}
}
참고로 scratchCodes는 사용자가 터미널을 잃어버렸을 때 사용하는 코드로 기본적으로 5개를 발행한다.
https://github.com/wstrange/GoogleAuth#scratch-codes
validationCode가 어떤 용도를 구상했는지 잘 이해할 수 없습니다.혹시 아시는 분 있으면 꼭 가르쳐 주세요
샘플 코드는 하지 않았지만 이 값들의 처리도 필요에 따라 실시하는 것이 좋다고 생각합니다.
Java ServiceLoader용 준비
createCredentials를 실행할 때 GoogleAuth는 Java ServiceLoader API ICredential Repository의 실행 클래스를 가져와 secret Key를 저장합니다.
src/resource 산하의 등류 경로가 통과하는 곳에서META-INF/services 폴더com을 제작합니다.warrenstrange.googleauth.ICredential Repository라는 텍스트 파일을 만듭니다.
제작된 파일에서 다음과 같이 ICredential Repository의 실제 클래스 이름을 기술하면 Google Auth에서 이 클래스를 사용합니다.io.github.yuizho.twofactorauth.MyCredentialRepository
시크릿 정보 반환
생성된 시크릿 키를 포함한 시크릿 정보를 Google Authenticator로 읽을 때 다음 형식의 URI를 생성하여 QR 코드로 변환합니다.otpauth://totp/<userId>?secret=<secretKey>&issuer=<applicationName>
e.g. otpauth://totp/test_user?secret=ZYWAZKOQLG3YHBSZ&issuer=two-factor-auth-sample
URI 형식의 자세한 내용은 다음을 참조하십시오.
https://github.com/google/google-authenticator/wiki/Key-Uri-Format
토큰 인증
저장된 위치에서 "user id"에 사용되는 secretKey를 가져와 토큰을 생성한 다음 Google Authenticator를 통해 받은 토큰과 일치하는지 확인할 수 있습니다.GoogleAuthenticator gAuth = new GoogleAuthenticator();
boolean isCodeValid = gAuth.authorizeUser("user_id", token);
Google Auth는 secretKey를 저장할 때와 같이 ICredential Repository 구현 클래스의 get Secret Key 방법을 호출하여 secretKey를 처리합니다.
※ 호출된 ICredential Repository의 설치 클래스 지정 방법은 Java Service Loader용 준비 참조public class MyCredentialRepository implements ICredentialRepository {
// ...
@Override
public String getSecretKey(String userId) {
// userIdをキーにテーブルからsecretKeyを取得し、返却する処理を実装
}
}
그런 다음 Google Auth에서 받은 secretkey와 현재timestamp에 따라 영패를 생성하여 Google Authenticator#authorize User에 전달된 두 번째 파라미터의 영패와 비교합니다.
총결산
따라서 비교적 간단하게 두 단계의 인증을 실현했다.
이번에는 서버 쪽 라이브러리에서 Google Auth를 사용했습니다. 물론 라이브러리를 사용하지 않아도 직접 설치할 수 있습니다.
이 경우 아래의 RFC 등을 참조하여 영패 TOTP의 생성 처리를 실시할 수 있다(샘플 코드도 있다).
https://tools.ietf.org/html/rfc6238
Reference
이 문제에 관하여(Java로 2단계 인증), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuizho/items/553f1aac138143d8f8d9
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
GoogleAuthenticator gAuth = new GoogleAuthenticator();
GoogleAuthenticatorKey key = gAuth.createCredentials("user_id");
public class MyCredentialRepository implements ICredentialRepository {
// ...
@Override
public void saveUserCredentials(String userId, String secretKey, int validationCode, List<Integer> scratchCodes) {
// userIdをkeyにしてsecretKeyを保存する処理を記述
}
}
io.github.yuizho.twofactorauth.MyCredentialRepository
otpauth://totp/<userId>?secret=<secretKey>&issuer=<applicationName>
e.g. otpauth://totp/test_user?secret=ZYWAZKOQLG3YHBSZ&issuer=two-factor-auth-sample
GoogleAuthenticator gAuth = new GoogleAuthenticator();
boolean isCodeValid = gAuth.authorizeUser("user_id", token);
public class MyCredentialRepository implements ICredentialRepository {
// ...
@Override
public String getSecretKey(String userId) {
// userIdをキーにテーブルからsecretKeyを取得し、返却する処理を実装
}
}
따라서 비교적 간단하게 두 단계의 인증을 실현했다.
이번에는 서버 쪽 라이브러리에서 Google Auth를 사용했습니다. 물론 라이브러리를 사용하지 않아도 직접 설치할 수 있습니다.
이 경우 아래의 RFC 등을 참조하여 영패 TOTP의 생성 처리를 실시할 수 있다(샘플 코드도 있다).
https://tools.ietf.org/html/rfc6238
Reference
이 문제에 관하여(Java로 2단계 인증), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yuizho/items/553f1aac138143d8f8d9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)