Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't Map exception thrown by MpJwtValidator::createSecurityIdentity #22004

Closed
GregJohnStewart opened this issue Dec 7, 2021 · 4 comments
Closed
Labels

Comments

@GregJohnStewart
Copy link
Contributor

Describe the bug

I am attempting to catch all errors related to authorization, in order to redirect web ui users towards a login page, For many exceptions, this has worked fine, but when a token has expired the following error is thrown:

https://github.com/quarkusio/quarkus/blob/main/extensions/smallrye-jwt/runtime/src/main/java/io/quarkus/smallrye/jwt/runtime/auth/MpJwtValidator.java#L78

Which I cannot seem to catch/map no matter what I try to do:

Mapper to catch the error:

@Slf4j
@Provider
public class AuthenticationFailedExceptionMapper extends UiNotAuthorizedExceptionMapper<AuthenticationFailedException> {

}

Mapper superclass, as there are different errors thrown in differing auth cases:


@Slf4j
public abstract class UiNotAuthorizedExceptionMapper<E extends Throwable> implements ExceptionMapper<E> {
    protected static boolean isUiEndpoint(URI uri) {
        String path = uri.getPath();

        return !path.startsWith("/api") &&
                !path.startsWith("/q/") &&
                !path.startsWith("/openapi");
    }

    @Context
    UriInfo crc;

    @Context
    JsonWebToken jsonWebToken;

//    @Context
//    @CookieParam("jwt")
//    Map<String, Cookie> authCookies;

    public Response toResponse(E e) {
        log.warn("User not authorized to access: {} - {}/{}", crc.getRequestUri(), e.getClass().getName(), e.getMessage());

//        log.info("Cookie: {}", authCookies);
        URI uri = this.crc.getRequestUri();
        if (isUiEndpoint(uri)) {
            return Response.seeOther( //seeOther = 303 redirect
                            UriBuilder.fromUri("/")
                                    .queryParam("messageHeading", "Unauthorized")
                                    .queryParam("message", "Please login to access this page.")
                                    .queryParam("messageType", "danger")
                                    .queryParam("returnPath", uri.getPath() + (uri.getQuery() == null ? "" : "?" + uri.getQuery()))
                                    .build()
                    )//build the URL where you want to redirect
//                    .entity("Not authorized")//entity is not required
                    .cookie(
                            new NewCookie(
                                    new Cookie(
                                            ConfigProvider.getConfig().getValue("mp.jwt.token.cookie", String.class),
                                            "",
                                            "/",
                                            ConfigProvider.getConfig().getValue("runningInfo.hostnamePort", String.class)
                                    ),
                                    "To clear out the auth cookie",
                                    0,
                                    false
                            )
                    )
                    .build();
        }
        log.info("Erring exception for url that wasn't in ui");
        return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage() + e.toString()).build();
    }

Expected behavior

The mapper given above should be able to catch the error thrown when tokens expire (and other errors)

Actual behavior

The error is not caught by the mapper

How to Reproduce?

Repository: https://github.com/Epic-Breakfast-Productions/OpenQuarterMaster/tree/main/software/open-qm-base-station

Will need to run ./gradlew build publishToMavenLocal for this dir to have dependency built: https://github.com/Epic-Breakfast-Productions/OpenQuarterMaster/tree/main/software/libs/open-qm-core

Will need a running instance of Mongodb to connect to

In the base station quarkus project, set mp.jwt.expiration.default to something small (10 seconds works), and quarkus.mongodb.connection-string to how to connect to your mongo instance (defaults to mongodb://localhost:27017)

Run server, open web ui ( http://localhost:8080 ). Create account (a local account to your instance) and login.

Wait for token to expire.

Refresh when token expired, see blank screen instead of being redirected to login screen

Output of uname -a or ver

Linux GeneralDevBox 5.11.0-41-generic #45~20.04.1-Ubuntu SMP Wed Nov 10 10:20:10 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "11.0.11" 2021-04-20 OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04) OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.5.0.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 7.3

Additional information

No response

@GregJohnStewart GregJohnStewart added the kind/bug Something isn't working label Dec 7, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented Dec 7, 2021

/cc @sberyozkin

@sberyozkin
Copy link
Member

@GregJohnStewart Can you please try to disable the proactive authentication, https://quarkus.io/guides/security-built-in-authentication#proactive-authentication ?

@GregJohnStewart
Copy link
Contributor Author

That worked! And I think that fixes a couple of other issues I have noticed in the past, related to the enforcement of authentication. Thanks!
Is this as intended (and I will close the issue) or something to dive into further? Part of me wants to say this is an odd thing to need to do to map an exception

@sberyozkin
Copy link
Member

sberyozkin commented Dec 7, 2021

Np, by default the security code runs before the JAX-RS chain starts, in this case one needs to experiment with the Vert.x fault filters to intercept the errors. This is why it is needed to delay the authentication until it is proven it is needed for the JAX-RS exception mappers to be used.
If you'd like please try the Vert.x fault filters and see if it works without disabling the proactive authentication, if it does not work then it would need be investigated further, this issue should be closed IMHO, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants