QuarkusにおけるOIDCでのログインユーザー情報の保持方法
2024/09/15
弊社ではバックエンドのフレームワークにQuarkusを採用し、Kotlinで使用しています。
表題通りQuarkusでログインユーザー情報を保持する方法が意外に公式に詳しく書かれていないので紹介させていただきます。
以下公式に、リクエストヘッダーから取得する方法は書いてあるので、これを参考にします。
https://quarkus.io/guides/security-customization#jaxrs-security-context
この例からわかるように、SecurityContextにセットするという方法も取ることができます。
ただ、Principalは文字列しか保持できないため、ログインユーザーの細かい情報を持ち回すのには不便です。
ですので以下のようなイメージで実装しました(一部改変しています)。
kotlin
@Provider
@PreMatching
class SecurityOverrideFilter : ContainerRequestFilter {
@Inject lateinit var userRepository: UserRepository
@Inject lateinit var jwt: JsonWebToken
@Inject lateinit var userIdentity: UserIdentity
override fun filter(requestContext: ContainerRequestContext) {
val email = jwt.getClaim<String?>("specific_claim") ?: return
val user =
userRepository.findByEmailOrNotFound(email).also {
userIdentity.user = it
}
requestContext.securityContext =
object : SecurityContext {
override fun getUserPrincipal(): Principal = Principal { user.id.toString() }
override fun isUserInRole(role: String?): Boolean = role?.let { it in accessTargetKindKeys } ?: false
override fun isSecure(): Boolean = requestContext.securityContext.isSecure
override fun getAuthenticationScheme() = requestContext.securityContext.authenticationScheme
}
}
}
@RequestScoped
class UserIdentity {
var user: User = User()
}
jwtからメールアドレスを取得し、それを元にユーザーを取得し、RequestScopedのインスタンスに保持します。
これにより、CDIが使える箇所では UserIdentity
を依存性注入することで自由にログインユーザー情報を取ることができます。