如何在 Micronaut 中模拟经过身份验证的用户?

问题描述 投票:0回答:1

我正在尝试为需要经过身份验证的用户的控制器方法编写测试, 这是它的样子:

@Controller("/api/task")
class TaskController(
    private val taskCompletionService: TaskCompletionService,
    private val userSecurityService: UserSecurityService
) {

    @Post("/{id}")
    suspend fun completeTask(
        @PathVariable id: Long,
        @Body request: TaskCompletionRequestDTO
    ) {
        taskCompletionService.completeTask(
            taskId = id,
            userId = userSecurityService.getUserId(),
            action = request.action
        )
    }
}

我正在努力嘲笑 UserSecurityService

@Singleton
class UserSecurityService {

    fun getUserId(): Int = getUserIdOrNull() ?: throw UserIdNotFoundException("UserId not found")
    fun getUserIdOrNull(): Int? = getPrincipal()?.attributes?.get(PrincipalAttribute.USER_ID)?.toString()?.toInt()

    @OptIn(ExperimentalStdlibApi::class)
    private fun getPrincipal(): Authentication? =
        (ServerRequestContext.currentRequest<Any?>().get().userPrincipal.getOrNull()) as? Authentication

    @OptIn(ExperimentalStdlibApi::class)
    fun isAuthorized(): Boolean {
        val principal =
            ServerRequestContext.currentRequest<HttpRequest<*>>()
                .getOrNull()
                ?.attributes?.get(HttpAttributes.PRINCIPAL.toString(), Authentication::class.java)

        return principal != null && !principal.isEmpty
    }
}
  1. 我尝试使用@MockBean注释,但它说我不能在最终类上使用AOP
  2. 我尝试使用@Replaces注释
 @Replaces(UserSecurityService::class)
    @Bean
    fun userSecurityService(): UserSecurityService = mock()

和存根

whenever(userSecurityService().getUserId()).thenReturn(123)

,但不知何故

getUserId()
总是返回 0,所以我认为这种存根不起作用(

情况很复杂,因为我有几个 HTTP 过滤器需要访问有关经过身份验证的用户的数据(通过

UserSecurityService
)。在实际应用程序中,我使用 JWT 令牌,但在测试中我无法使用生产令牌

micronaut:
  security:
    token:
      jwt:
        claims-validators:
          issuer: https://mysecretproject.com/auth
        signatures:
          secret:
            generator:
              secret: ${SECURITY_TOKEN}

理想情况下,我想在 Spring 中使用类似于

@WithMockUser
的东西,我可以在其中模拟用户身份验证,而不需要真正的 JWT 令牌。 Micronaut 有没有办法在测试中模拟 JWT 身份验证或绕过令牌验证?

预先感谢您的帮助!

kotlin authentication mocking micronaut
1个回答
0
投票

不是我的存储库,但我通过以下方式成功实现了它:

https://github.com/lstoeferle/micronaut-jwt-auth-mock

基本上,您可以将

TokenAuthenticationFetcher
替换为您自己的,并且可以使用用户和给定角色对身份验证进行硬编码。

© www.soinside.com 2019 - 2024. All rights reserved.