0

Because we use a custom format of error we want to customize all error responses ... in particular Forbidden (we succeed) and Unauthorized (we failed).

I read many docs, posts and I tried different solutions you can find in my sample project

First: ServerExceptionMapper

@ServerExceptionMapper
@Priority(1)
fun unauthorized(e: UnauthorizedException) =
   mapExceptionIntoError(Response.Status.UNAUTHORIZED, "UNAUTHORIZED", e.message)

Second: ExceptionMapper

@Provider
@Priority(Priorities.AUTHORIZATION)
class UnauthorizedErrorMapper : ExceptionMapper<UnauthorizedException> {

    private val logger: Logger = Logger.getLogger(this.javaClass.simpleName)

    @Override
    override fun toResponse(exception: UnauthorizedException): Response {
        logger.severe(exception.message)

        val message = exception.message
        val code = STATUS.statusCode
        val error =  ErrorInfo(STATUS.statusCode, STATUS.name, message)

        return Response
            .status(code)
            .entity(error)
            .build()
    }

    companion object {
        private val STATUS = Response.Status.UNAUTHORIZED
    }
}

Third: failureHandler

@ApplicationScoped
class UnauthorizedExceptionHandler {
    fun init(@Observes router: Router) {
        router.route().failureHandler { event ->
            if (event.failure() is UnauthorizedException) {
                event.response().end("CUSTOMIZED_RESPONSE")
            } else {
                event.next()
            }
        }
    }
}

With no success. What did I miss or do wrong?

Thanks in advance Patrice

Patrice Conil
  • 83
  • 1
  • 8

2 Answers2

0

This use case does work as we have a test in the repo that does this.

public static final class CustomExceptionMappers {

    @ServerExceptionMapper(UnauthorizedException.class)
    public Response forbidden() {
        return Response.status(999).build();
    }
}
geoand
  • 60,071
  • 24
  • 172
  • 190
  • Yes as I said it works with forbidden ... but not for Unauthorized. :( – Patrice Conil Aug 30 '23 at 12:30
  • Maybe a kotlin side effect. @geoand have you tried to run tests in my repo ? – Patrice Conil Aug 30 '23 at 13:15
  • I have not unfortunately – geoand Aug 30 '23 at 13:46
  • Hi @geoand, I investigate more and found that we haven't same behaviour using RolesAllowed on resource path or by defining roles in application.properties When I define role via annotation, as you do in the test, everything works like a charm but when role is defined in application.properties CustomExceptionMapper is never called. – Patrice Conil Aug 31 '23 at 15:09
0

ServerExceptionMapper works only for /hello using RolesAllowed annotation like in

    @GET
    @Path("/hello")
    @RolesAllowed("role1")
    fun hello(): RestResponse<Reply> = RestResponse.ok(Reply("Hello from RESTEasy Reactive"))


    @GET
    @Path("/helloNotAnnotated")
    @Produces(MediaType.APPLICATION_JSON)
    fun helloNotAnnotated() = RestResponse.ok(Reply("Hello from helloNotAnnotated"))

and not for role2 defined in application.properties using elytron

quarkus.security.users.embedded.enabled=true
quarkus.security.users.embedded.plain-text=true
quarkus.security.users.embedded.users.user=password
quarkus.security.users.embedded.roles.role1=user
quarkus.security.users.embedded.roles.role2=user
quarkus.http.auth.permission.role-role2.paths=/helloNotAnnotated
quarkus.http.auth.permission.role-role2.policy=role2-policy
quarkus.http.auth.policy.role2-policy.roles-allowed=role2

See differences in action in my sample project

Patrice Conil
  • 83
  • 1
  • 8