jooby-project / jooby

The modular web framework for Java and Kotlin
https://jooby.io
Apache License 2.0
1.7k stars 199 forks source link

Wired behaviours between Cors and Pac4jModule #3509

Closed jonaskahn closed 2 weeks ago

jonaskahn commented 2 weeks ago

In my project, I setup both CORS and Pac4J like below:

    install(
        Pac4jModule().client(
            "/api/secure/*",
            CheckHttpMethodAuthorizer(
                HttpConstants.HTTP_METHOD.GET,
                HttpConstants.HTTP_METHOD.PUT,
                HttpConstants.HTTP_METHOD.POST,
                HttpConstants.HTTP_METHOD.DELETE,
                HttpConstants.HTTP_METHOD.PATCH
            )
        ) {
            HeaderClient(
                "Authorization",
                "Bearer ",
                AdvancedJwtAuthenticator(
                    require(JedisPooled::class.java),
                    SecretSignatureConfiguration(it.getString("jwt.salt"))
                )
            )
        }
    )

    val corsOption = Cors()
    corsOption.setOrigin("*")
    corsOption.setUseCredentials(true)
    corsOption.setHeaders("X-Requested-With", "Content-Type", "Accept", "Origin", "Authorization")
    corsOption.setMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD")
    corsOption.setMaxAge(Duration.ofMinutes(60))
    use(CorsHandler(corsOption))

AdvancedJwtAuthenticator: Just an extended class to store JWT ID to redis before create user profile.


                    if (startAuthentication(context, sessionStore, currentClients)) {
                        LOGGER.debug("Starting authentication");
                        saveRequestedUrl(context, sessionStore, currentClients, config.getClients().getAjaxRequestResolver());
                        action = redirectToIdentityProvider(context, sessionStore, currentClients);
                    } else {
                       // Line 152: DefaultSecurityLogic.java
                        LOGGER.debug("unauthorized");
                        action = unauthorized(context, sessionStore, currentClients);
                    }

It will lead to browser can never send Options method to complete API calling. Could you explain this ?

jknack commented 2 weeks ago

Just add Cors handler before pac4j, should work.

jonaskahn commented 2 weeks ago

Confirmed. It worked. Thank you Btw, Could you write docs to notice other people?

jknack commented 2 weeks ago

This is part of handler/pipeline documentation https://jooby.io/#router-pipeline-order

You added a security handler before cors, so browser will never reach cors bc of the security handler running first.

does it make sense?

jonaskahn commented 2 weeks ago

Yup. It does I missed the docs. In other framewors and language I've never ever care about the order of settings 💀. This is my second time, before that I also figure out to install Jackson before declare router. Aw, thank for your help.