[keycloak-user] JBoss EAP 7.0 - keycloak-wildfly-adapter-dist-4.3.0.Final - KeycloakConfigResolver called on unprotected Resources
Dmitry Telegin
dt at acutus.pro
Mon Nov 5 00:36:17 EST 2018
Hi Andreas, you're welcome :) answers inline
On Fri, 2018-11-02 at 19:25 +0000, Andreas Lau wrote:
> Hello Dmitry,
>
>
>
> thanks for your help, this is exactly I was looking for and so simple
> :).
>
> Yes the resources are just static stuff that is needed to display the
> site properly. Nothing that is relevant to security. It's simple if
> the main page is authenticated the resources don't have to be checked
> again.
>
>
>
> Thinking more about it I would like to know if there is a way to
> recognize that the page, that gets called, is called from a logged in
> state. Actually we might be able to access the access token of the
> header right?
>
>
>
> From my current understanding I would not need to get a particular
> config (so I could return the default new KeycloakDeployment()) if I
> am successfully logged in and call further pages from "within". Am I
> right?
I don't think this is a good idea. How should you detect a logged-in
state from a resolver? Yep there is access token, but how would you
validate it? You need realm public keys for that, where do you get
them? If you return a dummy KeycloakDeployment, how should the
underlying adapter validate the logged-in session, in the absence of
realm config?
As you see, there are more questions than answers here. I'm afraid
you're risking to spend major time for minor optimizations. Remember,
"Premature optimization is the root of all evil" (C) Donald Knuth :)
Dmitry
> Thanks again, regards
>
> Andreas.
>
>
>
> Am 2. November 2018 05:45:09 MEZ schrieb Dmitry Telegin <dt at acutus.pr
> o>:
> > Andreas,
> >
> > Could you please elaborate on the nature of the resources your JSF
> > is accessing?
> >
> > If those are static images/CSS/etc. and they do not require
> > authentication, you can simply return new KeycloakDeployment(), a
> > dummy unconfigured instance (you can't return null from the
> > resolver as it will result in an NPE).
> >
> > If those are REST resources that need authentication, you'll
> > probably need to propagate kId somehow to that services, like in a
> > HTTP header or URL param, and process it in the resolver.
> >
> > Good luck,
> > Dmitry
> >
> > On Fri, 2018-11-02 at 02:28 +0000, Andreas Lau wrote:
> > > Hey,
> > > I forgot to bounce back to the list. Sorry
> > > > Von: Andreas Lau <andreas.lau at outlook.com>
> > > Gesendet: 30. Oktober 2018 23:08:06 MEZ
> > > > An: Dmitry Telegin <dt at acutus.pro>
> > > Betreff: Re: [keycloak-user] JBoss EAP 7.0 - keycloak-wildfly-
> > > adapter-dist-4.3.0.Final - KeycloakConfigResolver called on
> > > unprotected Resources
> > >
> > > Hello Dmitry,
> > >
> > > thanks for your response and informations. My problem with that
> > > many calls of the resolve methode was not a performance concern
> > > in first place. I was surprised for sure and I did indeed thought
> > > that I mad a mistake somewhere following the instructions.
> > >
> > > As you pointed out the behavior is not wrong. The resolver should
> > > be called that many times. That's OK I'm fine with this.
> > > The first call to the jsf page is not a problem at all, because
> > > in the URL we have set the parameter who determines which
> > > keycloak.json file has to be used. But I have a problem at the
> > > time where the jsf loading process starts to load the resources.
> > > It fires get request with the URL to the resources the jsf needs.
> > > But now I have lost my scope because the URL used to load the
> > > resource has no identifier in it. How should I determine which
> > > keycloak.json I should take?
> > >
> > > Cheers,
> > > Andreas
> > >
> > > Am 30. Oktober 2018 06:29:56 MEZ schrieb Dmitry Telegin <dt at acutu
> > > s.pro>:
> > >
> > > Hello Andreas,
> > >
> > > I'm afraid this is by design - one of the reasons may be Java EE
> > > programmatic security [1], where the application can instigate
> > > login even from the resources not protected by web.xml security
> > > constraints.
> > >
> > > But I don't think you should be bothered - in your resolver,
> > > there is a cache for KeycloakDeployments, and cache calls are
> > > cheap (and you will always have a cache hit, except for the very
> > > first invocation).
> > >
> > > Even if there had been the code to determine whether the resolver
> > > should or should not kick in, according to web.xml rules, - this
> > > code would have been more expensive, let alone it would have
> > > broken programmatic security. If you are super determined, you
> > > can craft a simple performance test using e.g. Gatling [2] - I'm
> > > pretty sure the results for resolver vs. no resolver will differ
> > > insignificantly.
> > >
> > > [1] https://docs.oracle.com/javaee/7/tutorial/security-webtier003
> > > .htm
> > > [2] https://gatling.io/
> > >
> > > Cheers,
> > > Dmitry Telegin
> > > CTO, Acutus s.r.o.
> > > Keycloak Consulting and Training
> > >
> > > Pod lipami street 339/52, 130 00 Prague 3, Czech Republic
> > > +42 (022) 888-30-71
> > > E-mail: info at acutus.pro
> > >
> > > On Sat, 2018-10-27 at 07:21 +0000, Andreas Lau wrote:
> > > Hey guys, sorry for bouncing that topic again, but this issue
> > > currently is a show stopper for us. We need to have multi-tenancy
> > > for our application, but as it works now it is not feasible.
> > > So we desparatly ask for your help.
> > >
> > > Am 24. Oktober 2018 17:16:23 MESZ schrieb Andreas Lau <andreas.la
> > > u at outlook.com>:
> > >
> > > Hello,
> > > we deployed a jsf primfaces application on a JBoss EAP 7.0
> > > System. We have to support multiple clients using multi tenancy.
> > > We followed the instructions of the documentation [1] to build up
> > > a CustomKeycloakConfigResolver.
> > > We configured the web.xml like this:
> > > [web.xml]
> > > <web-app>
> > > ...
> > > <security-constraint>
> > > <web-resource-collection>
> > > <web-resource-name>portal</web-resource-name>
> > > <url-pattern>/portal/*</url-pattern>
> > > </web-resource-collection>
> > > <auth-constraint>
> > > <role-name>user</role-name>
> > > </auth-constraint>
> > > </security-constraint>
> > > <security-constraint>
> > > <web-resource-collection>
> > > <web-resource-name>public</web-resource-name>
> > > <url-pattern>/portal/pages/willkommen.jsf</url-pattern>
> > > <url-pattern>/portal/pages/logout.jsf</url-pattern>
> > > </web-resource-collection>
> > > </security-constraint>
> > >
> > > <login-config>
> > > <auth-method>KEYCLOAK</auth-method>
> > > </login-config>
> > >
> > > <security-role>
> > > <role-name>user</role-name>
> > > </security-role>
> > > ...
> > > <context-param>
> > > <param-name>keycloak.config.resolver</param-name>
> > > <param-
> > > value>de.sample.security.MandantBasedKeycloakConfigResolver</para
> > > m-value>
> > > </context-param>
> > > ...
> > > </web-app>
> > >
> > > As you can see everything under portal is restricted with two
> > > exceptions. The code of MandantBasedKeycloakConfigResolver is
> > > straight forward and adapted to the example code [2]. In our
> > > example we consider that the url has a query parameter that
> > > provides an id which we can map to a corresponding keycloak.json
> > > file. A sample would be "https://localhost:8443/SampleApp/portal/
> > > pages/willkommen.jsf?kId=1".
> > >
> > > After deployment I realized, that the KeycloakConfigResolver is
> > > called 44 times (see log entries [3]). As it turns out the
> > > KeycloakConfigResolver.resolve() methode is called for every
> > > resource that is loaded through get requests to display the site.
> > > I did not expect that many invocation, since the resources are
> > > not protected.
> > >
> > > Can you please tell me if this behaviour is correct? What is my
> > > error in adopting the mulity tenancy sample? How can we
> > > prevent/workaround that many calls?
> > > While researching I found a jira https://issues.jboss.org/browse/
> > > KEYCLOAK-8616 with a potentially similar problem. Here they use
> > > keycloak to secure a spring boot application and have troubles
> > > when a sso redirection occurs.
> > >
> > > Regards,
> > > Andreas
> > >
> > > [1] https://www.keycloak.org/docs/latest/securing_apps/index.html
> > > #_multi_tenancy
> > >
> > > [2] public KeycloakDeployment resolve(HttpFacade.Request request)
> > > {
> > >
> > > LOGGER.debug("MandantBasedKeycloakConfigResolver.resolve(
> > > ) - counter:" + counter++);
> > > final String mandantId = request.getFirstParam("kId");
> > > LOGGER.debug("MandantBasedKeycloakConfigResolver.resolve(
> > > ) - requestFirstParam(kId):" + mandantId);
> > > LOGGER.debug("MandantBasedKeycloakConfigResolver.resolve(
> > > ) - uri:" + request.getURI());
> > >
> > > if (mandantId == null || mandantId.isEmpty()) {
> > > // throw new IllegalStateException("Not able to
> > > resolve realm for parameter kId - Parameter not found!");
> > > return null;
> > > }
> > >
> > > KeycloakDeployment deployment = cache.get(mandantId);
> > > if (deployment == null) {
> > >
> > > String keycloakConfigFilename =
> > > resolveKeycloakConfigFilename(mandantId);
> > >
> > > InputStream is = getClass().getResourceAsStream("/" +
> > > keycloakConfigFilename);
> > > if (is == null) {
> > > // throw new IllegalStateException("Not able to
> > > find the file /" + keycloakConfigFilename);
> > > return null;
> > > }
> > > LOGGER.debug("MandantBasedKeycloakConfigResolver.reso
> > > lve() - is IS==null?:" + (is == null));
> > >
> > > deployment = KeycloakDeploymentBuilder.build(is);
> > > cache.put(mandantId, deployment);
> > > }
> > >
> > > return deployment;
> > > }
> > >
> > > [3]
> > > 17:28:43,281 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() - counter:0
> > > 17:28:50,215 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() -
> > > requestFirstParam(kId):3
> > > 17:28:50,228 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() - uri:https:
> > > //localhost:8443/SampleApp/portal/pages/willkommen.jsf?kId=3
> > > 17:28:50,229 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() - is
> > > IS==null?:false
> > > 17:28:50,496 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() - counter:1
> > > 17:28:50,496 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() -
> > > requestFirstParam(kId):3
> > > 17:28:50,496 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() - uri:https:
> > > //localhost:8443/SampleApp/portal/pages/willkommen.jsf?kId=3
> > > 17:28:50,496 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() - counter:2
> > > 17:28:50,496 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() -
> > > requestFirstParam(kId):3
> > > 17:28:50,496 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-4) MandantBasedKeycloakConfigResolver.resolve() - uri:https:
> > > //localhost:8443/SampleApp/portal/pages/willkommen.jsf?kId=3
> > > 17:28:50,933 INFO [stdout] (default task-4) INIT Willkommen
> > > 17:28:50,933 INFO [stdout] (default task-4) initialized mandant
> > > <<<<<<<<<<<<<
> > >
> > > 17:28:51,168 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-5) MandantBasedKeycloakConfigResolver.resolve() - counter:3
> > > 17:28:51,168 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-5) MandantBasedKeycloakConfigResolver.resolve() -
> > > requestFirstParam(kId):null
> > > 17:28:51,168 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-5) MandantBasedKeycloakConfigResolver.resolve() - uri:https:
> > > //localhost:8443/SampleApp/javax.faces.resource/components.css.js
> > > f;jsessionid=6YidBEhtdxxI3NAASHOPab5bdBN_JAOjgqf8qHeh.localhost?l
> > > n=primefaces&v=6.1
> > > 17:28:51,168 ERROR [io.undertow.request] (default task-5)
> > > UT005023: Exception handling request to
> > > /SampleApp/javax.faces.resource/components.css.jsf;jsessionid=6Yi
> > > dBEhtdxxI3NAASHOPab5bdBN_JAOjgqf8qHeh.localhost:
> > > java.lang.IllegalStateException: Not able to resolve realm for
> > > parameter kId - Parameter not found!
> > > at
> > > de.sample.security.MandantBasedKeycloakConfigResolver.resolve(Man
> > > dantBasedKeycloakConfigResolver.java:46) [classes:]
> > > at
> > > org.keycloak.adapters.AdapterDeploymentContext.resolveDeployment(
> > > AdapterDeploymentContext.java:88) [keycloak-adapter-core-
> > > 4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > org.keycloak.adapters.PreAuthActionsHandler.preflightCors(PreAuth
> > > ActionsHandler.java:107) [keycloak-adapter-core-
> > > 4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > org.keycloak.adapters.PreAuthActionsHandler.handleRequest(PreAuth
> > > ActionsHandler.java:79) [keycloak-adapter-core-
> > > 4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > org.keycloak.adapters.undertow.ServletPreAuthActionsHandler.handl
> > > eRequest(ServletPreAuthActionsHandler.java:68) [keycloak-
> > > undertow-adapter-4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > io.undertow.server.handlers.PredicateHandler.handleRequest(Predic
> > > ateHandler.java:43) [undertow-core-1.3.31.Final-redhat-
> > > 3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler.handleFirstReq
> > > uest(ServletInitialHandler.java:285) [undertow-servlet-
> > > 1.3.31.Final-redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler.dispatchReques
> > > t(ServletInitialHandler.java:264) [undertow-servlet-1.3.31.Final-
> > > redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler.access$000(Ser
> > > vletInitialHandler.java:81) [undertow-servlet-1.3.31.Final-
> > > redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler$1.handleReques
> > > t(ServletInitialHandler.java:175) [undertow-servlet-1.3.31.Final-
> > > redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.server.Connectors.executeRootHandler(Connectors.java:
> > > 324) [undertow-core-1.3.31.Final-redhat-3.jar:1.3.31.Final-
> > > redhat-3]
> > > at
> > > io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.ja
> > > va:803) [undertow-core-1.3.31.Final-redhat-3.jar:1.3.31.Final-
> > > redhat-3]
> > > at
> > > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecu
> > > tor.java:1142) [rt.jar:1.8.0_112]
> > > at
> > > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExec
> > > utor.java:617) [rt.jar:1.8.0_112]
> > > at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_112]
> > >
> > > .......
> > >
> > > 17:28:51,824 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-50) MandantBasedKeycloakConfigResolver.resolve() -
> > > counter:43
> > > 17:28:51,825 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-50) MandantBasedKeycloakConfigResolver.resolve() -
> > > requestFirstParam(kId):null
> > > 17:28:51,825 DEBUG
> > > [de.sample.security.MandantBasedKeycloakConfigResolver] (default
> > > task-50) MandantBasedKeycloakConfigResolver.resolve() - uri:https
> > > ://localhost:8443/SampleApp/javax.faces.resource/customJs/customJ
> > > avaScript.js.jsf;jsessionid=6YidBEhtdxxI3NAASHOPab5bdBN_JAOjgqf8q
> > > Heh.localhost?ln=ultima-layout
> > > 17:28:51,825 ERROR [io.undertow.request] (default task-50)
> > > UT005023: Exception handling request to
> > > /SampleApp/javax.faces.resource/customJs/customJavaScript.js.jsf;
> > > jsessionid=6YidBEhtdxxI3NAASHOPab5bdBN_JAOjgqf8qHeh.localhost:
> > > java.lang.IllegalStateException: Not able to resolve realm for
> > > parameter kId - Parameter not found!
> > > at
> > > de.sample.security.MandantBasedKeycloakConfigResolver.resolve(Man
> > > dantBasedKeycloakConfigResolver.java:46) [classes:]
> > > at
> > > org.keycloak.adapters.AdapterDeploymentContext.resolveDeployment(
> > > AdapterDeploymentContext.java:88) [keycloak-adapter-core-
> > > 4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > org.keycloak.adapters.PreAuthActionsHandler.preflightCors(PreAuth
> > > ActionsHandler.java:107) [keycloak-adapter-core-
> > > 4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > org.keycloak.adapters.PreAuthActionsHandler.handleRequest(PreAuth
> > > ActionsHandler.java:79) [keycloak-adapter-core-
> > > 4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > org.keycloak.adapters.undertow.ServletPreAuthActionsHandler.handl
> > > eRequest(ServletPreAuthActionsHandler.java:68) [keycloak-
> > > undertow-adapter-4.0.0.Final.jar:4.0.0.Final]
> > > at
> > > io.undertow.server.handlers.PredicateHandler.handleRequest(Predic
> > > ateHandler.java:43) [undertow-core-1.3.31.Final-redhat-
> > > 3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler.handleFirstReq
> > > uest(ServletInitialHandler.java:285) [undertow-servlet-
> > > 1.3.31.Final-redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler.dispatchReques
> > > t(ServletInitialHandler.java:264) [undertow-servlet-1.3.31.Final-
> > > redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler.access$000(Ser
> > > vletInitialHandler.java:81) [undertow-servlet-1.3.31.Final-
> > > redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.servlet.handlers.ServletInitialHandler$1.handleReques
> > > t(ServletInitialHandler.java:175) [undertow-servlet-1.3.31.Final-
> > > redhat-3.jar:1.3.31.Final-redhat-3]
> > > at
> > > io.undertow.server.Connectors.executeRootHandler(Connectors.java:
> > > 324) [undertow-core-1.3.31.Final-redhat-3.jar:1.3.31.Final-
> > > redhat-3]
> > > at
> > > io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.ja
> > > va:803) [undertow-core-1.3.31.Final-redhat-3.jar:1.3.31.Final-
> > > redhat-3]
> > > at
> > > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecu
> > > tor.java:1142) [rt.jar:1.8.0_112]
> > > at
> > > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExec
> > > utor.java:617) [rt.jar:1.8.0_112]
> > > at java.lang.Thread.run(Thread.java:745)
> > > [rt.jar:1.8.0_112]keycloak-user mailing list
> > > keycloak-user at lists.jboss.org
> > > https://lists.jboss.org/mailman/listinfo/keycloak-userkeycloak-us
> > > er mailing list
> > > keycloak-user at lists.jboss.org
> > > https://lists.jboss.org/mailman/listinfo/keycloak-userkeycloak-us
> > > er mailing list
> > > keycloak-user at lists.jboss.org
> > > https://lists.jboss.org/mailman/listinfo/keycloak-user
>
>
>
More information about the keycloak-user
mailing list