0

I have the following controller for which I'm trying to test

@Secured(SecurityRule.IS_AUTHENTICATED)
@Controller
class UserController(private val userService: UserService) {
    @Get("/principal")
    fun getPrincipal(principal: Principal): Principal = principal
}

My test looks as the following

class Credentials(val username: String, val password: String)

class LoginResponse(
    @JsonProperty("access_token") val accessToken: String,
    @JsonProperty("expires_in") val expiresIn: Int,
    @JsonProperty("refresh_token") val refreshToken: String,
    @JsonProperty("token_type") val tokenType: String,
    @JsonProperty("username") val username: String)

@Client("/")
interface Client {
    @Post("/login")
    fun login(@Body credentials: Credentials): LoginResponse

    @Get("/principal")
    fun getPrincipal(@Header authorizationHeader: String): Principal
}

@MicronautTest
internal class UserControllerTest {
    @Inject
    lateinit var authenticationConfiguration: AuthenticationConfiguration

    @Inject
    lateinit var client: Client

    @Test
    fun getPrincipal() {
        val credentials = Credentials(authenticationConfiguration.testUserEmail, authenticationConfiguration.testUserPassword)
        val loginResponse = client.login(credentials)
        val authorizationHeader = "Authorization:Bearer ${loginResponse.accessToken}"
        val principal = client.getPrincipal(authorizationHeader)
    }
}

The login works just fine. I get a bearer token and the authorizationHeader looks just fine. But the call to client.getPrincipal(authorizationHeader) fails with io.micronaut.http.client.exceptions.HttpClientResponseException: Unauthorized

Any clue what goes wrong?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
user672009
  • 4,379
  • 8
  • 44
  • 77

1 Answers1

0

It turns out that I can either declare my client as the following. By naming the argument to match the actual http header.

@Client("/")
interface Client {
    ...
    @Get("/principal")
    fun getPrincipal(@Header authorization: String): Principal
}

But it's also possible letting the @Header annotation take an argument specifying which http header to target

@Client("/")
interface Client {
    ...
    @Get("/principal")
    fun getPrincipal(@Header("Authorization") authorizationValue: String): Principal
}
user672009
  • 4,379
  • 8
  • 44
  • 77