Auth Framework
Auth Framework 코드를 보고 이해하기 위한 글 2026.03.27 Main branch(cbebe6bd229ee296d31cafd9118567d11840a8e7)을 보고 분석
AI의 로드맵 (Notion) 을 보고 순서대로 분석해봄
0. Background
가장 기본이 되는 Framework Backoffice, Partner backoffice, partner auth는 auth-framework을 gradle로 import함.
Auth 구조를 설계하신 분의 공식 문서를 보면, Backoffice, Partner Auth는 거의 비슷한 구조로 공통된 부분을 AuthFramework로 추출하시고,
resource/META-INF.spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports을 통해 PluggableAutoConfiguration 을 import 한다. => 그러면 이 부분이 ComponentScan을 통해 com.bucketplace.auth.pasf package을 전부 import 하면서, auth framework을 backoffice, partner auth에서 다 가져온다.
추가적으로 PluggableAuthConfigurationProperties, OAuthFeatureConfigurationProperties 이 두 프로퍼티도 spring application.yaml에서 가져온다.
1. Auth Plugins / Provider
AuthPlugin.kt
- getDescriptor - Plugin의 Descriptor을 정의. 이것으로 어떤 플러그인 구현체를 선택할지 결정. 그리고 그 구현체가 내부적으로 LDAP / DB을 사용함.
- verifyAndGetUser - loginId, systemName, password
- getTwoFactorFeature
- 이 부분은 Partner auth와 관련된 부분으로 보여 잠시 패스..
AuthPluginProvider.kt
- AuthPlugin 을 Properties 로 가져와서 맵핑해주는 곳.
AuthAdminPlugins.kt
- Admin 의 할 수 있는 역할 수행
- 우리가 일반적으로 생각할 수 있는 사이트 운영자의 회원관리 정보
AuthAdminPluginsProvider.kt
- 위의 AuthPluginProvider와 동일하게 Properties 을 가져와서 맵핑.
- Properties 도 동일함.
2. GrpcService
- GRpc 서비스가 Spring MVC의 Controller라고 이해할 수 있음.
- path나 req / res는 proto에 정의됨. protos/bauth.proto 에 정의되어 있음. 예를 들어
// com.bucketplace.pasf.bauth.grpc
// BackofficeAuthGrpcService
@Component
@GRpcService
class BackofficeAuthGrpcService(
private val backofficeAuthAuthorityManager: BackofficeAuthAuthorityManager,
private val adminService: AdminService,
private val userService: UserService,
private val userRoleService: UserRoleService,
private val backupService: BackupService,
private val piiLogger: PIILogger,
) : BackofficeAuthServiceGrpcKt.BackofficeAuthServiceCoroutineImplBase() {
// Login endpoint는 proto에 정의
override suspend fun login(request: LoginReq): LoginRes {
val result =
runCatching {
loginRes {
accessToken = adminService.login(request.loginId, request.password)
}
}
piiLogger.log(
accessType = AccessType.AUTHORIZATION,
accessResult = if (result.isSuccess) AccessResult.SUCCESS else AccessResult.FAILURE,
target = request.loginId,
)
return result.getOrThrow()
}
override suspend fun refresh(request: RefreshReq): RefreshRes {
return refreshRes {
accessToken = adminService.refresh(request.accessToken)
}
}
//...
}
// bauth.proto
service BackofficeAuthService {
// Backoffice Auth 웹 콘솔 사용자 인증
rpc Login (LoginReq) returns (LoginRes) {
option (google.api.http) = {
post: "/v1/admin/login"
body: "*"
};
}
// Backoffice Auth 웹 콘솔 인증 토큰 갱신
rpc Refresh (RefreshReq) returns (RefreshRes) {
option (google.api.http) = {
post: "/v1/admin/refresh"
body: "*"
};
}
// ...
}