From romain.poiffaut at elca.ch Fri Nov 2 04:55:34 2018 From: romain.poiffaut at elca.ch (Poiffaut Romain) Date: Fri, 2 Nov 2018 08:55:34 +0000 Subject: [keycloak-dev] Keycloak with CockroachDB Message-ID: <3518a39d213249c39c7a33b446a7ca9a@elca.ch> Hello, For the Cloudtrust project (https://github.com/cloudtrust), I have investigated the feasibility of supporting CockroachDB in Keycloak. I have created a fork based on Keycloak 3.4.3 (it was the latest version when I started on this) working with CockroachDB 2.0.2. It is now working with this DB, and passes all unit tests. Some resilience tests have also been performed to validate the whole integration. Address of the repo : https://github.com/cloudtrust/keycloak/tree/cockroach-db For those who might be interested, here are some details: CockroachDB is a multi-master SQL database designed to run in the cloud and being resilient to failures (https://www.cockroachlabs.com/). This database has a lot of very interesting properties such as being lockless, distributed and supporting serializable isolation. CockroachDB introduces the notion of SAVEPOINT. As this DB is lockless, a transaction may fail due to a concurrent transaction. In such case, we can rollback to the SAVEPOINT and retry the transaction. Retrying transactions has the benefit of increasing their priority each time they are retried, thus increasing their likelihood to succeed. (More detailed information are available in their very good documentation (e.g. https://www.cockroachlabs.com/docs/stable/transactions.html#client-side-transaction-retries, https://www.cockroachlabs.com/blog/how-cockroachdb-distributes-atomic-transactions/, https://www.cockroachlabs.com/blog/serializable-lockless-distributed-isolation-cockroachdb/ )) So even if CockroachDB uses PostgreSQL driver to communicate with the DB, one of the challenges was to add an automatic transaction retry mechanism with the smallest impact on Keycloak. Thanks to the architecture of Keycloak, this mechanism can be added in KeycloakSessionServletFilter with a very limited impact. A second challenge is due to the rollbackOnly mechanism implemented in Keycloak and Hibernate: after a rollback, a transaction cannot be used anymore. The retry operation must be performed in the same transaction to increase its priority. Thus the rollbackOnly mechanism is disabled/bypassed in order to keep the transaction active even after a rollback is issued. As suggested by CockroachDB, we replace the default Hibernate transaction coordinator class to a custom one (https://github.com/cockroachdb/hibernate-savepoint-fix). Moreover, we mainly modify JpaKeycloakTransaction so that if the transaction fails to commit due to retryable transaction error, we disable the rollbackOnly mechansim to able to retry the transaction. CockroachDB does not support addition of some constraints (e.g. primary keys) after table creation. To circumvent this limitation, we can create a new table, migrate the data, delete the old table, rename the new table with the correct name. As CockroachDb was not supported by Keycloak until now, we didn?t adapt all existing liquibase scripts. We decided to create a new liquibase script which creates the whole database schema for the current version. This current limitation is being discussed and will be fixed in future release (https://github.com/cockroachdb/cockroach/issues/19141). Some tests have also been slightly adapted to support SERIALIZABLE isolation, so other DBs configured with such level can also benefit from this adaptation (i.e. PostgreSQL) These challenges have been solved and our forked version of Keycloak is now compatible with CockroachDB, but it currently is at the cost of breaking the usage of standard databases. Our company is really interested to add the support of this DB into Keycloak and to provide it to the community. The next steps now would be to migrate our fork to the latest version of Keycloak and add the support of this DB without breaking support of the others and we would be happy to discuss it. Cheers, Romain Poiffaut From psilva at redhat.com Fri Nov 2 06:59:54 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Fri, 2 Nov 2018 07:59:54 -0300 Subject: [keycloak-dev] Keycloak with CockroachDB In-Reply-To: <3518a39d213249c39c7a33b446a7ca9a@elca.ch> References: <3518a39d213249c39c7a33b446a7ca9a@elca.ch> Message-ID: Interesting, didn't know about CockroachDB. It seems your arguments and requirements to support this database are based on its cloud-native nature and capabilities. I think I understand some of the reasons behind this proposal. But how much it adds to Keycloak architecture that could justify the changes/efforts you mentioned considering that, even with current limitation of a single master database, we do hava a cache layer on top of the database already managing clustering and enabling cloud deployment ? Regard. Pedro Igor Em sex, 2 de nov de 2018 05:58, Poiffaut Romain Hello, > > For the Cloudtrust project (https://github.com/cloudtrust), I have > investigated the feasibility of supporting CockroachDB in Keycloak. > > I have created a fork based on Keycloak 3.4.3 (it was the latest version > when I started on this) working with CockroachDB 2.0.2. It is now working > with this DB, and passes all unit tests. Some resilience tests have also > been performed to validate the whole integration. > Address of the repo : > https://github.com/cloudtrust/keycloak/tree/cockroach-db > > For those who might be interested, here are some details: > > CockroachDB is a multi-master SQL database designed to run in the cloud > and being resilient to failures (https://www.cockroachlabs.com/). > This database has a lot of very interesting properties such as being > lockless, distributed and supporting serializable isolation. > CockroachDB introduces the notion of SAVEPOINT. As this DB is lockless, a > transaction may fail due to a concurrent transaction. In such case, we can > rollback to the SAVEPOINT and retry the transaction. Retrying transactions > has the benefit of increasing their priority each time they are retried, > thus increasing their likelihood to succeed. (More detailed information are > available in their very good documentation (e.g. > https://www.cockroachlabs.com/docs/stable/transactions.html#client-side-transaction-retries, > > https://www.cockroachlabs.com/blog/how-cockroachdb-distributes-atomic-transactions/, > > https://www.cockroachlabs.com/blog/serializable-lockless-distributed-isolation-cockroachdb/ > )) > > So even if CockroachDB uses PostgreSQL driver to communicate with the DB, > one of the challenges was to add an automatic transaction retry mechanism > with the smallest impact on Keycloak. > Thanks to the architecture of Keycloak, this mechanism can be added in > KeycloakSessionServletFilter with a very limited impact. > > A second challenge is due to the rollbackOnly mechanism implemented in > Keycloak and Hibernate: after a rollback, a transaction cannot be used > anymore. > The retry operation must be performed in the same transaction to increase > its priority. > Thus the rollbackOnly mechanism is disabled/bypassed in order to keep the > transaction active even after a rollback is issued. > As suggested by CockroachDB, we replace the default Hibernate transaction > coordinator class to a custom one ( > https://github.com/cockroachdb/hibernate-savepoint-fix). > Moreover, we mainly modify JpaKeycloakTransaction so that if the > transaction fails to commit due to retryable transaction error, we disable > the rollbackOnly mechansim to able to retry the transaction. > > CockroachDB does not support addition of some constraints (e.g. primary > keys) after table creation. > To circumvent this limitation, we can create a new table, migrate the > data, delete the old table, rename the new table with the correct name. > As CockroachDb was not supported by Keycloak until now, we didn?t adapt > all existing liquibase scripts. We decided to create a new liquibase script > which creates the whole database schema for the current version. > This current limitation is being discussed and will be fixed in future > release (https://github.com/cockroachdb/cockroach/issues/19141). > > Some tests have also been slightly adapted to support SERIALIZABLE > isolation, so other DBs configured with such level can also benefit from > this adaptation (i.e. PostgreSQL) > > These challenges have been solved and our forked version of Keycloak is > now compatible with CockroachDB, but it currently is at the cost of > breaking the usage of standard databases. > Our company is really interested to add the support of this DB into > Keycloak and to provide it to the community. > The next steps now would be to migrate our fork to the latest version of > Keycloak and add the support of this DB without breaking support of the > others and we would be happy to discuss it. > > > Cheers, > Romain Poiffaut > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From simonerota at gmail.com Sat Nov 3 20:47:22 2018 From: simonerota at gmail.com (Simone Rota) Date: Sun, 4 Nov 2018 01:47:22 +0100 Subject: [keycloak-dev] Exposing OTP url for frontend customization Message-ID: <581e0458-4c1c-c06f-d61c-b301e0ba8c6e@gmail.com> Hi everybody, It would be really useful for theme development to expose the OTP URL (the one that gets embedded in the QR-Code) in a couple of TotpBeans. This would allow easier customization such as (re)generating a custom QR code client side. Use case: I can append a "image" param to the QR Code URL, so I can provide a custom icon from theme resources to OTP clients such as FreeOTP. AFAIK This can be currently done without changes only in the account page since in the login form there's no info about the user. If this seems interesting I can create a Jira Issue and PR; I attach a patch against 4.5.0-Final anyway since it's a very small one. Regards, Simone Rota From dt at acutus.pro Mon Nov 5 00:25:50 2018 From: dt at acutus.pro (Dmitry Telegin) Date: Mon, 05 Nov 2018 08:25:50 +0300 Subject: [keycloak-dev] The ultimate fate of master realm Message-ID: <1541395550.3650.3.camel@acutus.pro> Hi, The idea of getting rid of master realm has been around for years [1] [2]. Just wanted to know, what's the current stance on this? Can we tell for sure that there still will be master realm in KC 5.0? Or can we tell the opposite? Some background: we're working on a Keycloak extension (provider) that needs to operate a global (non-realm-based) writable config. So I'm choosing between the two options: - store config keys as master realm attributes; - introduce full-fledged configuration system based on Apache Commons Configuration, backed by its own DB table and Infinispan cache. The latter is obviously more complex, however more powerful. I've posted a write-up on it about a year ago [3], but didn't get any feedback. I hope it could be reevaluated today; for Keycloak proper, there are several use cases like auto-update settings, admin email, periodic tasks etc. The former, on the contrary, is much easier to implement, however there is a risk of having to rewrite everything from scratch should master realm bite the dust one day. Cheers, Dmitry Telegin CTO, Acutus s.r.o. [1] http://lists.jboss.org/pipermail/keycloak-dev/2015-December/006066.html [2] https://issues.jboss.org/browse/KEYCLOAK-3443 [3] http://lists.jboss.org/pipermail/keycloak-dev/2017-December/010261.html From sthorger at redhat.com Mon Nov 5 02:24:52 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 5 Nov 2018 08:24:52 +0100 Subject: [keycloak-dev] Turkish translation review needed In-Reply-To: References: Message-ID: Anyone? On Wed, 31 Oct 2018 at 06:37, Stian Thorgersen wrote: > We have a PR for Turkish translations for Keycloak. Can someone from the > community review this please? > > https://github.com/keycloak/keycloak/pull/5678 > From sthorger at redhat.com Mon Nov 5 02:25:05 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 5 Nov 2018 08:25:05 +0100 Subject: [keycloak-dev] Review Latvian translation In-Reply-To: References: Message-ID: Anyone? On Wed, 31 Oct 2018 at 06:36, Stian Thorgersen wrote: > We have a PR for Latvian translations for Keycloak. Can someone from the > community review it please? > > https://github.com/keycloak/keycloak/pull/5676 > From sthorger at redhat.com Mon Nov 5 14:13:36 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 5 Nov 2018 20:13:36 +0100 Subject: [keycloak-dev] The ultimate fate of master realm In-Reply-To: <1541395550.3650.3.camel@acutus.pro> References: <1541395550.3650.3.camel@acutus.pro> Message-ID: It is very unlikely that we will remove the master realm in 5.x. There are already a way to deal with global config which is in standalone.xml. The limitation there currently is that changes require a server restart and we don't have a schema so it's a simple key-value type config. Changes here can be done through jboss-cli and with domain mode you can have these propagated to all nodes in the cluster. At this point we won't consider adding another level of global config like Apache Commons Configuration. On Mon, 5 Nov 2018 at 10:47, Dmitry Telegin
wrote: > Hi, > > The idea of getting rid of master realm has been around for years [1] [2]. > Just wanted to know, what's the current stance on this? Can we tell for > sure that there still will be master realm in KC 5.0? Or can we tell the > opposite? > > Some background: we're working on a Keycloak extension (provider) that > needs to operate a global (non-realm-based) writable config. So I'm > choosing between the two options: > - store config keys as master realm attributes; > - introduce full-fledged configuration system based on Apache Commons > Configuration, backed by its own DB table and Infinispan cache. > > The latter is obviously more complex, however more powerful. I've posted a > write-up on it about a year ago [3], but didn't get any feedback. I hope it > could be reevaluated today; for Keycloak proper, there are several use > cases like auto-update settings, admin email, periodic tasks etc. > > The former, on the contrary, is much easier to implement, however there is > a risk of having to rewrite everything from scratch should master realm > bite the dust one day. > > Cheers, > Dmitry Telegin > CTO, Acutus s.r.o. > > [1] > http://lists.jboss.org/pipermail/keycloak-dev/2015-December/006066.html > [2] https://issues.jboss.org/browse/KEYCLOAK-3443 > [3] > http://lists.jboss.org/pipermail/keycloak-dev/2017-December/010261.html > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From sthorger at redhat.com Mon Nov 5 14:20:27 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 5 Nov 2018 20:20:27 +0100 Subject: [keycloak-dev] Keycloak with CockroachDB In-Reply-To: <3518a39d213249c39c7a33b446a7ca9a@elca.ch> References: <3518a39d213249c39c7a33b446a7ca9a@elca.ch> Message-ID: CockroachDB is not something we will consider including in the core code base at the moment. It is a very high overhead supporting multiple DB and something like CockroachDB that is less like a traditional relational DB will be too much effort for us to consider at this stage. I would suggest that you maintain this as a separate extension, but we can discuss how that can be done. What changes are needed to make this into a drop-in extension that doesn't require a forked Keycloak build for instance. On Fri, 2 Nov 2018 at 09:56, Poiffaut Romain wrote: > Hello, > > For the Cloudtrust project (https://github.com/cloudtrust), I have > investigated the feasibility of supporting CockroachDB in Keycloak. > > I have created a fork based on Keycloak 3.4.3 (it was the latest version > when I started on this) working with CockroachDB 2.0.2. It is now working > with this DB, and passes all unit tests. Some resilience tests have also > been performed to validate the whole integration. > Address of the repo : > https://github.com/cloudtrust/keycloak/tree/cockroach-db > > For those who might be interested, here are some details: > > CockroachDB is a multi-master SQL database designed to run in the cloud > and being resilient to failures (https://www.cockroachlabs.com/). > This database has a lot of very interesting properties such as being > lockless, distributed and supporting serializable isolation. > CockroachDB introduces the notion of SAVEPOINT. As this DB is lockless, a > transaction may fail due to a concurrent transaction. In such case, we can > rollback to the SAVEPOINT and retry the transaction. Retrying transactions > has the benefit of increasing their priority each time they are retried, > thus increasing their likelihood to succeed. (More detailed information are > available in their very good documentation (e.g. > https://www.cockroachlabs.com/docs/stable/transactions.html#client-side-transaction-retries, > > https://www.cockroachlabs.com/blog/how-cockroachdb-distributes-atomic-transactions/, > > https://www.cockroachlabs.com/blog/serializable-lockless-distributed-isolation-cockroachdb/ > )) > > So even if CockroachDB uses PostgreSQL driver to communicate with the DB, > one of the challenges was to add an automatic transaction retry mechanism > with the smallest impact on Keycloak. > Thanks to the architecture of Keycloak, this mechanism can be added in > KeycloakSessionServletFilter with a very limited impact. > This can be achieved with a custom KeycloakTransaction wrapper instead. That way you do not need to modify Keycloak source code. > > A second challenge is due to the rollbackOnly mechanism implemented in > Keycloak and Hibernate: after a rollback, a transaction cannot be used > anymore. > The retry operation must be performed in the same transaction to increase > its priority. > Thus the rollbackOnly mechanism is disabled/bypassed in order to keep the > transaction active even after a rollback is issued. > As suggested by CockroachDB, we replace the default Hibernate transaction > coordinator class to a custom one ( > https://github.com/cockroachdb/hibernate-savepoint-fix). > Moreover, we mainly modify JpaKeycloakTransaction so that if the > transaction fails to commit due to retryable transaction error, we disable > the rollbackOnly mechansim to able to retry the transaction. > We could add an option to the connection provider to allow setting a custom transaction coordinator. > > CockroachDB does not support addition of some constraints (e.g. primary > keys) after table creation. > To circumvent this limitation, we can create a new table, migrate the > data, delete the old table, rename the new table with the correct name. > As CockroachDb was not supported by Keycloak until now, we didn?t adapt > all existing liquibase scripts. We decided to create a new liquibase script > which creates the whole database schema for the current version. > This current limitation is being discussed and will be fixed in future > release (https://github.com/cockroachdb/cockroach/issues/19141). > Not sure how to handle this. If you need to modify Liquibase scripts that pretty much leaves you with having to maintain your own "duplicates". > > Some tests have also been slightly adapted to support SERIALIZABLE > isolation, so other DBs configured with such level can also benefit from > this adaptation (i.e. PostgreSQL) > > These challenges have been solved and our forked version of Keycloak is > now compatible with CockroachDB, but it currently is at the cost of > breaking the usage of standard databases. > Our company is really interested to add the support of this DB into > Keycloak and to provide it to the community. > The next steps now would be to migrate our fork to the latest version of > Keycloak and add the support of this DB without breaking support of the > others and we would be happy to discuss it. > > > Cheers, > Romain Poiffaut > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From dt at acutus.pro Mon Nov 5 17:44:18 2018 From: dt at acutus.pro (Dmitry Telegin) Date: Tue, 06 Nov 2018 01:44:18 +0300 Subject: [keycloak-dev] The ultimate fate of master realm In-Reply-To: References: <1541395550.3650.3.camel@acutus.pro> Message-ID: <1541457858.3123.3.camel@acutus.pro> Hello Stian, On Mon, 2018-11-05 at 20:13 +0100, Stian Thorgersen wrote: > It is very unlikely that we will remove the master realm in 5.x. Glad to hear that, thx for the info > There are already a way to deal with global config which is in standalone.xml. The limitation there currently is that changes require a server restart and we don't have a schema so it's a simple key-value type config. Changes here can be done through jboss-cli and with domain mode you can have these propagated to all nodes in the cluster. At this point we won't consider adding another level of global config like Apache Commons Configuration. I'd also add my 2? to the list of limitations: - it's impossible to?modify configuration in runtime from either Keycloak itself or providers (or is it? DMR maybe?) - in standalone-ha mode, you'll still need to propagate the changes to the nodes somehow. I think for now I'll stick to using master realm attributes. And if Keycloak is about to undergo such a drastic changes, I hope it will be announced in advance so I'll have enough time to port my code. Thanks for clarifications, Dmitry > > > On Mon, 5 Nov 2018 at 10:47, Dmitry Telegin
wrote: > > Hi, > > > > The idea of getting rid of master realm has been around for years [1] [2]. Just wanted to know, what's the current stance on this? Can we tell for sure that there still will be master realm in KC 5.0? Or can we tell the opposite? > > > > Some background: we're working on a Keycloak extension (provider) that needs to operate a global (non-realm-based) writable config. So I'm choosing between the two options: > > - store config keys as master realm attributes; > > - introduce full-fledged configuration system based on Apache Commons Configuration, backed by its own DB table and Infinispan cache. > > > > The latter is obviously more complex, however more powerful. I've posted a write-up on it about a year ago [3], but didn't get any feedback. I hope it could be reevaluated today; for Keycloak proper, there are several use cases like auto-update settings, admin email, periodic tasks etc. > > > > The former, on the contrary, is much easier to implement, however there is a risk of having to rewrite everything from scratch should master realm bite the dust one day. > > > > Cheers, > > Dmitry Telegin > > CTO, Acutus s.r.o. > > > > [1] http://lists.jboss.org/pipermail/keycloak-dev/2015-December/006066.html > > [2] https://issues.jboss.org/browse/KEYCLOAK-3443 > > [3] http://lists.jboss.org/pipermail/keycloak-dev/2017-December/010261.html > > > > _______________________________________________ > > keycloak-dev mailing list > > keycloak-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/keycloak-dev > > From sthorger at redhat.com Tue Nov 6 06:27:51 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Tue, 6 Nov 2018 12:27:51 +0100 Subject: [keycloak-dev] The ultimate fate of master realm In-Reply-To: <1541457858.3123.3.camel@acutus.pro> References: <1541395550.3650.3.camel@acutus.pro> <1541457858.3123.3.camel@acutus.pro> Message-ID: On Mon, 5 Nov 2018 at 23:44, Dmitry Telegin
wrote: > Hello Stian, > > On Mon, 2018-11-05 at 20:13 +0100, Stian Thorgersen wrote: > > It is very unlikely that we will remove the master realm in 5.x. > > Glad to hear that, thx for the info > > > There are already a way to deal with global config which is in > standalone.xml. The limitation there currently is that changes require a > server restart and we don't have a schema so it's a simple key-value type > config. Changes here can be done through jboss-cli and with domain mode you > can have these propagated to all nodes in the cluster. At this point we > won't consider adding another level of global config like Apache Commons > Configuration. > > I'd also add my 2? to the list of limitations: > - it's impossible to modify configuration in runtime from either Keycloak > itself or providers (or is it? DMR maybe?) > It is possible, but not that nice. There is Java libs to interact with DMR. We use it in some tests. > - in standalone-ha mode, you'll still need to propagate the changes to the > nodes somehow. > Yes, that's what domain mode is for really. > > I think for now I'll stick to using master realm attributes. And if > Keycloak is about to undergo such a drastic changes, I hope it will be > announced in advance so I'll have enough time to port my code. > Absolutely - it will be a lengthy discussion and we will keep it the discussion open. So keep monitoring keycloak-dev ;) > > Thanks for clarifications, > Dmitry > > > > > > On Mon, 5 Nov 2018 at 10:47, Dmitry Telegin
wrote: > > > Hi, > > > > > > The idea of getting rid of master realm has been around for years [1] > [2]. Just wanted to know, what's the current stance on this? Can we tell > for sure that there still will be master realm in KC 5.0? Or can we tell > the opposite? > > > > > > Some background: we're working on a Keycloak extension (provider) that > needs to operate a global (non-realm-based) writable config. So I'm > choosing between the two options: > > > - store config keys as master realm attributes; > > > - introduce full-fledged configuration system based on Apache Commons > Configuration, backed by its own DB table and Infinispan cache. > > > > > > The latter is obviously more complex, however more powerful. I've > posted a write-up on it about a year ago [3], but didn't get any feedback. > I hope it could be reevaluated today; for Keycloak proper, there are > several use cases like auto-update settings, admin email, periodic tasks > etc. > > > > > > The former, on the contrary, is much easier to implement, however > there is a risk of having to rewrite everything from scratch should master > realm bite the dust one day. > > > > > > Cheers, > > > Dmitry Telegin > > > CTO, Acutus s.r.o. > > > > > > [1] > http://lists.jboss.org/pipermail/keycloak-dev/2015-December/006066.html > > > [2] https://issues.jboss.org/browse/KEYCLOAK-3443 > > > [3] > http://lists.jboss.org/pipermail/keycloak-dev/2017-December/010261.html > > > > > > _______________________________________________ > > > keycloak-dev mailing list > > > keycloak-dev at lists.jboss.org > > > https://lists.jboss.org/mailman/listinfo/keycloak-dev > > > > From alistair.doswald at elca.ch Tue Nov 6 06:59:40 2018 From: alistair.doswald at elca.ch (Doswald Alistair) Date: Tue, 6 Nov 2018 11:59:40 +0000 Subject: [keycloak-dev] Full implementation of SAML artifact-binding for [JIRA KEYCLOAK-831] Message-ID: <09fb2cbc2ccb4c9caae867c83a650b77@elca.ch> Hello, A couple of weeks ago I submitted a partial implementation of artifact-binding (only AuthnRequests were handled) as a pull request, mostly to have some code review before I proceeded (though I didn't get any feedback). Now I have fully implemented the artifact binding part of SAML. How should I proceed: 1. Should I close the current pull request, and submit a new one with the full code, 2. Should I commit the code on the same fork as I'm currently doing a PR on? It should be adding into the PR and I can update the description to say that it's the full code. Best regards, Alistair From marco.scheuermann at daimler.com Tue Nov 6 07:43:15 2018 From: marco.scheuermann at daimler.com (marco.scheuermann at daimler.com) Date: Tue, 06 Nov 2018 12:43:15 +0000 Subject: [keycloak-dev] Custom REST endpoint - how to make sure that only admins can call it? In-Reply-To: <9B7DA271-0775-4552-92BD-AFEC2D12C191@daimler.com> References: <9B7DA271-0775-4552-92BD-AFEC2D12C191@daimler.com> Message-ID: Using correct dev mailing list... Von: "Scheuermann, Marco (059)" Datum: Dienstag, 6. November 2018 um 13:41 An: "keycloak-dev-bounces at lists.jboss.org" Cc: "Herrmann, David Christian (059)" Betreff: Custom REST endpoint - how to make sure that only admins can call it? Hi Community, we just implemented a custom REST endpoint based on org.keycloak.services.resource.RealmResourceProvider; How can we make sure that only users with admin role can call these endpoints? Due to the fact that it is a SPI implementation, I have not deployment descriptors to configure security for the endpoint... Greetings, Marco If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support. From johannes at kodet.no Tue Nov 6 08:17:32 2018 From: johannes at kodet.no (Johannes Knutsen) Date: Tue, 6 Nov 2018 14:17:32 +0100 Subject: [keycloak-dev] Custom REST endpoint - how to make sure that only admins can call it? In-Reply-To: References: <9B7DA271-0775-4552-92BD-AFEC2D12C191@daimler.com> Message-ID: Hi Marco! I think you should have a look at the AccountRestService, https://github.com/keycloak/keycloak/blob/11374a27078266bebe5239d595796589e78bae9d/services/src/main/java/org/keycloak/services/resources/account/AccountRestService.java, and AccountLoader, https://github.com/keycloak/keycloak/blob/11374a27078266bebe5239d595796589e78bae9d/services/src/main/java/org/keycloak/services/resources/account/AccountLoader.java. This is how role checking is done internally in Keycloak and should work in a custom REST endpoint as well. Typically something like this should be a good start: AuthenticationManager.AuthResult authResult = new AppAuthManager().authenticateBearerToken(session); if (authResult == null) { throw new NotAuthorizedException("Bearer token required"); } Auth auth = new Auth(session.getContext().getRealm(), authResult.getToken(), authResult.getUser(), client, authResult.getSession(), false); The Auth object has several methods to do role checks: auth.hasOneOfAppRole, auth.hasRealmRole, auth.hasClientRole, and auth.hasOneOfRealmRole. Hope this gets you started :) Regards, Johannes Knutsen On Tue, Nov 6, 2018 at 1:45 PM wrote: > > Using correct dev mailing list... > > Von: "Scheuermann, Marco (059)" > Datum: Dienstag, 6. November 2018 um 13:41 > An: "keycloak-dev-bounces at lists.jboss.org" > Cc: "Herrmann, David Christian (059)" > Betreff: Custom REST endpoint - how to make sure that only admins can call it? > > Hi Community, > > we just implemented a custom REST endpoint based on > > > org.keycloak.services.resource.RealmResourceProvider; > > How can we make sure that only users with admin role can call these endpoints? > > Due to the fact that it is a SPI implementation, I have not deployment descriptors to configure security for the endpoint... > > Greetings, > Marco > > If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support. > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From jdennis at redhat.com Tue Nov 6 08:54:15 2018 From: jdennis at redhat.com (John Dennis) Date: Tue, 6 Nov 2018 08:54:15 -0500 Subject: [keycloak-dev] Full implementation of SAML artifact-binding for [JIRA KEYCLOAK-831] In-Reply-To: <09fb2cbc2ccb4c9caae867c83a650b77@elca.ch> References: <09fb2cbc2ccb4c9caae867c83a650b77@elca.ch> Message-ID: On 11/6/18 6:59 AM, Doswald Alistair wrote: > Hello, > > A couple of weeks ago I submitted a partial implementation of artifact-binding (only AuthnRequests were handled) as a pull request, mostly to have some code review before I proceeded (though I didn't get any feedback). > > Now I have fully implemented the artifact binding part of SAML. How should I proceed: I can't comment on handling the pull request but I do want to make sure the "fully implemented" includes both generating and consuming SAML metadata with the newly introduced artifact bindings as well as the ability to specify the artifact binding in the SAML client page of the realm (probably under fine grained SAML endpoints). I believe there are multiple independent code locations that generate metadata (e.g. admin rest API vs. client installation tab in the admin console) so we'll want to make sure all code locations are updated. Historically we've had problems getting consistent metadata. -- John Dennis From romain.poiffaut at elca.ch Tue Nov 6 11:34:00 2018 From: romain.poiffaut at elca.ch (Poiffaut Romain) Date: Tue, 6 Nov 2018 16:34:00 +0000 Subject: [keycloak-dev] Keycloak with CockroachDB In-Reply-To: References: <3518a39d213249c39c7a33b446a7ca9a@elca.ch> Message-ID: CockroachDB is a normal ACID relational SQL database which uses the PostgreSQL driver. The modifications that were necessary are due to the client retry mechanism for conflicting transactions. From our point of view (or perhaps more correctly, for our use cases), its advantages over the currently supported databases for cloud deployment would be sufficient to have it included in the core. However, if you?re willing to introduce changes that allow us to maintain the integration of CockroachDB as a module/extension, we would more than willing to shift our code to make it a separate extension. In this manner, CockroachDB would be usable with Keycloak for anyone who wishes to benefit its use, and if you later decide that it would be beneficial to maintain it in the core, the work to integrate it should be quite low. I?ll try out your suggestions for lessening the dependency to the code, and I?d be happy to discuss the changes that need to be done to make it a drop-in extension. De : Stian Thorgersen Envoy? : lundi 5 novembre 2018 20:20 ? : Poiffaut Romain Cc : keycloak-dev Objet : Re: [keycloak-dev] Keycloak with CockroachDB CockroachDB is not something we will consider including in the core code base at the moment. It is a very high overhead supporting multiple DB and something like CockroachDB that is less like a traditional relational DB will be too much effort for us to consider at this stage. I would suggest that you maintain this as a separate extension, but we can discuss how that can be done. What changes are needed to make this into a drop-in extension that doesn't require a forked Keycloak build for instance. On Fri, 2 Nov 2018 at 09:56, Poiffaut Romain > wrote: Hello, For the Cloudtrust project (https://github.com/cloudtrust), I have investigated the feasibility of supporting CockroachDB in Keycloak. I have created a fork based on Keycloak 3.4.3 (it was the latest version when I started on this) working with CockroachDB 2.0.2. It is now working with this DB, and passes all unit tests. Some resilience tests have also been performed to validate the whole integration. Address of the repo : https://github.com/cloudtrust/keycloak/tree/cockroach-db For those who might be interested, here are some details: CockroachDB is a multi-master SQL database designed to run in the cloud and being resilient to failures (https://www.cockroachlabs.com/). This database has a lot of very interesting properties such as being lockless, distributed and supporting serializable isolation. CockroachDB introduces the notion of SAVEPOINT. As this DB is lockless, a transaction may fail due to a concurrent transaction. In such case, we can rollback to the SAVEPOINT and retry the transaction. Retrying transactions has the benefit of increasing their priority each time they are retried, thus increasing their likelihood to succeed. (More detailed information are available in their very good documentation (e.g. https://www.cockroachlabs.com/docs/stable/transactions.html#client-side-transaction-retries, https://www.cockroachlabs.com/blog/how-cockroachdb-distributes-atomic-transactions/, https://www.cockroachlabs.com/blog/serializable-lockless-distributed-isolation-cockroachdb/ )) So even if CockroachDB uses PostgreSQL driver to communicate with the DB, one of the challenges was to add an automatic transaction retry mechanism with the smallest impact on Keycloak. Thanks to the architecture of Keycloak, this mechanism can be added in KeycloakSessionServletFilter with a very limited impact. This can be achieved with a custom KeycloakTransaction wrapper instead. That way you do not need to modify Keycloak source code. A second challenge is due to the rollbackOnly mechanism implemented in Keycloak and Hibernate: after a rollback, a transaction cannot be used anymore. The retry operation must be performed in the same transaction to increase its priority. Thus the rollbackOnly mechanism is disabled/bypassed in order to keep the transaction active even after a rollback is issued. As suggested by CockroachDB, we replace the default Hibernate transaction coordinator class to a custom one (https://github.com/cockroachdb/hibernate-savepoint-fix). Moreover, we mainly modify JpaKeycloakTransaction so that if the transaction fails to commit due to retryable transaction error, we disable the rollbackOnly mechansim to able to retry the transaction. We could add an option to the connection provider to allow setting a custom transaction coordinator. CockroachDB does not support addition of some constraints (e.g. primary keys) after table creation. To circumvent this limitation, we can create a new table, migrate the data, delete the old table, rename the new table with the correct name. As CockroachDb was not supported by Keycloak until now, we didn?t adapt all existing liquibase scripts. We decided to create a new liquibase script which creates the whole database schema for the current version. This current limitation is being discussed and will be fixed in future release (https://github.com/cockroachdb/cockroach/issues/19141). Not sure how to handle this. If you need to modify Liquibase scripts that pretty much leaves you with having to maintain your own "duplicates". Some tests have also been slightly adapted to support SERIALIZABLE isolation, so other DBs configured with such level can also benefit from this adaptation (i.e. PostgreSQL) These challenges have been solved and our forked version of Keycloak is now compatible with CockroachDB, but it currently is at the cost of breaking the usage of standard databases. Our company is really interested to add the support of this DB into Keycloak and to provide it to the community. The next steps now would be to migrate our fork to the latest version of Keycloak and add the support of this DB without breaking support of the others and we would be happy to discuss it. Cheers, Romain Poiffaut _______________________________________________ keycloak-dev mailing list keycloak-dev at lists.jboss.org https://lists.jboss.org/mailman/listinfo/keycloak-dev From alistair.doswald at elca.ch Wed Nov 7 04:48:00 2018 From: alistair.doswald at elca.ch (Doswald Alistair) Date: Wed, 7 Nov 2018 09:48:00 +0000 Subject: [keycloak-dev] Full implementation of SAML artifact-binding for [JIRA KEYCLOAK-831] In-Reply-To: References: <09fb2cbc2ccb4c9caae867c83a650b77@elca.ch> Message-ID: <6efd6d73924141b59e1e5bea16869860@elca.ch> Hello, The SAML client page has three new options for artifact binding: a slider to force artifact binding (for example if the client doesn't specify HTTP-Artifact in its authnrequest, but we still want artifact binding fort that client), and two new fields in the Fine-grained SAML endpoint configuration: "Artifact binding URL" (for sending the artifact message) and "Artifact Resolution Service" (for sending an ArtifactResolve message). Import will read the "ArtifactResolutionService" and "AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" and fill the two fields in the Fine-grained SAML endpoint configuration correctly. For the metadata however, I see the problem. I have all the artifact-related metadata correctly at http://:/auth/realms//protocol/saml/descriptor, but not in any of the formats on the installation page. At first I thought that it was just a problem on my part, but in fact only the POST endpoints are displayed in the "installation" metadata: Redirect and SOAP endpoints that are at http://:/auth/realms//protocol/saml/descriptor are not in the "installation" metadata (any variant). Is this a more general bug? I am currently building from master. Are there any other metadata sources aside from those two of which I am unaware? I'm not very familiar with the admin REST API, but looking at the overview in the documentation, I didn't find any other obvious way to get SAML metadata. Best regards, Alistair -----Original Message----- From: John Dennis Sent: mardi 6 novembre 2018 14:54 To: Doswald Alistair ; keycloak-dev ; Hynek Mlnarik Subject: Re: [keycloak-dev] Full implementation of SAML artifact-binding for [JIRA KEYCLOAK-831] On 11/6/18 6:59 AM, Doswald Alistair wrote: > Hello, > > A couple of weeks ago I submitted a partial implementation of artifact-binding (only AuthnRequests were handled) as a pull request, mostly to have some code review before I proceeded (though I didn't get any feedback). > > Now I have fully implemented the artifact binding part of SAML. How should I proceed: I can't comment on handling the pull request but I do want to make sure the "fully implemented" includes both generating and consuming SAML metadata with the newly introduced artifact bindings as well as the ability to specify the artifact binding in the SAML client page of the realm (probably under fine grained SAML endpoints). I believe there are multiple independent code locations that generate metadata (e.g. admin rest API vs. client installation tab in the admin console) so we'll want to make sure all code locations are updated. Historically we've had problems getting consistent metadata. -- John Dennis From sthorger at redhat.com Wed Nov 7 07:54:22 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Wed, 7 Nov 2018 13:54:22 +0100 Subject: [keycloak-dev] Keycloak with CockroachDB In-Reply-To: References: <3518a39d213249c39c7a33b446a7ca9a@elca.ch> Message-ID: On Tue, 6 Nov 2018 at 17:34, Poiffaut Romain wrote: > CockroachDB is a normal ACID relational SQL database which uses the > PostgreSQL driver. The modifications that were necessary are due to the > client retry mechanism for conflicting transactions. From our point of view > (or perhaps more correctly, for our use cases), its advantages over the > currently supported databases for cloud deployment would be sufficient to > have it included in the core. > The issue is if support for CockroachDB is added directly to Keycloak and not maintained as an extension it becomes our responsibility to maintain and support it, which we simply don't have capacity to do. > > > However, if you?re willing to introduce changes that allow us to maintain > the integration of CockroachDB as a module/extension, we would more than > willing to shift our code to make it a separate extension. In this manner, > CockroachDB would be usable with Keycloak for anyone who wishes to benefit > its use, and if you later decide that it would be beneficial to maintain it > in the core, the work to integrate it should be quite low. > I would love to get to a point to make it easier to properly have community maintained extensions to Keycloak. That is a great way to provide additional features and capabilities that we do not have the capacity to maintain within the core Keycloak team. So I'm absolutely open to discussions around how this can be improved and simplified. > > > > I?ll try out your suggestions for lessening the dependency to the code, > and I?d be happy to discuss the changes that need to be done to make it a > drop-in extension. > > > > > > *De :* Stian Thorgersen > *Envoy? :* lundi 5 novembre 2018 20:20 > *? :* Poiffaut Romain > *Cc :* keycloak-dev > *Objet :* Re: [keycloak-dev] Keycloak with CockroachDB > > > > CockroachDB is not something we will consider including in the core code > base at the moment. It is a very high overhead supporting multiple DB and > something like CockroachDB that is less like a traditional relational DB > will be too much effort for us to consider at this stage. > > > > I would suggest that you maintain this as a separate extension, but we can > discuss how that can be done. What changes are needed to make this into a > drop-in extension that doesn't require a forked Keycloak build for instance. > > On Fri, 2 Nov 2018 at 09:56, Poiffaut Romain > wrote: > > Hello, > > For the Cloudtrust project (https://github.com/cloudtrust), I have > investigated the feasibility of supporting CockroachDB in Keycloak. > > I have created a fork based on Keycloak 3.4.3 (it was the latest version > when I started on this) working with CockroachDB 2.0.2. It is now working > with this DB, and passes all unit tests. Some resilience tests have also > been performed to validate the whole integration. > Address of the repo : > https://github.com/cloudtrust/keycloak/tree/cockroach-db > > For those who might be interested, here are some details: > > CockroachDB is a multi-master SQL database designed to run in the cloud > and being resilient to failures (https://www.cockroachlabs.com/). > This database has a lot of very interesting properties such as being > lockless, distributed and supporting serializable isolation. > CockroachDB introduces the notion of SAVEPOINT. As this DB is lockless, a > transaction may fail due to a concurrent transaction. In such case, we can > rollback to the SAVEPOINT and retry the transaction. Retrying transactions > has the benefit of increasing their priority each time they are retried, > thus increasing their likelihood to succeed. (More detailed information are > available in their very good documentation (e.g. > https://www.cockroachlabs.com/docs/stable/transactions.html#client-side-transaction-retries, > > https://www.cockroachlabs.com/blog/how-cockroachdb-distributes-atomic-transactions/, > > https://www.cockroachlabs.com/blog/serializable-lockless-distributed-isolation-cockroachdb/ > )) > > So even if CockroachDB uses PostgreSQL driver to communicate with the DB, > one of the challenges was to add an automatic transaction retry mechanism > with the smallest impact on Keycloak. > Thanks to the architecture of Keycloak, this mechanism can be added in > KeycloakSessionServletFilter with a very limited impact. > > > > This can be achieved with a custom KeycloakTransaction wrapper instead. > That way you do not need to modify Keycloak source code. > > > > > A second challenge is due to the rollbackOnly mechanism implemented in > Keycloak and Hibernate: after a rollback, a transaction cannot be used > anymore. > The retry operation must be performed in the same transaction to increase > its priority. > Thus the rollbackOnly mechanism is disabled/bypassed in order to keep the > transaction active even after a rollback is issued. > As suggested by CockroachDB, we replace the default Hibernate transaction > coordinator class to a custom one ( > https://github.com/cockroachdb/hibernate-savepoint-fix). > Moreover, we mainly modify JpaKeycloakTransaction so that if the > transaction fails to commit due to retryable transaction error, we disable > the rollbackOnly mechansim to able to retry the transaction. > > > > We could add an option to the connection provider to allow setting a > custom transaction coordinator. > > > > > CockroachDB does not support addition of some constraints (e.g. primary > keys) after table creation. > To circumvent this limitation, we can create a new table, migrate the > data, delete the old table, rename the new table with the correct name. > As CockroachDb was not supported by Keycloak until now, we didn?t adapt > all existing liquibase scripts. We decided to create a new liquibase script > which creates the whole database schema for the current version. > This current limitation is being discussed and will be fixed in future > release (https://github.com/cockroachdb/cockroach/issues/19141). > > > > Not sure how to handle this. If you need to modify Liquibase scripts that > pretty much leaves you with having to maintain your own "duplicates". > > > > > Some tests have also been slightly adapted to support SERIALIZABLE > isolation, so other DBs configured with such level can also benefit from > this adaptation (i.e. PostgreSQL) > > These challenges have been solved and our forked version of Keycloak is > now compatible with CockroachDB, but it currently is at the cost of > breaking the usage of standard databases. > Our company is really interested to add the support of this DB into > Keycloak and to provide it to the community. > The next steps now would be to migrate our fork to the latest version of > Keycloak and add the support of this DB without breaking support of the > others and we would be happy to discuss it. > > > Cheers, > Romain Poiffaut > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > > From jdennis at redhat.com Wed Nov 7 08:28:47 2018 From: jdennis at redhat.com (John Dennis) Date: Wed, 7 Nov 2018 08:28:47 -0500 Subject: [keycloak-dev] Full implementation of SAML artifact-binding for [JIRA KEYCLOAK-831] In-Reply-To: <6efd6d73924141b59e1e5bea16869860@elca.ch> References: <09fb2cbc2ccb4c9caae867c83a650b77@elca.ch> <6efd6d73924141b59e1e5bea16869860@elca.ch> Message-ID: <017bd320-8de4-c0bb-915d-a28754583854@redhat.com> On 11/7/18 4:48 AM, Doswald Alistair wrote: > Hello, > > The SAML client page has three new options for artifact binding: a > slider to force artifact binding (for example if the client doesn't > specify HTTP-Artifact in its authnrequest, but we still want artifact > binding fort that client), and two new fields in the Fine-grained > SAML endpoint configuration: "Artifact binding URL" (for sending the > artifact message) and "Artifact Resolution Service" (for sending an > ArtifactResolve message). > > Import will read the "ArtifactResolutionService" and > "AssertionConsumerService > Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" and fill > the two fields in the Fine-grained SAML endpoint configuration > correctly. Thank you, that sounds great. > For the metadata however, I see the problem. I have all the > artifact-related metadata correctly at > http://:/auth/realms//protocol/saml/descriptor, > but not in any of the formats on the installation page. At first I > thought that it was just a problem on my part, but in fact only the > POST endpoints are displayed in the "installation" metadata: Redirect > and SOAP endpoints that are at > http://:/auth/realms//protocol/saml/descriptor are > not in the "installation" metadata (any variant). Is this a more > general bug? I am currently building from master. > > Are there any other metadata sources aside from those two of which I > am unaware? I'm not very familiar with the admin REST API, but > looking at the overview in the documentation, I didn't find any > other obvious way to get SAML metadata. The /auth/realms//protocol/saml/descriptor REST API and the client installation tab in the admin console are the only two I'm aware of. But I'm not a Keycloak dev so I can't say for sure if any others might be lurking. Several years ago I looked at the source code for generating metadata and REST endpoint and the client installation tab used two different implementations instead of common code as I recall. > Best regards, > > Alistair > > -----Original Message----- From: John Dennis > Sent: mardi 6 novembre 2018 14:54 To: Doswald Alistair > ; keycloak-dev > ; Hynek Mlnarik > Subject: Re: [keycloak-dev] Full implementation of SAML > artifact-binding for [JIRA KEYCLOAK-831] > > On 11/6/18 6:59 AM, Doswald Alistair wrote: >> Hello, >> >> A couple of weeks ago I submitted a partial implementation of >> artifact-binding (only AuthnRequests were handled) as a pull >> request, mostly to have some code review before I proceeded >> (though I didn't get any feedback). >> >> Now I have fully implemented the artifact binding part of SAML. How >> should I proceed: > > I can't comment on handling the pull request but I do want to make > sure the "fully implemented" includes both generating and consuming > SAML metadata with the newly introduced artifact bindings as well as > the ability to specify the artifact binding in the SAML client page > of the realm (probably under fine grained SAML endpoints). I believe > there are multiple independent code locations that generate metadata > (e.g. admin rest API vs. client installation tab in the admin > console) so we'll want to make sure all code locations are updated. > Historically we've had problems getting consistent metadata. > > > -- John Dennis > -- John Dennis From bruno at abstractj.org Thu Nov 8 01:23:22 2018 From: bruno at abstractj.org (Bruno Oliveira) Date: Thu, 8 Nov 2018 04:23:22 -0200 Subject: [keycloak-dev] Cron jobs for the quickstarts Message-ID: Good morning, while I was fixing the quickstarts build I was thinking about having a daily cron job to build master. The reason why I would like to do this is to get breaking changes from Keycloak server early. The way how we do today is counterproductive from my point of view, because we only know that things are broken when someone submits a PR. Thoughts? -- - abstractj From psilva at redhat.com Thu Nov 8 07:01:25 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Thu, 8 Nov 2018 10:01:25 -0200 Subject: [keycloak-dev] Cron jobs for the quickstarts In-Reply-To: References: Message-ID: +1 On Thu, Nov 8, 2018 at 4:26 AM Bruno Oliveira wrote: > Good morning, while I was fixing the quickstarts build I was thinking > about having a daily cron job to build master. The reason why I would > like to do this is to get breaking changes from Keycloak server early. > > The way how we do today is counterproductive from my point of view, > because we only know that things are broken when someone submits a PR. > > Thoughts? > > -- > - abstractj > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From slaskawi at redhat.com Thu Nov 8 07:06:16 2018 From: slaskawi at redhat.com (Sebastian Laskawiec) Date: Thu, 8 Nov 2018 13:06:16 +0100 Subject: [keycloak-dev] Cron jobs for the quickstarts In-Reply-To: References: Message-ID: +1. I think you can configure Travis to do daily jobs... On Thu, Nov 8, 2018 at 1:04 PM Pedro Igor Silva wrote: > +1 > > On Thu, Nov 8, 2018 at 4:26 AM Bruno Oliveira wrote: > > > Good morning, while I was fixing the quickstarts build I was thinking > > about having a daily cron job to build master. The reason why I would > > like to do this is to get breaking changes from Keycloak server early. > > > > The way how we do today is counterproductive from my point of view, > > because we only know that things are broken when someone submits a PR. > > > > Thoughts? > > > > -- > > - abstractj > > _______________________________________________ > > keycloak-dev mailing list > > keycloak-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/keycloak-dev > > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From bruno at abstractj.org Thu Nov 8 07:20:45 2018 From: bruno at abstractj.org (Bruno Oliveira) Date: Thu, 8 Nov 2018 10:20:45 -0200 Subject: [keycloak-dev] Cron jobs for the quickstarts In-Reply-To: References: Message-ID: Yay, I think we do have a consensus of 3 :) Cron will be scheduled only for 'master', we gonna leave the branch 'latest' as is. On Thu, Nov 8, 2018 at 10:06 AM Sebastian Laskawiec wrote: > > +1. I think you can configure Travis to do daily jobs... > > On Thu, Nov 8, 2018 at 1:04 PM Pedro Igor Silva wrote: >> >> +1 >> >> On Thu, Nov 8, 2018 at 4:26 AM Bruno Oliveira wrote: >> >> > Good morning, while I was fixing the quickstarts build I was thinking >> > about having a daily cron job to build master. The reason why I would >> > like to do this is to get breaking changes from Keycloak server early. >> > >> > The way how we do today is counterproductive from my point of view, >> > because we only know that things are broken when someone submits a PR. >> > >> > Thoughts? >> > >> > -- >> > - abstractj >> > _______________________________________________ >> > keycloak-dev mailing list >> > keycloak-dev at lists.jboss.org >> > https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev -- - abstractj From asaldanha1947 at gmail.com Thu Nov 8 11:15:00 2018 From: asaldanha1947 at gmail.com (Anil Saldanha) Date: Thu, 8 Nov 2018 10:15:00 -0600 Subject: [keycloak-dev] Order of Protocol Mappers Message-ID: Hi all, quick question. If a bunch of protocol mappers have been written and listed in META-INF/services, is there a way to show them in alphabetical order in the UI? Regards, Anil From psilva at redhat.com Thu Nov 8 11:29:05 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Thu, 8 Nov 2018 14:29:05 -0200 Subject: [keycloak-dev] Order of Protocol Mappers In-Reply-To: References: Message-ID: Hey Anil! I don't think so, tables are sorted by priority in angular. Regards. Pedro Igor On Thu, Nov 8, 2018 at 2:21 PM Anil Saldanha wrote: > Hi all, > quick question. If a bunch of protocol mappers have been written and > listed in META-INF/services, is there a way to show them in alphabetical > order in the UI? > > Regards, > Anil > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From asaldanha1947 at gmail.com Thu Nov 8 11:57:37 2018 From: asaldanha1947 at gmail.com (Anil Saldanha) Date: Thu, 8 Nov 2018 10:57:37 -0600 Subject: [keycloak-dev] Order of Protocol Mappers In-Reply-To: References: Message-ID: Thank you Pedro. Could you provide a link to the Angular file? > On Nov 8, 2018, at 10:29 AM, Pedro Igor Silva wrote: > > Hey Anil! > > I don't think so, tables are sorted by priority in angular. > > Regards. > Pedro Igor > >> On Thu, Nov 8, 2018 at 2:21 PM Anil Saldanha wrote: >> Hi all, >> quick question. If a bunch of protocol mappers have been written and >> listed in META-INF/services, is there a way to show them in alphabetical >> order in the UI? >> >> Regards, >> Anil >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev From psilva at redhat.com Thu Nov 8 12:43:17 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Thu, 8 Nov 2018 15:43:17 -0200 Subject: [keycloak-dev] Order of Protocol Mappers In-Reply-To: References: Message-ID: https://github.com/keycloak/keycloak/blob/2a4cee60440be6767e0f1e9155cebfa381cfb776/themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html#L40 There are similar pages in other places where mappers are used. On Thu, Nov 8, 2018 at 2:57 PM Anil Saldanha wrote: > Thank you Pedro. Could you provide a link to the Angular file? > > On Nov 8, 2018, at 10:29 AM, Pedro Igor Silva wrote: > > Hey Anil! > > I don't think so, tables are sorted by priority in angular. > > Regards. > Pedro Igor > > On Thu, Nov 8, 2018 at 2:21 PM Anil Saldanha > wrote: > >> Hi all, >> quick question. If a bunch of protocol mappers have been written and >> listed in META-INF/services, is there a way to show them in alphabetical >> order in the UI? >> >> Regards, >> Anil >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > From gideonray at gmail.com Fri Nov 9 03:28:14 2018 From: gideonray at gmail.com (Gideon Caranzo) Date: Fri, 9 Nov 2018 16:28:14 +0800 Subject: [keycloak-dev] master admin and realm admin check improvement Message-ID: Hi, During realm import, there is a step wherein the master admin roles and realm admin roles are checked. In my understanding, this is needed because some realm JSON from older versions may not have all the admin roles. These steps takes at least 20 seconds for my setup since I have a very large number of realms. Is it okay if these are done only when roles are present in the JSON to speed up realm creation? It would look like this in *RealmManager *class: *public* RealmModel importRealm(RealmRepresentation rep, *boolean* skipUserDependent) { ? *if* (rep.getRoles() != *null*) { // Assert all *admin* roles are available once import took place. This is needed due to import from previous version where JSON file may not contain all *admin* roles checkMasterAdminManagementRoles(realm); checkRealmAdminManagementRoles(realm); } Thank you. Best regards, Gideon From gambol99 at gmail.com Fri Nov 9 05:11:40 2018 From: gambol99 at gmail.com (gambol) Date: Fri, 9 Nov 2018 10:11:40 +0000 Subject: [keycloak-dev] Authentication SPI - Pinning the IDP Message-ID: Hiya Hopefully someone know's a way around this .. We have a requirement to pin a keycloak client to a specific group of login options i.e. they can only login via a social provider and not a local username/password, BUT we also wish to allow certain users the ability to override the behavior. I mocked up authenticator which used the IdentityProviderSpi.IDENTITY_PROVIDER_SPI_NAME checked it against the a configurable list for the authenticator and also looked for a user override attribute. Now on first login that works fine, but as the access token comes up for refresh the IdentityProviderSpi.IDENTITY_PROVIDER_SPI_NAME is not retained (i guess because it's now a sso session refresh and not a login) and so the authenticator throws the error message. Is it possible to hook into login only? .. Anyone think of another way around it? :-) .. I tried using SetClientNotes / SetAuthNote to retain the logged in provider, but that doesn't appear to work either. Disclaimer: I know the official stance would be the IDP provides authentication only with authorization handled by the application end, but in many case's third party applications can't support this .. so was hoping we could control it at source. Rohith From ulrik.sjolin at gmail.com Fri Nov 9 09:51:14 2018 From: ulrik.sjolin at gmail.com (=?UTF-8?Q?Ulrik_Sj=C3=B6lin?=) Date: Fri, 9 Nov 2018 06:51:14 -0800 Subject: [keycloak-dev] [keycloak-user] /authz/protection/permission/ticket usage? In-Reply-To: References: Message-ID: Hello, Thank you for you quick answer, things are really close now :) Unfortunately using returnNames in GET permission/ticket triggers an NPE when I use returnNames. I have built from tip of master (29f8187978ea464ff6636981ede22ac5f7f86075). I paste in the full console printout below. The NPE occurs at: 15:13:47,468 ERROR XNIO-1 task-15 [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error java.lang.NullPointerException at org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) The function in question seems to fail to get the owner. I tried to use ownerName when creating the ticket, and sure enough I got: [ { "id": "9785e990-8f14-408b-814b-f8f8b46e5076", "owner": "5759f399-a9c0-47e1-8eb7-dd8b9148aaec", "resource": "740fb06e-a543-4cca-9be1-ab240710c4c9", "scope": "55b45b56-2fcb-4b18-b9ab-ec68c53fc14b", "granted": true, "requester": "b4e263e7-7739-4e0b-b554-b96520d27bae" } ] So the owner field is set in the DB but it seems that line 874 still sets owner variable to null? I am really at loss what to do. I suspect a patch where we check for null on owner and requester is not the right thing to do :) 858 public static PermissionTicketRepresentation toRepresentation(PermissionTicket ticket, AuthorizationProvider authorization, boolean returnNames) { 859 PermissionTicketRepresentation representation = new PermissionTicketRepresentation(); 860 861 representation.setId(ticket.getId()); 862 representation.setGranted(ticket.isGranted()); 863 representation.setOwner(ticket.getOwner()); 864 representation.setRequester(ticket.getRequester()); 865 866 Resource resource = ticket.getResource(); 867 868 representation.setResource(resource.getId()); 869 870 if (returnNames) { 871 representation.setResourceName(resource.getName()); 872 KeycloakSession keycloakSession = authorization.getKeycloakSession(); 873 RealmModel realm = authorization.getRealm(); 874 UserModel owner = keycloakSession.users().getUserById(ticket.getOwner(), realm); 875 UserModel requester = keycloakSession.users().getUserById(ticket.getRequester(), realm); 876 representation.setRequesterName(requester.getUsername()); 877 representation.setOwnerName(owner.getUsername()); 878 } 879 880 Scope scope = ticket.getScope(); 881 882 if (scope != null) { 883 representation.setScope(scope.getId()); 884 if (returnNames) { 885 representation.setScopeName(scope.getName()); 886 } 887 } 888 889 return representation; 890 } 891 } Best Regards, Ulrik 15:13:47,468 ERROR XNIO-1 task-15 [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error java.lang.NullPointerException at org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) at org.keycloak.authorization.protection.permission.PermissionTicketService.lambda$find$90(PermissionTicketService.java:224) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at org.keycloak.authorization.protection.permission.PermissionTicketService.find(PermissionTicketService.java:225) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140) at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:509) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:399) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:363) at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:365) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:337) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:443) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:233) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:139) at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:142) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:219) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) 15:15:05,130 ERROR XNIO-1 task-22 [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error java.lang.NullPointerException at org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) at org.keycloak.authorization.protection.permission.PermissionTicketService.lambda$find$90(PermissionTicketService.java:224) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at org.keycloak.authorization.protection.permission.PermissionTicketService.find(PermissionTicketService.java:225) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140) at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:509) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:399) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:363) at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:365) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:337) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:443) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:233) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:139) at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:142) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:219) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) On 9 November 2018 at 14:37:01, Pedro Igor Silva (psilva at redhat.com) wrote: Hi, You can use "scopeName" and "requesterName" properties for that. Take a look here https://github.com/keycloak/keycloak/blob/5cbe595fe3094aae8135b8f2c729e9af0cbdd076/core/src/main/java/org/keycloak/representations/idm/authorization/PermissionTicketRepresentation.java#L22 . Regards. Pedro Igor On Fri, Nov 9, 2018 at 7:18 AM Ulrik Sj?lin wrote: > Hello, > > I have a question on how to use the > API: /authz/protection/permission/ticket > > I can call the endpoint successfully if I do the call with only ids: > > curl --silent -X POST \ > http:// > ${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket > \ > -H "Authorization: Bearer ${service_access_token}" \ > -H "Content-Type: application/json" \ > -d "{ > \"resource\":\"${resource_id}\", > \"scope\":\"40065a35-02d5-4db9-be46-02566cf7a666\", > \"requester\":\"79ae9a5a-0304-41ec-b721-d57a09d419cb\", > \"granted\":\"true\" > }? > > It would however be a lot more workable for me if I could use names like: > > curl --silent -X POST \ > http:// > ${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket > \ > -H "Authorization: Bearer ${service_access_token}" \ > -H "Content-Type: application/json" \ > -d "{ > \"resource\":\"${resource_id}\", > \"scope\":\?Read\", > \"requester\":\?alice\", > \"granted\":\"true\" > }? > > But when I do this I get: > > {"error":"invalid_scope","error_description":"Scope [Read] is invalid?} > {"error":"invalid_permission","error_description":"Requester does not > exists in this server as user.?} > > Looking at the code there seems to be lookups from names to id, but > for some reason it fails. What > am I doing wrong? Any help is greatly appreciated. > > Best Regards, > > Ulrik Sj?lin > > _______________________________________________ > keycloak-user mailing list > keycloak-user at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-user From psilva at redhat.com Fri Nov 9 10:58:14 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Fri, 9 Nov 2018 13:58:14 -0200 Subject: [keycloak-dev] [keycloak-user] /authz/protection/permission/ticket usage? In-Reply-To: References: Message-ID: Could not reproduce this. Can you give me an example of the GET request ? On Fri, Nov 9, 2018 at 12:54 PM Ulrik Sj?lin wrote: > Hello, > > Thank you for you quick answer, things are really close now :) > > Unfortunately using returnNames in GET permission/ticket triggers an NPE > when I use returnNames. I have built from tip of master > (29f8187978ea464ff6636981ede22ac5f7f86075). > I paste in the full console printout below. The NPE occurs at: > > 15:13:47,468 ERROR XNIO-1 task-15 > [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error > java.lang.NullPointerException > at > > org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) > > The function in question seems to fail to get the owner. I tried to use > ownerName when creating the ticket, and sure enough I got: > > [ > { > "id": "9785e990-8f14-408b-814b-f8f8b46e5076", > "owner": "5759f399-a9c0-47e1-8eb7-dd8b9148aaec", > "resource": "740fb06e-a543-4cca-9be1-ab240710c4c9", > "scope": "55b45b56-2fcb-4b18-b9ab-ec68c53fc14b", > "granted": true, > "requester": "b4e263e7-7739-4e0b-b554-b96520d27bae" > } > ] > > So the owner field is set in the DB but it seems that line 874 still sets > owner variable to null? I am really at loss what to do. I suspect a patch > where we > check for null on owner and requester is not the right thing to do :) > > 858 public static PermissionTicketRepresentation > toRepresentation(PermissionTicket ticket, AuthorizationProvider > authorization, boolean returnNames) { > 859 PermissionTicketRepresentation representation = new > PermissionTicketRepresentation(); > 860 > 861 representation.setId(ticket.getId()); > 862 representation.setGranted(ticket.isGranted()); > 863 representation.setOwner(ticket.getOwner()); > 864 representation.setRequester(ticket.getRequester()); > 865 > 866 Resource resource = ticket.getResource(); > 867 > 868 representation.setResource(resource.getId()); > 869 > 870 if (returnNames) { > 871 representation.setResourceName(resource.getName()); > 872 KeycloakSession keycloakSession = > authorization.getKeycloakSession(); > 873 RealmModel realm = authorization.getRealm(); > 874 UserModel owner = > keycloakSession.users().getUserById(ticket.getOwner(), realm); > 875 UserModel requester = > keycloakSession.users().getUserById(ticket.getRequester(), realm); > 876 representation.setRequesterName(requester.getUsername()); > 877 representation.setOwnerName(owner.getUsername()); > 878 } > 879 > 880 Scope scope = ticket.getScope(); > 881 > 882 if (scope != null) { > 883 representation.setScope(scope.getId()); > 884 if (returnNames) { > 885 representation.setScopeName(scope.getName()); > 886 } > 887 } > 888 > 889 return representation; > 890 } > 891 } > > > Best Regards, > > Ulrik > > 15:13:47,468 ERROR XNIO-1 task-15 > [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error > java.lang.NullPointerException > at > > org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.lambda$find$90(PermissionTicketService.java:224) > at > java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) > at > java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235) > at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) > at > > java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) > at > java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) > at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) > at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.find(PermissionTicketService.java:225) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > > org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:509) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:399) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:363) > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:365) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:337) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100) > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:443) > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:233) > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:139) > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > at > > org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:142) > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:219) > at > > org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) > at > > io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) > at > > org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) > at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) > at > > io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) > at > > io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) > at > > io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) > at > > io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) > at > > io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) > at > > io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > at > > io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) > at > > io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) > at > > io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) > at > > io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) > at > > io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > at > > io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) > at > > io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) > at > > io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) > at > > io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) > at > > io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) > at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360) > at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) > at > > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > at > > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > at java.lang.Thread.run(Thread.java:745) > 15:15:05,130 ERROR XNIO-1 task-22 > [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error > java.lang.NullPointerException > at > > org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.lambda$find$90(PermissionTicketService.java:224) > at > java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) > at > java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235) > at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) > at > > java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) > at > java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) > at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) > at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.find(PermissionTicketService.java:225) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > > org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:509) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:399) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:363) > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:365) > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:337) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100) > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:443) > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:233) > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:139) > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > at > > org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:142) > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:219) > at > > org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) > at > > io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) > at > > org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) > at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) > at > > io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) > at > > io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) > at > > io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) > at > > io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) > at > > io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) > at > > io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > at > > io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) > at > > io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) > at > > io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) > at > > io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) > at > > io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > at > > io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) > at > > io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) > at > > io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) > at > > io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) > at > > io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) > at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360) > at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) > at > > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > at > > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > at java.lang.Thread.run(Thread.java:745) > > > On 9 November 2018 at 14:37:01, Pedro Igor Silva (psilva at redhat.com) > wrote: > > Hi, > > You can use "scopeName" and "requesterName" properties for that. Take a > look here > > https://github.com/keycloak/keycloak/blob/5cbe595fe3094aae8135b8f2c729e9af0cbdd076/core/src/main/java/org/keycloak/representations/idm/authorization/PermissionTicketRepresentation.java#L22 > . > > Regards. > Pedro Igor > > On Fri, Nov 9, 2018 at 7:18 AM Ulrik Sj?lin > wrote: > > > Hello, > > > > I have a question on how to use the > > API: /authz/protection/permission/ticket > > > > I can call the endpoint successfully if I do the call with only ids: > > > > curl --silent -X POST \ > > http:// > > ${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket > > \ > > -H "Authorization: Bearer ${service_access_token}" \ > > -H "Content-Type: application/json" \ > > -d "{ > > \"resource\":\"${resource_id}\", > > \"scope\":\"40065a35-02d5-4db9-be46-02566cf7a666\", > > \"requester\":\"79ae9a5a-0304-41ec-b721-d57a09d419cb\", > > \"granted\":\"true\" > > }? > > > > It would however be a lot more workable for me if I could use names like: > > > > curl --silent -X POST \ > > http:// > > ${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket > > \ > > -H "Authorization: Bearer ${service_access_token}" \ > > -H "Content-Type: application/json" \ > > -d "{ > > \"resource\":\"${resource_id}\", > > \"scope\":\?Read\", > > \"requester\":\?alice\", > > \"granted\":\"true\" > > }? > > > > But when I do this I get: > > > > {"error":"invalid_scope","error_description":"Scope [Read] is invalid?} > > {"error":"invalid_permission","error_description":"Requester does not > > exists in this server as user.?} > > > > Looking at the code there seems to be lookups from names to id, but > > for some reason it fails. What > > am I doing wrong? Any help is greatly appreciated. > > > > Best Regards, > > > > Ulrik Sj?lin > > > > _______________________________________________ > > keycloak-user mailing list > > keycloak-user at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/keycloak-user > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From ulrik.sjolin at gmail.com Fri Nov 9 12:26:51 2018 From: ulrik.sjolin at gmail.com (=?UTF-8?Q?Ulrik_Sj=C3=B6lin?=) Date: Fri, 9 Nov 2018 09:26:51 -0800 Subject: [keycloak-dev] [keycloak-user] /authz/protection/permission/ticket usage? In-Reply-To: References: Message-ID: Here is my script? its a bit of a hack but it produces the problem 100% of times. Best Regards, Ulrik #!/bin/bash export host=keycloak export port=8081 export realm=myrealm export resource_server_client_id=myrealm-core-services export resource_server_client_secret=133544d2-8d6c-4a8b-a4e2-827bdd34cdca export username=alice export password=alice export resource_owner=jdoe export resource_name=JDoeResource export scope=read echo "Obtaining token for ${username}" export access_token=\ `curl --silent \ http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ -d client_id=${resource_server_client_id} \ -d client_secret=${resource_server_client_secret} \ -d username=${username} \ -d password=${password} \ -d grant_type=password \ | jq -r ".access_token"` echo "Obtaining token for ${resource_server_client_id}" export service_access_token=\ `curl --silent -X POST \ http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ -d grant_type=client_credentials \ -d client_id=${resource_server_client_id} \ -d client_secret=${resource_server_client_secret} \ | jq -r ".access_token"` echo "Getting resouce id for resource: ${resource_name}" export result=\ `curl --silent -X GET \ http://${host}:${port}/auth/realms/${realm}/authz/protection/resource_set?name=${resource_name} \ -H "Authorization: Bearer ${access_token}" \ | jq -r ".[0]"` if [ "$result" = "null" ]; then ? ? echo "Trying to create resource" ? ? export new_obj=`curl --silent -X POST \ ? ? http://${host}:${port}/auth/realms/${realm}/authz/protection/resource_set \ ? ? -H "content-type: application/json" \ ? ? -H "Authorization: Bearer ${service_access_token}" \ ? ? -d "{ ? ? \"name\":\"${resource_name}\", ? ? \"type\":\"Entities\", ? ? \"ownerManagedAccess\":\"true\", ? ? \"resource_scopes\":[\"admin\",\"peek\",\"read\",\"write\",\"delete\"] ? ? }"` ? ? resource_id=`echo $new_obj | jq "._id" | tr -d '"'` ? ? echo "Resource ID: ${resource_id}" else ? ? echo "Found resource with id: ${result}" ? ? resource_id=$result fi echo "Add permission ticket" export result=\ `curl --silent -X POST \ http://${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket \ -H "Authorization: Bearer ${service_access_token}" \ -H "Content-Type: application/json" \ -d "{ \"resource\":\"${resource_id}\", \"scopeName\":\"${scope}\", \"requesterName\":\"${username}\", \"granted\":\"true\", \"ownerName\":\"${resource_server_client_id}\" }"` echo echo "Get a list of all permission tickets" export result=\ `curl --silent -X GET \ http://${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket \ -H "Authorization: Bearer ${service_access_token}"` echo $result | jq -C . echo echo "Get a list of all permission tickets - with names" export result=\ `curl --silent -X GET \ http://${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket?returnNames=true \ -H "Authorization: Bearer ${service_access_token}"` echo $result | jq -C . On 9 November 2018 at 16:58:27, Pedro Igor Silva (psilva at redhat.com(mailto:psilva at redhat.com)) wrote: > Could not reproduce this. Can you give me an example of the GET request ? > > On Fri, Nov 9, 2018 at 12:54 PM Ulrik Sj?lin wrote: > > Hello, > > > > Thank you for you quick answer, things are really close now :) > > > > Unfortunately using returnNames in GET permission/ticket triggers an NPE > > when I use returnNames. I have built from tip of master > > (29f8187978ea464ff6636981ede22ac5f7f86075). > > I paste in the full console printout below. The NPE occurs at: > > > > 15:13:47,468 ERROR XNIO-1 task-15 > > [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error > > java.lang.NullPointerException > > at > > org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) > > > > The function in question seems to fail to get the owner. I tried to use > > ownerName when creating the ticket, and sure enough I got: > > > > [ > > { > > "id": "9785e990-8f14-408b-814b-f8f8b46e5076", > > "owner": "5759f399-a9c0-47e1-8eb7-dd8b9148aaec", > > "resource": "740fb06e-a543-4cca-9be1-ab240710c4c9", > > "scope": "55b45b56-2fcb-4b18-b9ab-ec68c53fc14b", > > "granted": true, > > "requester": "b4e263e7-7739-4e0b-b554-b96520d27bae" > > } > > ] > > > > So the owner field is set in the DB but it seems that line 874 still sets > > owner variable to null? I am really at loss what to do. I suspect a patch > > where we > > check for null on owner and requester is not the right thing to do :) > > > > 858 public static PermissionTicketRepresentation > > toRepresentation(PermissionTicket ticket, AuthorizationProvider > > authorization, boolean returnNames) { > > 859 PermissionTicketRepresentation representation = new > > PermissionTicketRepresentation(); > > 860 > > 861 representation.setId(ticket.getId()); > > 862 representation.setGranted(ticket.isGranted()); > > 863 representation.setOwner(ticket.getOwner()); > > 864 representation.setRequester(ticket.getRequester()); > > 865 > > 866 Resource resource = ticket.getResource(); > > 867 > > 868 representation.setResource(resource.getId()); > > 869 > > 870 if (returnNames) { > > 871 representation.setResourceName(resource.getName()); > > 872 KeycloakSession keycloakSession = > > authorization.getKeycloakSession(); > > 873 RealmModel realm = authorization.getRealm(); > > 874 UserModel owner = > > keycloakSession.users().getUserById(ticket.getOwner(), realm); > > 875 UserModel requester = > > keycloakSession.users().getUserById(ticket.getRequester(), realm); > > 876 representation.setRequesterName(requester.getUsername()); > > 877 representation.setOwnerName(owner.getUsername()); > > 878 } > > 879 > > 880 Scope scope = ticket.getScope(); > > 881 > > 882 if (scope != null) { > > 883 representation.setScope(scope.getId()); > > 884 if (returnNames) { > > 885 representation.setScopeName(scope.getName()); > > 886 } > > 887 } > > 888 > > 889 return representation; > > 890 } > > 891 } > > > > > > Best Regards, > > > > Ulrik > > > > 15:13:47,468 ERROR XNIO-1 task-15 > > [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error > > java.lang.NullPointerException > > at > > org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) > > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.lambda$find$90(PermissionTicketService.java:224) > > at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) > > at java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235) > > at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) > > at > > java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) > > at > > java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) > > at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) > > at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) > > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.find(PermissionTicketService.java:225) > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > > at > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > > at > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > > at java.lang.reflect.Method.invoke(Method.java:497) > > at > > org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:509) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:399) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:363) > > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:365) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:337) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:443) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:233) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:139) > > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:142) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:219) > > at > > org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) > > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) > > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) > > at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) > > at > > io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) > > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) > > at > > org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) > > at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) > > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) > > at > > io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) > > at > > io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) > > at > > io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) > > at > > io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) > > at > > io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) > > at > > io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) > > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > > at > > io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) > > at > > io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) > > at > > io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) > > at > > io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) > > at > > io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) > > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) > > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) > > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) > > at > > io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) > > at > > io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) > > at > > io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) > > at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360) > > at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) > > at > > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > > at > > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > > at java.lang.Thread.run(Thread.java:745) > > 15:15:05,130 ERROR XNIO-1 task-22 > > [org.keycloak.services.error.KeycloakErrorHandler] Uncaught server error > > java.lang.NullPointerException > > at > > org.keycloak.models.utils.ModelToRepresentation.toRepresentation(ModelToRepresentation.java:877) > > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.lambda$find$90(PermissionTicketService.java:224) > > at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) > > at java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235) > > at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) > > at > > java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) > > at > > java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) > > at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) > > at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) > > at > > org.keycloak.authorization.protection.permission.PermissionTicketService.find(PermissionTicketService.java:225) > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > > at > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > > at > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > > at java.lang.reflect.Method.invoke(Method.java:497) > > at > > org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:509) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:399) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:363) > > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:365) > > at > > org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:337) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132) > > at > > org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:443) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:233) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:139) > > at > > org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:142) > > at > > org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:219) > > at > > org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) > > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) > > at > > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) > > at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) > > at > > io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) > > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) > > at > > org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) > > at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) > > at > > io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) > > at > > io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) > > at > > io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) > > at > > io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) > > at > > io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) > > at > > io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) > > at > > io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) > > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > > at > > io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) > > at > > io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) > > at > > io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) > > at > > io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) > > at > > io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) > > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > > at > > io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) > > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) > > at > > io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) > > at > > io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) > > at > > io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) > > at > > io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) > > at > > io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) > > at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360) > > at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) > > at > > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > > at > > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > > at java.lang.Thread.run(Thread.java:745) > > > > > > On 9 November 2018 at 14:37:01, Pedro Igor Silva (psilva at redhat.com(mailto:psilva at redhat.com)) wrote: > > > > Hi, > > > > You can use "scopeName" and "requesterName" properties for that. Take a > > look here > > https://github.com/keycloak/keycloak/blob/5cbe595fe3094aae8135b8f2c729e9af0cbdd076/core/src/main/java/org/keycloak/representations/idm/authorization/PermissionTicketRepresentation.java#L22 > > . > > > > Regards. > > Pedro Igor > > > > On Fri, Nov 9, 2018 at 7:18 AM Ulrik Sj?lin wrote: > > > > > Hello, > > > > > > I have a question on how to use the > > > API: /authz/protection/permission/ticket > > > > > > I can call the endpoint successfully if I do the call with only ids: > > > > > > curl --silent -X POST \ > > > http:// > > > ${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket > > > \ > > > -H "Authorization: Bearer ${service_access_token}" \ > > > -H "Content-Type: application/json" \ > > > -d "{ > > > \"resource\":\"${resource_id}\", > > > \"scope\":\"40065a35-02d5-4db9-be46-02566cf7a666\", > > > \"requester\":\"79ae9a5a-0304-41ec-b721-d57a09d419cb\", > > > \"granted\":\"true\" > > > }? > > > > > > It would however be a lot more workable for me if I could use names like: > > > > > > curl --silent -X POST \ > > > http:// > > > ${host}:${port}/auth/realms/${realm}/authz/protection/permission/ticket > > > \ > > > -H "Authorization: Bearer ${service_access_token}" \ > > > -H "Content-Type: application/json" \ > > > -d "{ > > > \"resource\":\"${resource_id}\", > > > \"scope\":\?Read\", > > > \"requester\":\?alice\", > > > \"granted\":\"true\" > > > }? > > > > > > But when I do this I get: > > > > > > {"error":"invalid_scope","error_description":"Scope [Read] is invalid?} > > > {"error":"invalid_permission","error_description":"Requester does not > > > exists in this server as user.?} > > > > > > Looking at the code there seems to be lookups from names to id, but > > > for some reason it fails. What > > > am I doing wrong? Any help is greatly appreciated. > > > > > > Best Regards, > > > > > > Ulrik Sj?lin > > > > > > _______________________________________________ > > > keycloak-user mailing list > > > keycloak-user at lists.jboss.org(mailto:keycloak-user at lists.jboss.org) > > > https://lists.jboss.org/mailman/listinfo/keycloak-user > > _______________________________________________ > > keycloak-dev mailing list > > keycloak-dev at lists.jboss.org(mailto:keycloak-dev at lists.jboss.org) > > https://lists.jboss.org/mailman/listinfo/keycloak-dev From Chris.Brandhorst at topicus.nl Fri Nov 9 13:11:26 2018 From: Chris.Brandhorst at topicus.nl (Chris Brandhorst) Date: Fri, 9 Nov 2018 18:11:26 +0000 Subject: [keycloak-dev] SerializedBrokeredIdentityContext ProviderID is filled with IdP alias Message-ID: <03181FD0-EF67-4B86-B79E-B759C5CFB789@topicus.nl> Hi all, Redirect by Bruno from https://issues.jboss.org/browse/KEYCLOAK-8773: We came across the following. In SerializedBrokeredIdentityContext#serialize, the identityProviderId property is filled with the alias of the IdentityProviderModel, instead of (what we would expect) its providerId. Relevant line: https://github.com/keycloak/keycloak/blob/b478472b3578b8980d7b5f1642e91e75d1e78d16/services/src/main/java/org/keycloak/authentication/authenticators/broker/util/SerializedBrokeredIdentityContext.java#L300 We feel this behaviour is semantically incorrect: we were checking against this property in one of our authenticators, but our code did not work for another identity provider of the same type. After some digging we thus found that we were expecting the providerId (coded value) but were actually reading the alias (configured value). Simply throwing this in as a possible improvement. What do you think? Regards, Chris Brandhorst From dt at acutus.pro Sun Nov 11 23:02:34 2018 From: dt at acutus.pro (Dmitry Telegin) Date: Mon, 12 Nov 2018 07:02:34 +0300 Subject: [keycloak-dev] Using OIDC adapter with 3rd party IdPs Message-ID: <1541995354.2048.7.camel@acutus.pro> Hello everyone, In this thread [1] Fabrizio has noted that while Keycloak SAML adapter can be easily used with 3rd party SAML IdPs, the some doesn't work with OIDC by some reason. The reason in fact is that we hardcode Keycloak-specific string templates: public interface ServiceUrlConstants { public static final String AUTH_PATH = "/realms/{realm-name}/protocol/openid-connect/auth"; public static final String TOKEN_PATH = "/realms/{realm-name}/protocol/openid-connect/token"; public static final String TOKEN_SERVICE_LOGOUT_PATH = "/realms/{realm-name}/protocol/openid-connect/logout"; public static final String ACCOUNT_SERVICE_PATH = "/realms/{realm-name}/account"; public static final String REALM_INFO_PATH = "/realms/{realm-name}"; public static final String CLIENTS_MANAGEMENT_REGISTER_NODE_PATH = "/realms/{realm-name}/clients-managements/register-node"; public static final String CLIENTS_MANAGEMENT_UNREGISTER_NODE_PATH = "/realms/{realm-name}/clients-managements/unregister-node"; public static final String JWKS_URL = "/realms/{realm-name}/protocol/openid-connect/certs"; } and then resolve them in KeycloakDeployment. While I've suggested to Fabrizio that he could use KeycloakConfigResolver to customize KeycloakDeployment and override resolveUrls(), I wonder could it be out of the box? I mean we could retrieve .well-known/openid-configuration from auth-server-url, or, in case of no backchannel, embed it into keycloak.json (keycloak-saml.xml style): { "auth-server-url": "http://localhost:8080/auth", "openid-configuration": { "authorization_endpoint": "https://accounts.intuit.com/op/v1/ase", "id_token_signing_alg_values_supported": [ "RS256" ], "issuer": "https://oauth.platform.intuit.com/op/v1", "jwks_uri": "https://oauth.platform.intuit.com/op/v1/jwks", "response_types_supported": [ "code" ], "revocation_endpoint": "https://oauth.platform.intuit.com/oauth2/v1/tokens/revoke", "subject_types_supported": [ "public" ], "token_endpoint": "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer", "userinfo_endpoint": "https://accounts.platform.intuit.com/v1/openid_connect/userinfo" }, "ssl-required": "external", "resource": "test", "public-client": true, "confidential-port": 0 } Seems like a valuable addition to Keycloak, but surprisingly I couldn't find any related JIRA issue. What do you think? [1] http://lists.jboss.org/pipermail/keycloak-user/2018-November/016193.html Cheers, Dmitry Telegin CTO, Acutus s.r.o. From ian at ianduffy.ie Mon Nov 12 04:46:07 2018 From: ian at ianduffy.ie (Ian Duffy) Date: Mon, 12 Nov 2018 09:46:07 +0000 Subject: [keycloak-dev] Avatars/User pictures in keycloak Message-ID: Hi All, Does anyone have a good method for storing avatars/user pictures with Keycloak? I've seen some issues mentioning it but haven't come across any approaches: - https://issues.jboss.org/browse/KEYCLOAK-1044 - https://issues.jboss.org/browse/KEYCLOAK-598 I was thinking something along the lines of an additional user attribute that is a URL to an image. Unsure how to go about getting the user to upload that image, ideally it would be an experience that integrates into the account management screens. Thanks, Ian. From sthorger at redhat.com Mon Nov 12 05:52:09 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 12 Nov 2018 11:52:09 +0100 Subject: [keycloak-dev] Latvian translation review Message-ID: Anyone from the community that can review Latvian translation PR [1]? [1] https://github.com/keycloak/keycloak/pull/5676 From ssilvert at redhat.com Mon Nov 12 12:17:16 2018 From: ssilvert at redhat.com (Stan Silvert) Date: Mon, 12 Nov 2018 12:17:16 -0500 Subject: [keycloak-dev] Avatars/User pictures in keycloak In-Reply-To: References: Message-ID: On 11/12/2018 4:46 AM, Ian Duffy wrote: > Hi All, > > Does anyone have a good method for storing avatars/user pictures with > Keycloak? > > I've seen some issues mentioning it but haven't come across any approaches: > > - https://issues.jboss.org/browse/KEYCLOAK-1044 > - https://issues.jboss.org/browse/KEYCLOAK-598 We've been talking about this for the next version of account management console.? Not sure if it will make the first cut, but IMO it's a very important feature that we need to get done in 2019. > > I was thinking something along the lines of an additional user attribute > that is a URL to an image. Unsure how to go about getting the user to > upload that image, ideally it would be an experience that integrates into > the account management screens. > > Thanks, > Ian. > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From thomas.darimont at googlemail.com Mon Nov 12 13:04:17 2018 From: thomas.darimont at googlemail.com (Thomas Darimont) Date: Mon, 12 Nov 2018 19:04:17 +0100 Subject: [keycloak-dev] Avatars/User pictures in keycloak In-Reply-To: References: Message-ID: Hello, I have a prototype that uses a custom JAX-RS realm resource and minio [1] as the backend for storing avatar images (s3/filesystem etc.). A user can upload / download his avatar based on the current authentication. Would that help you? Cheers, Thomas [1] https://www.minio.io/ Am Mo., 12. Nov. 2018 um 18:23 Uhr schrieb Stan Silvert : > On 11/12/2018 4:46 AM, Ian Duffy wrote: > > Hi All, > > > > Does anyone have a good method for storing avatars/user pictures with > > Keycloak? > > > > I've seen some issues mentioning it but haven't come across any > approaches: > > > > - https://issues.jboss.org/browse/KEYCLOAK-1044 > > - https://issues.jboss.org/browse/KEYCLOAK-598 > We've been talking about this for the next version of account management > console. Not sure if it will make the first cut, but IMO it's a very > important feature that we need to get done in 2019. > > > > I was thinking something along the lines of an additional user attribute > > that is a URL to an image. Unsure how to go about getting the user to > > upload that image, ideally it would be an experience that integrates into > > the account management screens. > > > > Thanks, > > Ian. > > _______________________________________________ > > keycloak-dev mailing list > > keycloak-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/keycloak-dev > > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From thomas.darimont at googlemail.com Mon Nov 12 18:48:32 2018 From: thomas.darimont at googlemail.com (Thomas Darimont) Date: Tue, 13 Nov 2018 00:48:32 +0100 Subject: [keycloak-dev] Avatars/User pictures in keycloak In-Reply-To: References: Message-ID: ... the PoC can be found here: https://github.com/thomasdarimont/keycloak-avatar-minio-extension Suggestions welcome :) Cheers, Thomas Am Mo., 12. Nov. 2018 um 19:04 Uhr schrieb Thomas Darimont < thomas.darimont at googlemail.com>: > Hello, > > I have a prototype that uses a custom JAX-RS realm resource and minio [1] > as the backend for storing avatar images (s3/filesystem etc.). > A user can upload / download his avatar based on the current > authentication. > > Would that help you? > > Cheers, > Thomas > > [1] https://www.minio.io/ > > Am Mo., 12. Nov. 2018 um 18:23 Uhr schrieb Stan Silvert < > ssilvert at redhat.com>: > >> On 11/12/2018 4:46 AM, Ian Duffy wrote: >> > Hi All, >> > >> > Does anyone have a good method for storing avatars/user pictures with >> > Keycloak? >> > >> > I've seen some issues mentioning it but haven't come across any >> approaches: >> > >> > - https://issues.jboss.org/browse/KEYCLOAK-1044 >> > - https://issues.jboss.org/browse/KEYCLOAK-598 >> We've been talking about this for the next version of account management >> console. Not sure if it will make the first cut, but IMO it's a very >> important feature that we need to get done in 2019. >> > >> > I was thinking something along the lines of an additional user attribute >> > that is a URL to an image. Unsure how to go about getting the user to >> > upload that image, ideally it would be an experience that integrates >> into >> > the account management screens. >> > >> > Thanks, >> > Ian. >> > _______________________________________________ >> > keycloak-dev mailing list >> > keycloak-dev at lists.jboss.org >> > https://lists.jboss.org/mailman/listinfo/keycloak-dev >> >> >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev > > From cmelean at gmail.com Mon Nov 12 19:17:25 2018 From: cmelean at gmail.com (=?utf-8?Q?Calixto_Mele=C3=A1n?=) Date: Mon, 12 Nov 2018 19:17:25 -0500 Subject: [keycloak-dev] There is already a httpSessionManager References: <9700A518-4D16-4EEB-A7AC-18B650F0D2C2@gmail.com> Message-ID: I?m doing a simple tutorial with SpringBoot 2.1.0 and KeyCloack 4.5.0. When I start my app, I am getting the error below. It?s like the session manager bean is being registered more than once. org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'httpSessionManager' defined in class path resource [com/example/demo/configuration/SecurityConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=securityConfig; factoryMethodName=httpSessionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/example/demo/configuration/SecurityConfig.class]] for bean 'httpSessionManager': There is already [Generic bean: class [org.keycloak.adapters.springsecurity.management.HttpSessionManager]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in URL [jar:file:/Users/bigcat/.m! 2/repository/org/keycloak/keycloak-spring-security-adapter/4.5.0.Final/keycloak-spring-security-adapter-4.5.0.Final.jar!/org/keycloak/adapters/springsecurity/management/HttpSessionManager.class]] bound. Relevant maven dependencies I have are: org.keycloak keycloak-spring-boot-starter ${keycloak.version} org.springframework.boot spring-boot-starter-security SecurityConfig.class is: @KeycloakConfiguration public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { @Bean public KeycloakConfigResolver KeycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } /** * Registers the KeycloakAuthenticationProvider with the authentication manager. */ @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(keycloakAuthenticationProvider()); } /** * Defines the session authentication strategy. */ @Bean @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http .authorizeRequests() .antMatchers("/customers*").hasRole("pharmacist") .anyRequest().permitAll(); } } Appreciate any help. Thanks From zed at digitaltreemedia.co.uk Mon Nov 12 19:29:29 2018 From: zed at digitaltreemedia.co.uk (Zed Spencer-Milnes) Date: Tue, 13 Nov 2018 00:29:29 +0000 Subject: [keycloak-dev] There is already a httpSessionManager In-Reply-To: References: <9700A518-4D16-4EEB-A7AC-18B650F0D2C2@gmail.com> Message-ID: <8D5A725D-DF7B-41B6-B48B-2D829543B6E5@digitaltreemedia.co.uk> This is due to new behaviour in Spring Boot 2.1 surrounding duplicate definition of beans. Release note: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes#bean-overriding Overriding beans is required to follow the current documentation on integrating Keycloak into your Spring Boot app. You can reenable this behaviour by including the following in your application.yml: spring: main: allow-bean-definition-overriding: true Or spring.main.allow-bean-definition-overriding=true in your application.properties. Hope this helps. Regards, Zed > On 13 Nov 2018, at 00:17, Calixto Mele?n wrote: > > I?m doing a simple tutorial with SpringBoot 2.1.0 and KeyCloack 4.5.0. When I start my app, I am getting the error below. It?s like the session manager bean is being registered more than once. > > org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'httpSessionManager' defined in class path resource [com/example/demo/configuration/SecurityConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=securityConfig; factoryMethodName=httpSessionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/example/demo/configuration/SecurityConfig.class]] for bean 'httpSessionManager': There is already [Generic bean: class [org.keycloak.adapters.springsecurity.management.HttpSessionManager]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in URL [jar:file:/Users/bigcat/.m! > 2/repository/org/keycloak/keycloak-spring-security-adapter/4.5.0.Final/keycloak-spring-security-adapter-4.5.0.Final.jar!/org/keycloak/adapters/springsecurity/management/HttpSessionManager.class]] bound. > > Relevant maven dependencies I have are: > > > org.keycloak > keycloak-spring-boot-starter > ${keycloak.version} > > > > org.springframework.boot > spring-boot-starter-security > > > SecurityConfig.class is: > > @KeycloakConfiguration > public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { > > @Bean > public KeycloakConfigResolver KeycloakConfigResolver() { > return new KeycloakSpringBootConfigResolver(); > } > > /** > * Registers the KeycloakAuthenticationProvider with the authentication manager. > */ > @Autowired > public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { > auth.authenticationProvider(keycloakAuthenticationProvider()); > } > > /** > * Defines the session authentication strategy. > */ > @Bean > @Override > protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { > return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); > } > > @Override > protected void configure(HttpSecurity http) throws Exception > { > super.configure(http); > http > .authorizeRequests() > .antMatchers("/customers*").hasRole("pharmacist") > .anyRequest().permitAll(); > } > } > > > Appreciate any help. Thanks > > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From mposolda at redhat.com Tue Nov 13 13:18:43 2018 From: mposolda at redhat.com (Marek Posolda) Date: Tue, 13 Nov 2018 19:18:43 +0100 Subject: [keycloak-dev] Offline sessions preloading PR Message-ID: <14e5758c-71d2-4e65-5ec3-5387cbbc2989@redhat.com> I sent PR https://github.com/keycloak/keycloak/pull/5716 for fixes and performance improvements about the preloading of offline sessions. With this, the preloading of offline sessions at startup is still required, however it is highly optimized. Without this, preloading of 500K sessions on my laptop took 16 minutes (some customers reported 40 minutes in real environment). Now it is 18 seconds on my laptop. Moreover the preloading time was previously exponentially dependent to the total count of sessions, now it is lineary dependent. I know it will be even better to remove a need for preloading entirely, but there are few kinks around it. Hopefully in the future, we can delegate persistence of userSessions to infinispan entirely. The summary of changes in the PR: - It is not required anymore to lookup User at the startup when the UserSession is preloaded. In case that user is not available anymore at the time of preloading (which can happen especially with 3rd party UserStorage providers, for example when user was directly deleted from LDAP), then UserSession will be removed anyway later from both infinispan and DB due the fact that it will become expired as user doesn't exists and it won't be possible to refresh token. - The pagination SQL queries are based on "seeking" rather then classic pagination based on offset. See https://www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-slow/ and https://use-the-index-luke.com/sql/partial-results/fetch-next-page for details. This proved to have much better performance (at least for MySQL, but probably for the other DBs too) - DB Index added for column LAST_SESSION_REFRESH of table OFFLINE_USER_SESSION for the seeking above - Sessions are put to infinispan through the "cache.putAll" instead of many separate calls of "cache.put" . This is important especially for cluster and cross-dc, as when you call "cache.put" 100 times, you may have around 100 network calls, when with "cache.putAll" it is 1 bigger network call. - When some offline sessions are refreshed, there is bulk update of lastSessionRefresh times to DB every minute. So there is no DB write for each token refresh, but bulk update similarly like we have for cross-dc. This allows more proper tracking of expired sessions from both DB and Infinispan and there is no need for a workaround to automatically update all sessions at startup to the current time (which was problematic for environments with often restarts as offline sessions were defacto never expired). JIRA with the details is https://issues.jboss.org/browse/KEYCLOAK-5479 . A side-effect is, that UserSessionInitializerTest seems to be fixed now - https://issues.jboss.org/browse/KEYCLOAK-8723 . TBH I am not sure about exact cause why it is failing on master, however with latest master, it failed for me after 50 runs when running this test in a loop on my laptop. Similar behaviour was seen by Sebastian as well on his laptop. With this PR, I had more than 300 runs without any failure. Marek From mposolda at redhat.com Tue Nov 13 15:36:09 2018 From: mposolda at redhat.com (Marek Posolda) Date: Tue, 13 Nov 2018 21:36:09 +0100 Subject: [keycloak-dev] Using OIDC adapter with 3rd party IdPs In-Reply-To: <1541995354.2048.7.camel@acutus.pro> References: <1541995354.2048.7.camel@acutus.pro> Message-ID: Hi Dmitry, AFAIK there is no plan to support our OIDC adapter with 3rd party OIDC identity providers. It was needed to do this just for the SAML adapter and support it with 3rd party SAML Idp. There were few reasons for this and one of them was that we wanted to provide compatibility for the users of Picketlink (legacy security framework, which is part of Wildfly). One possibility to address this use-case for OIDC can be to use Keycloak server as proxy. You will basically configure your 3rd party OIDC as IdentityProvider in Keycloak. Keycloak OIDC adapter can delegate authentication to Keycloak server (possibly with kc_idp_hint parameter), which can directly redirect to 3rd party OIDC. Marek On 12/11/18 05:02, Dmitry Telegin wrote: > Hello everyone, > > In this thread [1] Fabrizio has noted that while Keycloak SAML adapter can be easily used with 3rd party SAML IdPs, the some doesn't work with OIDC by some reason. The reason in fact is that we hardcode Keycloak-specific string templates: > > public interface ServiceUrlConstants { > > public static final String AUTH_PATH = "/realms/{realm-name}/protocol/openid-connect/auth"; > public static final String TOKEN_PATH = "/realms/{realm-name}/protocol/openid-connect/token"; > public static final String TOKEN_SERVICE_LOGOUT_PATH = "/realms/{realm-name}/protocol/openid-connect/logout"; > public static final String ACCOUNT_SERVICE_PATH = "/realms/{realm-name}/account"; > public static final String REALM_INFO_PATH = "/realms/{realm-name}"; > public static final String CLIENTS_MANAGEMENT_REGISTER_NODE_PATH = "/realms/{realm-name}/clients-managements/register-node"; > public static final String CLIENTS_MANAGEMENT_UNREGISTER_NODE_PATH = "/realms/{realm-name}/clients-managements/unregister-node"; > public static final String JWKS_URL = "/realms/{realm-name}/protocol/openid-connect/certs"; > > } > > and then resolve them in KeycloakDeployment. While I've suggested to Fabrizio that he could use KeycloakConfigResolver to customize KeycloakDeployment and override resolveUrls(), I wonder could it be out of the box? > > I mean we could retrieve .well-known/openid-configuration from auth-server-url, or, in case of no backchannel, embed it into keycloak.json (keycloak-saml.xml style): > > { > "auth-server-url": "http://localhost:8080/auth", > "openid-configuration": { > "authorization_endpoint": "https://accounts.intuit.com/op/v1/ase", > "id_token_signing_alg_values_supported": [ > "RS256" > ], > "issuer": "https://oauth.platform.intuit.com/op/v1", > "jwks_uri": "https://oauth.platform.intuit.com/op/v1/jwks", > "response_types_supported": [ > "code" > ], > "revocation_endpoint": "https://oauth.platform.intuit.com/oauth2/v1/tokens/revoke", > "subject_types_supported": [ > "public" > ], > "token_endpoint": "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer", > "userinfo_endpoint": "https://accounts.platform.intuit.com/v1/openid_connect/userinfo" > }, > "ssl-required": "external", > "resource": "test", > "public-client": true, > "confidential-port": 0 > } > > Seems like a valuable addition to Keycloak, but surprisingly I couldn't find any related JIRA issue. What do you think? > > [1] http://lists.jboss.org/pipermail/keycloak-user/2018-November/016193.html > > Cheers, > Dmitry Telegin > CTO, Acutus s.r.o. > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From mposolda at redhat.com Tue Nov 13 15:37:58 2018 From: mposolda at redhat.com (Marek Posolda) Date: Tue, 13 Nov 2018 21:37:58 +0100 Subject: [keycloak-dev] Cron jobs for the quickstarts In-Reply-To: References: Message-ID: +1 On 08/11/18 13:06, Sebastian Laskawiec wrote: > +1. I think you can configure Travis to do daily jobs... > > On Thu, Nov 8, 2018 at 1:04 PM Pedro Igor Silva wrote: > >> +1 >> >> On Thu, Nov 8, 2018 at 4:26 AM Bruno Oliveira wrote: >> >>> Good morning, while I was fixing the quickstarts build I was thinking >>> about having a daily cron job to build master. The reason why I would >>> like to do this is to get breaking changes from Keycloak server early. >>> >>> The way how we do today is counterproductive from my point of view, >>> because we only know that things are broken when someone submits a PR. >>> >>> Thoughts? >>> >>> -- >>> - abstractj >>> _______________________________________________ >>> keycloak-dev mailing list >>> keycloak-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/keycloak-dev >>> >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From mposolda at redhat.com Tue Nov 13 15:45:53 2018 From: mposolda at redhat.com (Marek Posolda) Date: Tue, 13 Nov 2018 21:45:53 +0100 Subject: [keycloak-dev] SerializedBrokeredIdentityContext ProviderID is filled with IdP alias In-Reply-To: <03181FD0-EF67-4B86-B79E-B759C5CFB789@topicus.nl> References: <03181FD0-EF67-4B86-B79E-B759C5CFB789@topicus.nl> Message-ID: <9a593ecc-c99d-b03e-1cb2-2eab905dc807@redhat.com> Hi, the alias is here on purpose. Alias of identityProvider is guaranteed to be unique across the realm. This is not the case for providerId. For example you can have 3 SAML identity providers configured in your realm. Then all those 3 providers will have same providerId, so you won't know which one you want to work with. On the other hand, when you have alias, you can always lookup the providerId from it. Marek On 09/11/18 19:11, Chris Brandhorst wrote: > Hi all, > > Redirect by Bruno from https://issues.jboss.org/browse/KEYCLOAK-8773: > > We came across the following. In SerializedBrokeredIdentityContext#serialize, the identityProviderId property is filled with the alias of the IdentityProviderModel, instead of (what we would expect) its providerId. > > Relevant line: > https://github.com/keycloak/keycloak/blob/b478472b3578b8980d7b5f1642e91e75d1e78d16/services/src/main/java/org/keycloak/authentication/authenticators/broker/util/SerializedBrokeredIdentityContext.java#L300 > > We feel this behaviour is semantically incorrect: we were checking against this property in one of our authenticators, but our code did not work for another identity provider of the same type. After some digging we thus found that we were expecting the providerId (coded value) but were actually reading the alias (configured value). > > Simply throwing this in as a possible improvement. What do you think? > > Regards, > Chris Brandhorst > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From mposolda at redhat.com Wed Nov 14 03:05:45 2018 From: mposolda at redhat.com (Marek Posolda) Date: Wed, 14 Nov 2018 09:05:45 +0100 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? Message-ID: Right now, during each token refresh, we're verifying if the newly refreshed access token still contains all the roles, which were present in the refresh token. If not, the refresh token is rejected. I wonder if this check can be removed? This will also allow us to remove the roles (realm_access and resource_access claims) from the refresh token. Anyone knows a reason if this check can't be removed? I think the reason why this check was originally added is due the consent. Previously we did not have clientScopes and the consents on the consent screen were represented by individual roles and protocolMappers. However with clientScopes, this seem to be obsolete IMO. During token refresh, we should check that consents represented by clientScopes in the refresh token were not revoked by the user (or admin). If they were rejected, the refresh token should be rejected. We're doing this. However if some individual role was removed from the user (or from the role scope mappings), I don't see an issue with successfully refresh token and just ensure that the revoked role is not in the new token anymore. WDYT? Marek From thomas.darimont at googlemail.com Wed Nov 14 09:39:06 2018 From: thomas.darimont at googlemail.com (Thomas Darimont) Date: Wed, 14 Nov 2018 15:39:06 +0100 Subject: [keycloak-dev] KEYCLOAK-598 Support for uploading profile images via account pages Message-ID: Hello Keycloak Team, a few days ago there was a discussion on the mailing list about Avatar profile pictures which mentioned some existing JIRA issues [3], [4]. I have created a small example extension [1] that allows you to upload profile pictures with a custom realm "AccountResource" via the account page. This extension supports an "AvatarStorageProvider SPI" which allows exchangeable storage mechanisms for avatars. I have kept the "account" page simple, but I also have an example which supports dynamic cropping of the avatar image with "cropperjs" [2], which needs some polishing. Currently the extension is installed as "ear" but could also be integrated directly into Keycloak. What do you think about a direct integration into Keycloak? Best regards, Thomas [1] https://github.com/thomasdarimont/keycloak-avatar-minio-extension [2] https://github.com/fengyuanchen/cropperjs [3] https://issues.jboss.org/browse/KEYCLOAK-598 [4] https://issues.jboss.org/browse/KEYCLOAK-1044 From sthorger at redhat.com Wed Nov 14 16:37:19 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Wed, 14 Nov 2018 22:37:19 +0100 Subject: [keycloak-dev] Cron jobs for the quickstarts In-Reply-To: References: Message-ID: +1 In the long run the quickstart tests should run as part of the test pipeline, which should run as part of staging PRs for merge. In summary any change should require full QuickStarts tests before merging. On Tue, 13 Nov 2018 at 21:43, Marek Posolda wrote: > +1 > > On 08/11/18 13:06, Sebastian Laskawiec wrote: > > +1. I think you can configure Travis to do daily jobs... > > > > On Thu, Nov 8, 2018 at 1:04 PM Pedro Igor Silva > wrote: > > > >> +1 > >> > >> On Thu, Nov 8, 2018 at 4:26 AM Bruno Oliveira > wrote: > >> > >>> Good morning, while I was fixing the quickstarts build I was thinking > >>> about having a daily cron job to build master. The reason why I would > >>> like to do this is to get breaking changes from Keycloak server early. > >>> > >>> The way how we do today is counterproductive from my point of view, > >>> because we only know that things are broken when someone submits a PR. > >>> > >>> Thoughts? > >>> > >>> -- > >>> - abstractj > >>> _______________________________________________ > >>> keycloak-dev mailing list > >>> keycloak-dev at lists.jboss.org > >>> https://lists.jboss.org/mailman/listinfo/keycloak-dev > >>> > >> _______________________________________________ > >> keycloak-dev mailing list > >> keycloak-dev at lists.jboss.org > >> https://lists.jboss.org/mailman/listinfo/keycloak-dev > >> > > _______________________________________________ > > keycloak-dev mailing list > > keycloak-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/keycloak-dev > > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From sthorger at redhat.com Thu Nov 15 02:55:32 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Thu, 15 Nov 2018 08:55:32 +0100 Subject: [keycloak-dev] Keycloak 4.6.0.Final released Message-ID: http://blog.keycloak.org/2018/11/keycloak-460final-released.html From slaskawi at redhat.com Thu Nov 15 04:42:54 2018 From: slaskawi at redhat.com (Sebastian Laskawiec) Date: Thu, 15 Nov 2018 10:42:54 +0100 Subject: [keycloak-dev] Offline sessions preloading PR In-Reply-To: <14e5758c-71d2-4e65-5ec3-5387cbbc2989@redhat.com> References: <14e5758c-71d2-4e65-5ec3-5387cbbc2989@redhat.com> Message-ID: On Tue, Nov 13, 2018 at 7:47 PM Marek Posolda wrote: > I sent PR https://github.com/keycloak/keycloak/pull/5716 for fixes and > performance improvements about the preloading of offline sessions. With > this, the preloading of offline sessions at startup is still required, > however it is highly optimized. Without this, preloading of 500K > sessions on my laptop took 16 minutes (some customers reported 40 > minutes in real environment). Now it is 18 seconds on my laptop. > Moreover the preloading time was previously exponentially dependent to > the total count of sessions, now it is lineary dependent. > > I know it will be even better to remove a need for preloading entirely, > but there are few kinks around it. Hopefully in the future, we can > delegate persistence of userSessions to infinispan entirely. > > The summary of changes in the PR: > - It is not required anymore to lookup User at the startup when the > UserSession is preloaded. In case that user is not available anymore at > the time of preloading (which can happen especially with 3rd party > UserStorage providers, for example when user was directly deleted from > LDAP), then UserSession will be removed anyway later from both > infinispan and DB due the fact that it will become expired as user > doesn't exists and it won't be possible to refresh token. > > - The pagination SQL queries are based on "seeking" rather then classic > pagination based on offset. See > > https://www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-slow/ > and https://use-the-index-luke.com/sql/partial-results/fetch-next-page > for details. This proved to have much better performance (at least for > MySQL, but probably for the other DBs too) > > - DB Index added for column LAST_SESSION_REFRESH of table > OFFLINE_USER_SESSION for the seeking above > > - Sessions are put to infinispan through the "cache.putAll" instead of > many separate calls of "cache.put" . This is important especially for > cluster and cross-dc, as when you call "cache.put" 100 times, you may > have around 100 network calls, when with "cache.putAll" it is 1 bigger > network call. > > - When some offline sessions are refreshed, there is bulk update of > lastSessionRefresh times to DB every minute. So there is no DB write for > each token refresh, but bulk update similarly like we have for cross-dc. > This allows more proper tracking of expired sessions from both DB and > Infinispan and there is no need for a workaround to automatically update > all sessions at startup to the current time (which was problematic for > environments with often restarts as offline sessions were defacto never > expired). JIRA with the details is > https://issues.jboss.org/browse/KEYCLOAK-5479 . > > A side-effect is, that UserSessionInitializerTest seems to be fixed now > - https://issues.jboss.org/browse/KEYCLOAK-8723 . TBH I am not sure > about exact cause why it is failing on master, however with latest > master, it failed for me after 50 runs when running this test in a loop > on my laptop. Similar behaviour was seen by Sebastian as well on his > laptop. With this PR, I had more than 300 runs without any failure. That's good news Marek! So when do we plan to merge the refactoring PR? Since we focus now on stabilizing tests, this should get in ASAP... > > Marek > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From mposolda at redhat.com Thu Nov 15 05:40:55 2018 From: mposolda at redhat.com (Marek Posolda) Date: Thu, 15 Nov 2018 11:40:55 +0100 Subject: [keycloak-dev] Offline sessions preloading PR In-Reply-To: References: <14e5758c-71d2-4e65-5ec3-5387cbbc2989@redhat.com> Message-ID: <49829667-74e9-690d-d105-c65bac8913fb@redhat.com> On 15/11/18 10:42, Sebastian Laskawiec wrote: > > > On Tue, Nov 13, 2018 at 7:47 PM Marek Posolda > wrote: > > I sent PR https://github.com/keycloak/keycloak/pull/5716 for fixes > and > performance improvements about the preloading of offline sessions. > With > this, the preloading of offline sessions at startup is still > required, > however it is highly optimized. Without this, preloading of 500K > sessions on my laptop took 16 minutes (some customers reported 40 > minutes in real environment). Now it is 18 seconds on my laptop. > Moreover the preloading time was previously exponentially > dependent to > the total count of sessions, now it is lineary dependent. > > I know it will be even better to remove a need for preloading > entirely, > but there are few kinks around it. Hopefully in the future, we can > delegate persistence of userSessions to infinispan entirely. > > The summary of changes in the PR: > - It is not required anymore to lookup User at the startup when the > UserSession is preloaded. In case that user is not available > anymore at > the time of preloading (which can happen especially with 3rd party > UserStorage providers, for example when user was directly deleted > from > LDAP), then UserSession will be removed anyway later from both > infinispan and DB due the fact that it will become expired as user > doesn't exists and it won't be possible to refresh token. > > - The pagination SQL queries are based on "seeking" rather then > classic > pagination based on offset. See > https://www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-slow/ > > and > https://use-the-index-luke.com/sql/partial-results/fetch-next-page > for details. This proved to have much better performance (at least > for > MySQL, but probably for the other DBs too) > > - DB Index added for column LAST_SESSION_REFRESH of table > OFFLINE_USER_SESSION for the seeking above > > - Sessions are put to infinispan through the "cache.putAll" > instead of > many separate calls of "cache.put" . This is important especially for > cluster and cross-dc, as when you call "cache.put" 100 times, you may > have around 100 network calls, when with "cache.putAll" it is 1 > bigger > network call. > > - When some offline sessions are refreshed, there is bulk update of > lastSessionRefresh times to DB every minute. So there is no DB > write for > each token refresh, but bulk update similarly like we have for > cross-dc. > This allows more proper tracking of expired sessions from both DB and > Infinispan and there is no need for a workaround to automatically > update > all sessions at startup to the current time (which was problematic > for > environments with often restarts as offline sessions were defacto > never > expired). JIRA with the details is > https://issues.jboss.org/browse/KEYCLOAK-5479 . > > A side-effect is, that UserSessionInitializerTest seems to be > fixed now > - https://issues.jboss.org/browse/KEYCLOAK-8723 . TBH I am not sure > about exact cause why it is failing on master, however with latest > master, it failed for me after 50 runs when running this test in a > loop > on my laptop. Similar behaviour was seen by Sebastian as well on his > laptop. With this PR, I had more than 300 runs without any failure. > > > That's good news Marek! > > So when do we plan to merge the refactoring PR? Since we focus now on > stabilizing tests, this should get in ASAP... I hope for today afternoon/evening. Marek > > > Marek > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From marco.scheuermann at daimler.com Thu Nov 15 15:43:53 2018 From: marco.scheuermann at daimler.com (marco.scheuermann at daimler.com) Date: Thu, 15 Nov 2018 20:43:53 +0000 Subject: [keycloak-dev] Placing external libs for provider Message-ID: <3359D03B-EAEB-4DDD-AD37-232080188F3F@daimler.com> Hi community, I created a provider implementation and placed it under /providers. The provider has dependencies to other libs, e.g. an azure jar for accessing azure queues. Where do I have to put this lib so that the classloader will find it. I placed it also under /providers but the classes are not loaded.... Thank you, Marco If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support. From dt at acutus.pro Thu Nov 15 16:34:09 2018 From: dt at acutus.pro (Dmitry Telegin) Date: Fri, 16 Nov 2018 00:34:09 +0300 Subject: [keycloak-dev] Placing external libs for provider In-Reply-To: <3359D03B-EAEB-4DDD-AD37-232080188F3F@daimler.com> References: <3359D03B-EAEB-4DDD-AD37-232080188F3F@daimler.com> Message-ID: <1542317649.4793.1.camel@acutus.pro> Hello Marco, What version of Keycloak are you using??AFAIK "providers" directory has been deprecated long ago. For newer Keycloak versions, it is recommended to use standalone/deployments for the same.? If your provider depends on 3rd party libs, you should package everything into a EAR archive. Please look at BeerCloak [1] for the example of how this could be done. P.S. It is generally recommended to ask questions like this to keycloak-user mailing list. This one is dedicated to Keycloak development. [1] https://github.com/dteleguin/beercloak 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 Thu, 2018-11-15 at 20:43 +0000, marco.scheuermann at daimler.com wrote: > Hi community, > > I created a provider implementation and placed it under /providers. > The provider has dependencies to other libs, e.g. an azure jar for accessing azure queues. > Where do I have to put this lib so that the classloader will find it. I placed it also under /providers but the classes > are not loaded.... > > Thank you, > Marco > > > If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support. > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From marco.scheuermann at daimler.com Thu Nov 15 16:43:39 2018 From: marco.scheuermann at daimler.com (marco.scheuermann at daimler.com) Date: Thu, 15 Nov 2018 21:43:39 +0000 Subject: [keycloak-dev] Placing external libs for provider In-Reply-To: <1542317649.4793.1.camel@acutus.pro> References: <3359D03B-EAEB-4DDD-AD37-232080188F3F@daimler.com> <1542317649.4793.1.camel@acutus.pro> Message-ID: <44A94011-19C5-456D-BD03-4AC2E29E62D1@daimler.com> Thank you! Von meinem iPhone gesendet > Am 15.11.2018 um 22:34 schrieb Dmitry Telegin
: > > Hello Marco, > > What version of Keycloak are you using? AFAIK "providers" directory has been deprecated long ago. For newer Keycloak versions, it is recommended to use standalone/deployments for the same. > > If your provider depends on 3rd party libs, you should package everything into a EAR archive. Please look at BeerCloak [1] for the example of how this could be done. > > P.S. It is generally recommended to ask questions like this to keycloak-user mailing list. This one is dedicated to Keycloak development. > > [1] https://github.com/dteleguin/beercloak > > 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 Thu, 2018-11-15 at 20:43 +0000, marco.scheuermann at daimler.com wrote: >> Hi community, >> >> I created a provider implementation and placed it under /providers. >> The provider has dependencies to other libs, e.g. an azure jar for accessing azure queues. >> Where do I have to put this lib so that the classloader will find it. I placed it also under /providers but the classes >> are not loaded.... >> >> Thank you, >> Marco >> >> >> If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support. >> >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support. From ian at ianduffy.ie Fri Nov 16 05:00:38 2018 From: ian at ianduffy.ie (Ian Duffy) Date: Fri, 16 Nov 2018 10:00:38 +0000 Subject: [keycloak-dev] Service account permissions missing from JSON exports Message-ID: Hi all, When doing a JSON export of a client or full realm via the UI or via the instructions at [1] I've noticed if a client has a service account with different client permissions assigned they are excluded from the export. Any workaround to fix this or any guidance on where I should start looking to contribute a fix for keycloak 4.7.0? Thanks, Ian. [1] https://www.keycloak.org/docs/2.5/server_admin/topics/export-import.html From ian at ianduffy.ie Fri Nov 16 10:41:50 2018 From: ian at ianduffy.ie (Ian Duffy) Date: Fri, 16 Nov 2018 15:41:50 +0000 Subject: [keycloak-dev] Avatars/User pictures in keycloak In-Reply-To: References: Message-ID: Awesome Thomas, thank you for sharing I will check it out. From cedric at couralet.eu Fri Nov 16 13:19:15 2018 From: cedric at couralet.eu (=?UTF-8?Q?C=C3=A9dric_Couralet?=) Date: Fri, 16 Nov 2018 19:19:15 +0100 Subject: [keycloak-dev] [keycloak-user] Keycloak 4.6.0.Final released In-Reply-To: References: <9721fa600ae28dd56d6eecabe76ec884@couralet.eu> <6a959a9d128ff9715a66e3b26d993740@couralet.eu> Message-ID: <9eb67585f0b666a05c8d0aeb564adfe6@couralet.eu> Le 2018-11-16 18:49, Geoffrey Cleaves a ?crit?: > I'm unable to get 4.6.0.Final or 4.7.0.Snapshot Docker images to work > properly. The Admin Console throws an error with every action. I've > added new info to this ticket > https://issues.jboss.org/browse/KEYCLOAK-8832 [3] including this > screen cast to prove I'm not loco: > https://www.youtube.com/watch?v=prEO19-UQsk [4] > > Geoff > Hello, I manage to get those error by using DEBUG Log level and using chrome to access admin console. I think the problem is here : https://github.com/keycloak/keycloak/blob/e5bb25dd2f8460bfa818a1cbed0b26c3e88d69db/services/src/main/java/org/keycloak/services/resources/Cors.java#L193 in the debug message allowedOrigins..toArray() is called even when null. But I don't understand the difference between Firefox and Chrome on this. I think a simple fix is to configure the log level as INFO. C?dric Couralet From cedric at couralet.eu Fri Nov 16 13:21:26 2018 From: cedric at couralet.eu (=?UTF-8?Q?C=C3=A9dric_Couralet?=) Date: Fri, 16 Nov 2018 19:21:26 +0100 Subject: [keycloak-dev] [keycloak-user] Keycloak 4.6.0.Final released In-Reply-To: <9eb67585f0b666a05c8d0aeb564adfe6@couralet.eu> References: <9721fa600ae28dd56d6eecabe76ec884@couralet.eu> <6a959a9d128ff9715a66e3b26d993740@couralet.eu> <9eb67585f0b666a05c8d0aeb564adfe6@couralet.eu> Message-ID: <2ef4d5df5522c6e45d801a6b4ad6891f@couralet.eu> > But I don't understand the difference between Firefox and Chrome on > this. > This made me understand that difference : https://stackoverflow.com/questions/15512331/chrome-adding-origin-header-to-same-origin-request From cedric at couralet.eu Fri Nov 16 13:28:43 2018 From: cedric at couralet.eu (=?UTF-8?Q?C=C3=A9dric_Couralet?=) Date: Fri, 16 Nov 2018 19:28:43 +0100 Subject: [keycloak-dev] [keycloak-user] Keycloak 4.6.0.Final released In-Reply-To: <9eb67585f0b666a05c8d0aeb564adfe6@couralet.eu> References: <9721fa600ae28dd56d6eecabe76ec884@couralet.eu> <6a959a9d128ff9715a66e3b26d993740@couralet.eu> <9eb67585f0b666a05c8d0aeb564adfe6@couralet.eu> Message-ID: Le 2018-11-16 19:19, C?dric Couralet a ?crit?: > Le 2018-11-16 18:49, Geoffrey Cleaves a ?crit?: >> I'm unable to get 4.6.0.Final or 4.7.0.Snapshot Docker images to work >> properly. The Admin Console throws an error with every action. I've >> added new info to this ticket >> https://issues.jboss.org/browse/KEYCLOAK-8832 [3] including this >> screen cast to prove I'm not loco: >> https://www.youtube.com/watch?v=prEO19-UQsk [4] >> >> Geoff >> > > Hello, > > I manage to get those error by using DEBUG Log level and using chrome > to access admin console. > > I think the problem is here : > https://github.com/keycloak/keycloak/blob/e5bb25dd2f8460bfa818a1cbed0b26c3e88d69db/services/src/main/java/org/keycloak/services/resources/Cors.java#L193 > > in the debug message allowedOrigins..toArray() is called even when > null. > But I don't understand the difference between Firefox and Chrome on > this. > This made me understand that difference : https://stackoverflow.com/questions/15512331/chrome-adding-origin-header-to-same-origin-request From mposolda at redhat.com Mon Nov 19 05:45:36 2018 From: mposolda at redhat.com (Marek Posolda) Date: Mon, 19 Nov 2018 11:45:36 +0100 Subject: [keycloak-dev] Issue with concurrent SSO login to same client in more browser tabs Message-ID: <4a54e894-3bf1-75e6-4a73-8dbd8aebf09c@redhat.com> Hi, I've sent PR https://github.com/keycloak/keycloak/pull/5736 to fix the issue in subject (corresponding JIRAs are KEYCLOAK-7774 KEYCLOAK-8438). The cause is that once the user is authenticated in the browser and has userSession, there is just 1 clientSession per the userSession+client. So in case of concurrent SSO login in more browser tabs, there can be an issue that each tab is writing it's state to the same clientSession, which causes conflicts (especially attributes like nonce, scope or redirectUri can be possibly different for each tab and shouldn't be shared). The possibility can be to revert back when we had more clientSessions per userSession+client. I think this is step back and has lots of other issues (memory consumption, more cluster and cross-dc writes, worse performance in general...). For the future, it will be rather ideal to remove clientSession entirely or reduce their size even more, as they will be needed for logout, but hopefully for nothing more. So the other possibility is to move most of the state to the "code" parameter and to the refreshToken. Each browser tab has it's own "code" and it's own refreshToken. Problem with the "code" is, that it's used as query parameter in the URL and hence has limits for it's size. It seems ideal is still to stick with 2000 characters per URL. And when redirectUri itself will be part of the code, it can be problematic as we don't know how the redirectUri provided by users will be big.... Fortunately refreshToken doesn't have this issue as it needs to be always sent in the POST request. So to solve the issue for "code", I've added an entry to the infinispan cache "actionTokens", which encapsulates needed state and it's supposed to be valid just for the very short time (between the AuthenticationResponse to the application and the time when application sends the code-to-token request) and it's lifespan corresponds to realm code lifespan (1 minute by default). In the code-to-token request, there is a call to "cache.remove" to remove the code. Infinispan caches (local, distributed and hotrod caches) fortunately guarantee that "remove(123)" is always successful just in 1 thread (Successful means that it returns previous state). So we still have guarantee for the single-use code. Marek From psilva at redhat.com Tue Nov 20 05:54:43 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Tue, 20 Nov 2018 08:54:43 -0200 Subject: [keycloak-dev] Service account permissions missing from JSON exports In-Reply-To: References: Message-ID: Hi, Sorry for the late reply. By client permissions, you mean those defined via the "Permission" tab? If so, they are indeed not exported with a client. Regards. Pedro Igor On Fri, Nov 16, 2018 at 8:10 AM Ian Duffy wrote: > Hi all, > > When doing a JSON export of a client or full realm via the UI or via the > instructions at [1] I've noticed if a client has a service account with > different client permissions assigned they are excluded from the export. > > Any workaround to fix this or any guidance on where I should start looking > to contribute a fix for keycloak 4.7.0? > > Thanks, > Ian. > > [1] > https://www.keycloak.org/docs/2.5/server_admin/topics/export-import.html > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From ian at ianduffy.ie Tue Nov 20 05:56:55 2018 From: ian at ianduffy.ie (Ian Duffy) Date: Tue, 20 Nov 2018 10:56:55 +0000 Subject: [keycloak-dev] Service account permissions missing from JSON exports In-Reply-To: References: Message-ID: Hi Pedro, Thanks for your response. No not the ones under the permissions tab, under the "Clients" -> "Client-ID" -> "Service Account Roles" tab -> Client roles. Thanks, Ian. On Tue, 20 Nov 2018 at 10:54, Pedro Igor Silva wrote: > Hi, > > Sorry for the late reply. By client permissions, you mean those defined > via the "Permission" tab? If so, they are indeed not exported with a client. > > Regards. > Pedro Igor > > On Fri, Nov 16, 2018 at 8:10 AM Ian Duffy wrote: > >> Hi all, >> >> When doing a JSON export of a client or full realm via the UI or via the >> instructions at [1] I've noticed if a client has a service account with >> different client permissions assigned they are excluded from the export. >> >> Any workaround to fix this or any guidance on where I should start looking >> to contribute a fix for keycloak 4.7.0? >> >> Thanks, >> Ian. >> >> [1] >> https://www.keycloak.org/docs/2.5/server_admin/topics/export-import.html >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > From psilva at redhat.com Tue Nov 20 06:15:46 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Tue, 20 Nov 2018 09:15:46 -0200 Subject: [keycloak-dev] Service account permissions missing from JSON exports In-Reply-To: References: Message-ID: I see. It should work if you perform a full export, are you using v2.5 as mentioned in your original email? On Tue, Nov 20, 2018 at 8:57 AM Ian Duffy wrote: > Hi Pedro, > > Thanks for your response. > > No not the ones under the permissions tab, under the "Clients" -> > "Client-ID" -> "Service Account Roles" tab -> Client roles. > > Thanks, > Ian. > > On Tue, 20 Nov 2018 at 10:54, Pedro Igor Silva wrote: > >> Hi, >> >> Sorry for the late reply. By client permissions, you mean those defined >> via the "Permission" tab? If so, they are indeed not exported with a client. >> >> Regards. >> Pedro Igor >> >> On Fri, Nov 16, 2018 at 8:10 AM Ian Duffy wrote: >> >>> Hi all, >>> >>> When doing a JSON export of a client or full realm via the UI or via the >>> instructions at [1] I've noticed if a client has a service account with >>> different client permissions assigned they are excluded from the export. >>> >>> Any workaround to fix this or any guidance on where I should start >>> looking >>> to contribute a fix for keycloak 4.7.0? >>> >>> Thanks, >>> Ian. >>> >>> [1] >>> https://www.keycloak.org/docs/2.5/server_admin/topics/export-import.html >>> _______________________________________________ >>> keycloak-dev mailing list >>> keycloak-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/keycloak-dev >>> >> From ian at ianduffy.ie Tue Nov 20 07:07:30 2018 From: ian at ianduffy.ie (Ian Duffy) Date: Tue, 20 Nov 2018 12:07:30 +0000 Subject: [keycloak-dev] Service account permissions missing from JSON exports In-Reply-To: References: Message-ID: Sorry, v2.5 link due to google popping it up first. I'm using 4.5.0 and 4.6.0. On Tue, 20 Nov 2018 at 11:15, Pedro Igor Silva wrote: > I see. It should work if you perform a full export, are you using v2.5 as > mentioned in your original email? > > On Tue, Nov 20, 2018 at 8:57 AM Ian Duffy wrote: > >> Hi Pedro, >> >> Thanks for your response. >> >> No not the ones under the permissions tab, under the "Clients" -> >> "Client-ID" -> "Service Account Roles" tab -> Client roles. >> >> Thanks, >> Ian. >> >> On Tue, 20 Nov 2018 at 10:54, Pedro Igor Silva wrote: >> >>> Hi, >>> >>> Sorry for the late reply. By client permissions, you mean those defined >>> via the "Permission" tab? If so, they are indeed not exported with a client. >>> >>> Regards. >>> Pedro Igor >>> >>> On Fri, Nov 16, 2018 at 8:10 AM Ian Duffy wrote: >>> >>>> Hi all, >>>> >>>> When doing a JSON export of a client or full realm via the UI or via the >>>> instructions at [1] I've noticed if a client has a service account with >>>> different client permissions assigned they are excluded from the export. >>>> >>>> Any workaround to fix this or any guidance on where I should start >>>> looking >>>> to contribute a fix for keycloak 4.7.0? >>>> >>>> Thanks, >>>> Ian. >>>> >>>> [1] >>>> https://www.keycloak.org/docs/2.5/server_admin/topics/export-import.html >>>> _______________________________________________ >>>> keycloak-dev mailing list >>>> keycloak-dev at lists.jboss.org >>>> https://lists.jboss.org/mailman/listinfo/keycloak-dev >>>> >>> From psilva at redhat.com Tue Nov 20 07:20:54 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Tue, 20 Nov 2018 10:20:54 -0200 Subject: [keycloak-dev] Service account permissions missing from JSON exports In-Reply-To: References: Message-ID: Ahh, OK. Could you please file a JIRA then and provide some steps to reproduce the problem? Btw, for such questions, we usually ask people to use keycloak-user mailing list. Thanks for checking this out. Pedro Igor On Tue, Nov 20, 2018 at 10:07 AM Ian Duffy wrote: > Sorry, v2.5 link due to google popping it up first. I'm using 4.5.0 and > 4.6.0. > > On Tue, 20 Nov 2018 at 11:15, Pedro Igor Silva wrote: > >> I see. It should work if you perform a full export, are you using v2.5 as >> mentioned in your original email? >> >> On Tue, Nov 20, 2018 at 8:57 AM Ian Duffy wrote: >> >>> Hi Pedro, >>> >>> Thanks for your response. >>> >>> No not the ones under the permissions tab, under the "Clients" -> >>> "Client-ID" -> "Service Account Roles" tab -> Client roles. >>> >>> Thanks, >>> Ian. >>> >>> On Tue, 20 Nov 2018 at 10:54, Pedro Igor Silva >>> wrote: >>> >>>> Hi, >>>> >>>> Sorry for the late reply. By client permissions, you mean those defined >>>> via the "Permission" tab? If so, they are indeed not exported with a client. >>>> >>>> Regards. >>>> Pedro Igor >>>> >>>> On Fri, Nov 16, 2018 at 8:10 AM Ian Duffy wrote: >>>> >>>>> Hi all, >>>>> >>>>> When doing a JSON export of a client or full realm via the UI or via >>>>> the >>>>> instructions at [1] I've noticed if a client has a service account with >>>>> different client permissions assigned they are excluded from the >>>>> export. >>>>> >>>>> Any workaround to fix this or any guidance on where I should start >>>>> looking >>>>> to contribute a fix for keycloak 4.7.0? >>>>> >>>>> Thanks, >>>>> Ian. >>>>> >>>>> [1] >>>>> https://www.keycloak.org/docs/2.5/server_admin/topics/export-import.html >>>>> _______________________________________________ >>>>> keycloak-dev mailing list >>>>> keycloak-dev at lists.jboss.org >>>>> https://lists.jboss.org/mailman/listinfo/keycloak-dev >>>>> >>>> From gvincent at redhat.com Wed Nov 21 07:21:59 2018 From: gvincent at redhat.com (Guillaume Vincent) Date: Wed, 21 Nov 2018 13:21:59 +0100 Subject: [keycloak-dev] Javascript Adapter Feedback Message-ID: Hello, this mail is an email to give my feedback on Keycloak Javascript Adapter. The feedback is not good. If you are not open to criticism, do not read this email. TLDR: The Javascript code is a 1500+ line of code, untested, with 10 levels of indentations, no abstraction, difficult to read, difficult to maintain, include in an web application and not following semver. # loc maintain and fix 1500 line of code is not easy at all. The javascript adapter should be split in small javascript functions/modules/class and respect some basic clean code. SRP, no duplication, etc. # tests No single test on the javascript adapter? really. We should introduce some basic tests and API test to avoid breaking the interface. Basically decrypting a JWT, parsing the url, initialisation could be tested easily. # semver In javascript world, the common convention regarding the version number is semver[1]. So when the API change, the major version should be incremented. Not the minor one. We could avoid like that fixing the version number in package.json [2] to avoid those kind of bug [3] # integration in existing app nobody today create real professional frontend application using the plain javascript file. The frontend world is compose of small piece assemble together. We use bundler like webpack, browserify, rollup etc to create our application. Basically we don't do this: ``` ``` we do this ``` const Keycloack = require("keycloack"); var keycloak = Keycloak(); keycloak.init(); ``` yes like in node # modules the keycloak library should use modules or be decomposed into modules. Decoupled in small piece and use rollup or webpack to bundle the application. It will help for example bundler to do tree shacking for example and reduce the bundle size of the library. So instead of try to reinvent the wheel and introduce some insecure code[4]. We should use javascript module, well tested like this one[5] and do something like const uuidv4 = require('uuid/v4'); function createUUID() { return uuidv4(); } # hashtag redirectURL doesn't work if it contains a hashtag. Popular framework AngularJS, VueJS use hastag technique for routing. # cookies, iframe This make our work as developer trully hard. Basically the simplest javascript adpater, should be Instantiate a keycloak singleton load existing jwt in localstorage if present load url params to see if jwt in the url if jwt is present, save in local storage update the singleton # cordova adapter I don't look at this code, but I'm just asking myself, why a javascript adapter need a special code for cordova application? # keycloak promise Oo https://www.keycloak.org/docs/latest/upgrading/index.html#javascipt-adapter-promise A promise is standardized in javascript, so you should avoid using this term in the code if you don't return a promise. callback is a better term. A promise should return a unfulfilled method with then and catch methods attach to it. In French we have a proverb: "Criticism is easy, art is difficult". So I will definitely create a smaller javascript adapter that does not suffer from the problems listed above. And I would come and show the code here. Thanks for reading me [1] https://semver.org/ [2] https://github.com/redhat-cip/dci-ui/commit/e4d0208128afa05c33e72abe606cdcd93594c93e [3] https://issues.jboss.org/browse/KEYCLOAK-8839 [4] https://github.com/keycloak/keycloak/blob/master/adapters/oidc/js/src/main/resources/keycloak.js#L882-L893 [5] https://github.com/kelektiv/node-uuid -- Guillaume Vincent Senior FrontEnd Engineer gvincent at redhat.com TRIED. TESTED. TRUSTED. From sthorger at redhat.com Thu Nov 22 06:11:13 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Thu, 22 Nov 2018 12:11:13 +0100 Subject: [keycloak-dev] Javascript Adapter Feedback In-Reply-To: References: Message-ID: Thanks for your feedback, some comments below: On Wed, 21 Nov 2018, 13:26 Guillaume Vincent Hello, > > this mail is an email to give my feedback on Keycloak Javascript Adapter. > The feedback is not good. If you are not open to criticism, do not read > this email. > > TLDR: The Javascript code is a 1500+ line of code, untested, with 10 levels > of indentations, no abstraction, difficult to read, difficult to maintain, > include in an web application and not following semver. > > # loc > maintain and fix 1500 line of code is not easy at all. The javascript > adapter should be split in small javascript functions/modules/class and > respect some basic clean code. SRP, no duplication, etc. > Breaking up also introduces some complexity so I'm not fully convinced. > > > > # tests > No single test on the javascript adapter? really. We should introduce some > basic tests and API test to avoid breaking the interface. Basically > decrypting a JWT, parsing the url, initialisation could be tested easily. > Of course there are tests. Tests are part of our Arquillian Java testsuite though. > # semver > In javascript world, the common convention regarding the version number is > semver[1]. So when the API change, the major version should be incremented. > Not the minor one. We could avoid like that fixing the version number in > package.json [2] to avoid those kind of bug [3] > It's not quite that trivial as we release everything in Keycloak as a bundle. We can't bump the major version for a small api change and I know which one you are referring to. We strive to not break APIs and rather use deprecation. However, in the case you are referring to this was not possible as it was a broken design and there was no way to fix it. Api hasn't really changed either we just require you to set a config option to use native promises. > # integration in existing app > nobody today create real professional frontend application using the plain > javascript file. The frontend world is compose of small piece assemble > together. We use bundler like webpack, browserify, rollup etc to create our > application. Basically we don't do this: > > ``` > > > ``` > > we do this > > ``` > const Keycloack = require("keycloack"); > var keycloak = Keycloak(); > keycloak.init(); > > ``` > > yes like in node > Yes, some do, but not everyone. The adapter has been designed with the aim to work for both cases. > > # modules > the keycloak library should use modules or be decomposed into modules. > Decoupled in small piece and use rollup or webpack to bundle the > application. It will help for example bundler to do tree shacking for > example and reduce the bundle size of the library. > > So instead of try to reinvent the wheel and introduce some insecure > code[4]. We should use javascript module, well tested like this one[5] and > do something like > > const uuidv4 = require('uuid/v4'); > function createUUID() { > return uuidv4(); > Perhaps, but using libraries has its own problems. End of the day it's easier for us to support an in-line uiid function than support external libraries. > > > > > # hashtag > redirectURL doesn't work if it contains a hashtag. Popular framework > AngularJS, VueJS use hastag technique for routing. > It does. Try the admin console for instance which is angular and uses hashtags > > > > # cookies, iframe > This make our work as developer trully hard. Basically the simplest > javascript adpater, should be > > Instantiate a keycloak singleton > load existing jwt in localstorage if present > load url params to see if jwt in the url > if jwt is present, save in local storage > update the singleton > Don't know what you are talking about here really. There's no cookies and the only iframe is the session iframe and there's no other way to do that > # cordova adapter > I don't look at this code, but I'm just asking myself, why a javascript > adapter need a special code for cordova application? > Cordova mode opens login page in web view or browser tab, regular mode doesn't. > # keycloak promise Oo > > https://www.keycloak.org/docs/latest/upgrading/index.html#javascipt-adapter-promise > A promise is standardized in javascript, so you should avoid using this > term in the code if you don't return a promise. callback is a better term. > A promise should return a unfulfilled method with then and catch methods > attach to it. > We have both. Look at docs and upgrade guide. > > > > In French we have a proverb: "Criticism is easy, art is difficult". So I > will definitely create a smaller javascript adapter that does not suffer > from the problems listed above. And I would come and show the code here. > > Thanks for reading me > > > [1] https://semver.org/ > [2] > > https://github.com/redhat-cip/dci-ui/commit/e4d0208128afa05c33e72abe606cdcd93594c93e > [3] https://issues.jboss.org/browse/KEYCLOAK-8839 > [4] > > https://github.com/keycloak/keycloak/blob/master/adapters/oidc/js/src/main/resources/keycloak.js#L882-L893 > [5] https://github.com/kelektiv/node-uuid > > -- > > Guillaume Vincent > > Senior FrontEnd Engineer > > gvincent at redhat.com > > TRIED. TESTED. TRUSTED. > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From gvincent at redhat.com Thu Nov 22 07:46:03 2018 From: gvincent at redhat.com (Guillaume Vincent) Date: Thu, 22 Nov 2018 13:46:03 +0100 Subject: [keycloak-dev] Javascript Adapter Feedback In-Reply-To: References: Message-ID: On Thu, Nov 22, 2018 at 12:11 PM Stian Thorgersen wrote: > Thanks for your feedback, some comments below: > > On Wed, 21 Nov 2018, 13:26 Guillaume Vincent >> Hello, >> >> this mail is an email to give my feedback on Keycloak Javascript Adapter. >> The feedback is not good. If you are not open to criticism, do not read >> this email. >> >> TLDR: The Javascript code is a 1500+ line of code, untested, with 10 >> levels >> of indentations, no abstraction, difficult to read, difficult to maintain, >> include in an web application and not following semver. >> >> # loc >> maintain and fix 1500 line of code is not easy at all. The javascript >> adapter should be split in small javascript functions/modules/class and >> respect some basic clean code. SRP, no duplication, etc. >> > > Breaking up also introduces some complexity so I'm not fully convinced. > > I'm speaking about clean code. I encourage you to read Clean Code from Robert C. Martin. Maybe because you are working on the adapter for so long you found the code easy to read and maintain. But trust me for newcomers like me it's so painful to read. > >> >> >> >> # tests >> No single test on the javascript adapter? really. We should introduce some >> basic tests and API test to avoid breaking the interface. Basically >> decrypting a JWT, parsing the url, initialisation could be tested easily. >> > > Of course there are tests. Tests are part of our Arquillian Java testsuite > though. > I'm speaking about unit test, functional test in javascript with the use of some module like ava, jest or mocha. Not tests I cannot run. Tests that are run in nodejs and in browsers with some lib like pupetter or karma. Tests should be attach to the project and can be run with a single npm test command. > > >> # semver >> In javascript world, the common convention regarding the version number is >> semver[1]. So when the API change, the major version should be >> incremented. >> Not the minor one. We could avoid like that fixing the version number in >> package.json [2] to avoid those kind of bug [3] >> > > It's not quite that trivial as we release everything in Keycloak as a > bundle. We can't bump the major version for a small api change and I know > which one you are referring to. We strive to not break APIs and rather use > deprecation. However, in the case you are referring to this was not > possible as it was a broken design and there was no way to fix it. Api > hasn't really changed either we just require you to set a config option to > use native promises. > > Api hasn't really changed ? really? We probably don't have the same understanding of what is an API, and what is breaking an API. If I'm oblige to update my options given to a function or replace a function to have the same behavior when I update your library then you broke the API. 4.5.0 sso.init().then() works 4.6.0 sso.init().then() doesn't works. You forced dev to do sso.init({promiseType: "native"}).then() or sso.init().success() This is why I call a breaking change If you tied the version of Keycloak the product to the version of the Javascript adapter then you are not making the work of javascript dev easy. > >> # integration in existing app >> nobody today create real professional frontend application using the plain >> javascript file. The frontend world is compose of small piece assemble >> together. We use bundler like webpack, browserify, rollup etc to create >> our >> application. Basically we don't do this: >> >> ``` >> >> >> ``` >> >> we do this >> >> ``` >> const Keycloack = require("keycloack"); >> var keycloak = Keycloak(); >> keycloak.init(); >> >> ``` >> >> yes like in node >> > > Yes, some do, but not everyone. The adapter has been designed with the aim > to work for both cases. > > I'm not saying that you should remove the production of the library for the browser. I'm saying that the documentation should target the common usage of this library. If you think it's the first one, I think you are wrong. > >> >> # modules >> the keycloak library should use modules or be decomposed into modules. >> Decoupled in small piece and use rollup or webpack to bundle the >> application. It will help for example bundler to do tree shacking for >> example and reduce the bundle size of the library. >> >> So instead of try to reinvent the wheel and introduce some insecure >> code[4]. We should use javascript module, well tested like this one[5] and >> do something like >> >> const uuidv4 = require('uuid/v4'); >> function createUUID() { >> return uuidv4(); >> > > Perhaps, but using libraries has its own problems. End of the day it's > easier for us to support an in-line uiid function than support external > libraries. > > yes and use for example a function that use Math.random() with is not cryptographically strong. The choice made by keycloak team is to rewrite everything? zero modules? My opinion is that by doing this, you will introduce some vulnerability in the code. For example uuid is downloaded more than 13 millions times per week. So a lot of dev and some good ones already audited the 87 lines of code with 100% code coverage. I think less people will audit the 1500 loc difficult to read. > >> >> >> >> >> # hashtag >> redirectURL doesn't work if it contains a hashtag. Popular framework >> AngularJS, VueJS use hastag technique for routing. >> > > It does. Try the admin console for instance which is angular and uses > hashtags > > I haven't tested with the latest one, but keycloak.login({ redirectUri: " http://localhost:8000/#login" }) didn't work Keycloak consider #login as a fragment and raised an error > >> >> >> >> # cookies, iframe >> This make our work as developer trully hard. Basically the simplest >> javascript adpater, should be >> >> Instantiate a keycloak singleton >> load existing jwt in localstorage if present >> load url params to see if jwt in the url >> if jwt is present, save in local storage >> update the singleton >> > > Don't know what you are talking about here really. There's no cookies and > the only iframe is the session iframe and there's no other way to do that > > Cookie are use as a fallback for the localStorage storage used probably to save the JWT. Let me explain with more detail this point. We have in a typical application a login page. When we instantiate the page we want to check if the user is authenticated and redirect if so. >From a dev perspective I just want to do: const keycloack = Keycloak({...}) keycloak.init({...}).then(isAuthenticated => ...) .catch(...) The complexity in the documentation between the hybrid and implicit flow, the redirection or not on keycloak login page. The way that keycloak.init without onLoad: "check-sso" doesn't load the JWT token previously saved is also complex. The library should match the default workflow and make this workflow easy. > >> # cordova adapter >> I don't look at this code, but I'm just asking myself, why a javascript >> adapter need a special code for cordova application? >> > > Cordova mode opens login page in web view or browser tab, regular mode > doesn't. > > this again is crazy, really! why not a react-native mode? If I'm not targeting cordova, I'm obliged to have this code in my bundle? Because the library is not decoupled into module, my bundler cannot do tree shaking automatically. > >> # keycloak promise Oo >> >> https://www.keycloak.org/docs/latest/upgrading/index.html#javascipt-adapter-promise >> A promise is standardized in javascript, so you should avoid using this >> term in the code if you don't return a promise. callback is a better term. >> A promise should return a unfulfilled method with then and catch methods >> attach to it. >> > > We have both. Look at docs and upgrade guide. > please, can you stop saying to look at the guide? I read it carefully and already update my code to fix the breaking change. The documentation is partially updated and at some place wrong. Look at the example code here https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter keycloak.init().then() doesn't work. final point. I think for this problem we can maybe create another thread but: * you call an object a Keycloak promise who is not a promise (documentation problem and code problem) away async doesn't work with the keycloak "promise" * you introduce a breaking change (removing the default behavior) because callback and native promise doesn't work well together. but in the same time you encourage people to add a polyfill for Promises ( https://www.keycloak.org/docs/latest/securing_apps/index.html#earlier-browsers )? (ambiguity and a lot of extra code, difficult to maintain) For me you should use only native promise But obviously this is only my opinion > > >> >> >> >> In French we have a proverb: "Criticism is easy, art is difficult". So I >> will definitely create a smaller javascript adapter that does not suffer >> from the problems listed above. And I would come and show the code here. >> >> Thanks for reading me >> >> >> [1] https://semver.org/ >> [2] >> >> https://github.com/redhat-cip/dci-ui/commit/e4d0208128afa05c33e72abe606cdcd93594c93e >> [3] https://issues.jboss.org/browse/KEYCLOAK-8839 >> [4] >> >> https://github.com/keycloak/keycloak/blob/master/adapters/oidc/js/src/main/resources/keycloak.js#L882-L893 >> [5] https://github.com/kelektiv/node-uuid >> >> -- >> >> Guillaume Vincent >> >> Senior FrontEnd Engineer >> >> gvincent at redhat.com >> >> TRIED. TESTED. TRUSTED. >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > I don't know how many javascript devs do some web application and embed keycloak in their application. But my experience was painful. Maybe it's only me so keep doing what your are doing. I will rewrite a module for my need. Cheers Guillaume From sblanc at redhat.com Thu Nov 22 08:21:16 2018 From: sblanc at redhat.com (Sebastien Blanc) Date: Thu, 22 Nov 2018 14:21:16 +0100 Subject: [keycloak-dev] Javascript Adapter Feedback In-Reply-To: References: Message-ID: On Thu, Nov 22, 2018 at 1:47 PM Guillaume Vincent wrote: > On Thu, Nov 22, 2018 at 12:11 PM Stian Thorgersen > wrote: > > > Thanks for your feedback, some comments below: > > > > On Wed, 21 Nov 2018, 13:26 Guillaume Vincent > > >> Hello, > >> > >> this mail is an email to give my feedback on Keycloak Javascript > Adapter. > >> The feedback is not good. If you are not open to criticism, do not read > >> this email. > >> > >> TLDR: The Javascript code is a 1500+ line of code, untested, with 10 > >> levels > >> of indentations, no abstraction, difficult to read, difficult to > maintain, > >> include in an web application and not following semver. > >> > >> # loc > >> maintain and fix 1500 line of code is not easy at all. The javascript > >> adapter should be split in small javascript functions/modules/class and > >> respect some basic clean code. SRP, no duplication, etc. > >> > > > > Breaking up also introduces some complexity so I'm not fully convinced. > > > > > I'm speaking about clean code. I encourage you to read Clean Code from > Robert C. Martin. > Maybe because you are working on the adapter for so long you found the code > easy to read and maintain. > But trust me for newcomers like me it's so painful to read. > > > > > >> > >> > >> > >> # tests > >> No single test on the javascript adapter? really. We should introduce > some > >> basic tests and API test to avoid breaking the interface. Basically > >> decrypting a JWT, parsing the url, initialisation could be tested > easily. > >> > > > > Of course there are tests. Tests are part of our Arquillian Java > testsuite > > though. > > > > I'm speaking about unit test, functional test in javascript with the use of > some module like ava, jest or mocha. > Not tests I cannot run. > Tests that are run in nodejs and in browsers with some lib like pupetter or > karma. > Tests should be attach to the project and can be run with a single npm test > command. > > > > > > > >> # semver > >> In javascript world, the common convention regarding the version number > is > >> semver[1]. So when the API change, the major version should be > >> incremented. > >> Not the minor one. We could avoid like that fixing the version number in > >> package.json [2] to avoid those kind of bug [3] > >> > > > > It's not quite that trivial as we release everything in Keycloak as a > > bundle. We can't bump the major version for a small api change and I know > > which one you are referring to. We strive to not break APIs and rather > use > > deprecation. However, in the case you are referring to this was not > > possible as it was a broken design and there was no way to fix it. Api > > hasn't really changed either we just require you to set a config option > to > > use native promises. > > > > > Api hasn't really changed ? really? > We probably don't have the same understanding of what is an API, and what > is breaking an API. > If I'm oblige to update my options given to a function or replace a > function to have the same behavior when I update your library then you > broke the API. > > 4.5.0 sso.init().then() works > 4.6.0 sso.init().then() doesn't works. You forced dev to do > sso.init({promiseType: "native"}).then() or sso.init().success() > > This is why I call a breaking change > > If you tied the version of Keycloak the product to the version of the > Javascript adapter then you are not making the work of javascript dev easy. > > > > > > >> # integration in existing app > >> nobody today create real professional frontend application using the > plain > >> javascript file. The frontend world is compose of small piece assemble > >> together. We use bundler like webpack, browserify, rollup etc to create > >> our > >> application. Basically we don't do this: > >> > >> ``` > >> > >> > >> ``` > >> > >> we do this > >> > >> ``` > >> const Keycloack = require("keycloack"); > >> var keycloak = Keycloak(); > >> keycloak.init(); > >> > >> ``` > >> > >> yes like in node > >> > > > > Yes, some do, but not everyone. The adapter has been designed with the > aim > > to work for both cases. > > > > > I'm not saying that you should remove the production of the library for the > browser. > I'm saying that the documentation should target the common usage of this > library. > If you think it's the first one, I think you are wrong. > > > > > >> > >> # modules > >> the keycloak library should use modules or be decomposed into modules. > >> Decoupled in small piece and use rollup or webpack to bundle the > >> application. It will help for example bundler to do tree shacking for > >> example and reduce the bundle size of the library. > >> > >> So instead of try to reinvent the wheel and introduce some insecure > >> code[4]. We should use javascript module, well tested like this one[5] > and > >> do something like > >> > >> const uuidv4 = require('uuid/v4'); > >> function createUUID() { > >> return uuidv4(); > >> > > > > Perhaps, but using libraries has its own problems. End of the day it's > > easier for us to support an in-line uiid function than support external > > libraries. > > > > > yes and use for example a function that use Math.random() with is not > cryptographically strong. > The choice made by keycloak team is to rewrite everything? zero modules? > My opinion is that by doing this, you will introduce some vulnerability in > the code. > > For example uuid is downloaded more than 13 millions times per week. > So a lot of dev and some good ones already audited the 87 lines of code > with 100% code coverage. > > I think less people will audit the 1500 loc difficult to read. > > > > > >> > >> > >> > >> > >> # hashtag > >> redirectURL doesn't work if it contains a hashtag. Popular framework > >> AngularJS, VueJS use hastag technique for routing. > >> > > > > It does. Try the admin console for instance which is angular and uses > > hashtags > > > > > I haven't tested with the latest one, but keycloak.login({ redirectUri: " > http://localhost:8000/#login" }) didn't work > Keycloak consider #login as a fragment and raised an error > > > > > >> > >> > >> > >> # cookies, iframe > >> This make our work as developer trully hard. Basically the simplest > >> javascript adpater, should be > >> > >> Instantiate a keycloak singleton > >> load existing jwt in localstorage if present > >> load url params to see if jwt in the url > >> if jwt is present, save in local storage > >> update the singleton > >> > > > > Don't know what you are talking about here really. There's no cookies and > > the only iframe is the session iframe and there's no other way to do that > > > > > Cookie are use as a fallback for the localStorage storage used probably to > save the JWT. > Let me explain with more detail this point. > We have in a typical application a login page. > When we instantiate the page we want to check if the user is authenticated > and redirect if so. > >From a dev perspective I just want to do: > > const keycloack = Keycloak({...}) > keycloak.init({...}).then(isAuthenticated => ...) .catch(...) > > The complexity in the documentation between the hybrid and implicit flow, > the redirection or not on keycloak login page. > The way that keycloak.init without onLoad: "check-sso" doesn't load the JWT > token previously saved is also complex. > > The library should match the default workflow and make this workflow easy. > > > > > > >> # cordova adapter > >> I don't look at this code, but I'm just asking myself, why a javascript > >> adapter need a special code for cordova application? > >> > > > > Cordova mode opens login page in web view or browser tab, regular mode > > doesn't. > > > > > this again is crazy, really! > why not a react-native mode? > If I'm not targeting cordova, I'm obliged to have this code in my bundle? > Because the library is not decoupled into module, my bundler cannot do tree > shaking automatically. > > > > > >> # keycloak promise Oo > >> > >> > https://www.keycloak.org/docs/latest/upgrading/index.html#javascipt-adapter-promise > >> A promise is standardized in javascript, so you should avoid using this > >> term in the code if you don't return a promise. callback is a better > term. > >> A promise should return a unfulfilled method with then and catch methods > >> attach to it. > >> > > > > We have both. Look at docs and upgrade guide. > > > > please, can you stop saying to look at the guide? > I read it carefully and already update my code to fix the breaking change. > The documentation is partially updated and at some place wrong. > Look at the example code here > > https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter > keycloak.init().then() doesn't work. final point. > > I think for this problem we can maybe create another thread but: > * you call an object a Keycloak promise who is not a promise > (documentation problem and code problem) away async doesn't work with the > keycloak "promise" > * you introduce a breaking change (removing the default behavior) because > callback and native promise doesn't work well together. > but in the same time you encourage people to add a polyfill for Promises > ( > > https://www.keycloak.org/docs/latest/securing_apps/index.html#earlier-browsers > )? > (ambiguity and a lot of extra code, difficult to maintain) > > For me you should use only native promise > But obviously this is only my opinion > > > > > > > >> > >> > >> > >> In French we have a proverb: "Criticism is easy, art is difficult". So I > >> will definitely create a smaller javascript adapter that does not suffer > >> from the problems listed above. And I would come and show the code here. > >> > >> Thanks for reading me > >> > >> > >> [1] https://semver.org/ > >> [2] > >> > >> > https://github.com/redhat-cip/dci-ui/commit/e4d0208128afa05c33e72abe606cdcd93594c93e > >> [3] https://issues.jboss.org/browse/KEYCLOAK-8839 > >> [4] > >> > >> > https://github.com/keycloak/keycloak/blob/master/adapters/oidc/js/src/main/resources/keycloak.js#L882-L893 > >> [5] https://github.com/kelektiv/node-uuid > >> > >> -- > >> > >> Guillaume Vincent > >> > >> Senior FrontEnd Engineer > >> > >> gvincent at redhat.com > >> > >> TRIED. TESTED. TRUSTED. > >> _______________________________________________ > >> keycloak-dev mailing list > >> keycloak-dev at lists.jboss.org > >> https://lists.jboss.org/mailman/listinfo/keycloak-dev > >> > > > > I don't know how many javascript devs do some web application and embed > keycloak in their application. > But my experience was painful. > Maybe it's only me so keep doing what your are doing. > I will rewrite a module for my need. > You can also open some tickets and provide pull requests, we will be more than happy to review them there and have some serene discussions. > > Cheers > > Guillaume > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From gvincent at redhat.com Thu Nov 22 08:31:22 2018 From: gvincent at redhat.com (Guillaume Vincent) Date: Thu, 22 Nov 2018 14:31:22 +0100 Subject: [keycloak-dev] Javascript Adapter Feedback In-Reply-To: References: Message-ID: a friend of mine told me that I looked angry. I apologize, I did not want to sound harsh. I specify that I do not target anyone in particular when I give my opinion on the quality of the code. I'll put more smiley next time :) Cheers On Thu, Nov 22, 2018 at 2:21 PM Sebastien Blanc wrote: > > > > On Thu, Nov 22, 2018 at 1:47 PM Guillaume Vincent > wrote: > >> On Thu, Nov 22, 2018 at 12:11 PM Stian Thorgersen >> wrote: >> >> > Thanks for your feedback, some comments below: >> > >> > On Wed, 21 Nov 2018, 13:26 Guillaume Vincent > wrote: >> > >> >> Hello, >> >> >> >> this mail is an email to give my feedback on Keycloak Javascript >> Adapter. >> >> The feedback is not good. If you are not open to criticism, do not read >> >> this email. >> >> >> >> TLDR: The Javascript code is a 1500+ line of code, untested, with 10 >> >> levels >> >> of indentations, no abstraction, difficult to read, difficult to >> maintain, >> >> include in an web application and not following semver. >> >> >> >> # loc >> >> maintain and fix 1500 line of code is not easy at all. The javascript >> >> adapter should be split in small javascript functions/modules/class and >> >> respect some basic clean code. SRP, no duplication, etc. >> >> >> > >> > Breaking up also introduces some complexity so I'm not fully convinced. >> > >> > >> I'm speaking about clean code. I encourage you to read Clean Code from >> Robert C. Martin. >> Maybe because you are working on the adapter for so long you found the >> code >> easy to read and maintain. >> But trust me for newcomers like me it's so painful to read. >> >> >> > >> >> >> >> >> >> >> >> # tests >> >> No single test on the javascript adapter? really. We should introduce >> some >> >> basic tests and API test to avoid breaking the interface. Basically >> >> decrypting a JWT, parsing the url, initialisation could be tested >> easily. >> >> >> > >> > Of course there are tests. Tests are part of our Arquillian Java >> testsuite >> > though. >> > >> >> I'm speaking about unit test, functional test in javascript with the use >> of >> some module like ava, jest or mocha. >> Not tests I cannot run. >> Tests that are run in nodejs and in browsers with some lib like pupetter >> or >> karma. >> Tests should be attach to the project and can be run with a single npm >> test >> command. >> >> >> > >> > >> >> # semver >> >> In javascript world, the common convention regarding the version >> number is >> >> semver[1]. So when the API change, the major version should be >> >> incremented. >> >> Not the minor one. We could avoid like that fixing the version number >> in >> >> package.json [2] to avoid those kind of bug [3] >> >> >> > >> > It's not quite that trivial as we release everything in Keycloak as a >> > bundle. We can't bump the major version for a small api change and I >> know >> > which one you are referring to. We strive to not break APIs and rather >> use >> > deprecation. However, in the case you are referring to this was not >> > possible as it was a broken design and there was no way to fix it. Api >> > hasn't really changed either we just require you to set a config option >> to >> > use native promises. >> > >> > >> Api hasn't really changed ? really? >> We probably don't have the same understanding of what is an API, and what >> is breaking an API. >> If I'm oblige to update my options given to a function or replace a >> function to have the same behavior when I update your library then you >> broke the API. >> >> 4.5.0 sso.init().then() works >> 4.6.0 sso.init().then() doesn't works. You forced dev to do >> sso.init({promiseType: "native"}).then() or sso.init().success() >> >> This is why I call a breaking change >> >> If you tied the version of Keycloak the product to the version of the >> Javascript adapter then you are not making the work of javascript dev >> easy. >> >> >> >> > >> >> # integration in existing app >> >> nobody today create real professional frontend application using the >> plain >> >> javascript file. The frontend world is compose of small piece assemble >> >> together. We use bundler like webpack, browserify, rollup etc to create >> >> our >> >> application. Basically we don't do this: >> >> >> >> ``` >> >> >> >> >> >> ``` >> >> >> >> we do this >> >> >> >> ``` >> >> const Keycloack = require("keycloack"); >> >> var keycloak = Keycloak(); >> >> keycloak.init(); >> >> >> >> ``` >> >> >> >> yes like in node >> >> >> > >> > Yes, some do, but not everyone. The adapter has been designed with the >> aim >> > to work for both cases. >> > >> > >> I'm not saying that you should remove the production of the library for >> the >> browser. >> I'm saying that the documentation should target the common usage of this >> library. >> If you think it's the first one, I think you are wrong. >> >> >> > >> >> >> >> # modules >> >> the keycloak library should use modules or be decomposed into modules. >> >> Decoupled in small piece and use rollup or webpack to bundle the >> >> application. It will help for example bundler to do tree shacking for >> >> example and reduce the bundle size of the library. >> >> >> >> So instead of try to reinvent the wheel and introduce some insecure >> >> code[4]. We should use javascript module, well tested like this one[5] >> and >> >> do something like >> >> >> >> const uuidv4 = require('uuid/v4'); >> >> function createUUID() { >> >> return uuidv4(); >> >> >> > >> > Perhaps, but using libraries has its own problems. End of the day it's >> > easier for us to support an in-line uiid function than support external >> > libraries. >> > >> > >> yes and use for example a function that use Math.random() with is not >> cryptographically strong. >> The choice made by keycloak team is to rewrite everything? zero modules? >> My opinion is that by doing this, you will introduce some vulnerability in >> the code. >> >> For example uuid is downloaded more than 13 millions times per week. >> So a lot of dev and some good ones already audited the 87 lines of code >> with 100% code coverage. >> >> I think less people will audit the 1500 loc difficult to read. >> >> >> > >> >> >> >> >> >> >> >> >> >> # hashtag >> >> redirectURL doesn't work if it contains a hashtag. Popular framework >> >> AngularJS, VueJS use hastag technique for routing. >> >> >> > >> > It does. Try the admin console for instance which is angular and uses >> > hashtags >> > >> > >> I haven't tested with the latest one, but keycloak.login({ redirectUri: " >> http://localhost:8000/#login" }) didn't work >> Keycloak consider #login as a fragment and raised an error >> >> >> > >> >> >> >> >> >> >> >> # cookies, iframe >> >> This make our work as developer trully hard. Basically the simplest >> >> javascript adpater, should be >> >> >> >> Instantiate a keycloak singleton >> >> load existing jwt in localstorage if present >> >> load url params to see if jwt in the url >> >> if jwt is present, save in local storage >> >> update the singleton >> >> >> > >> > Don't know what you are talking about here really. There's no cookies >> and >> > the only iframe is the session iframe and there's no other way to do >> that >> > >> > >> Cookie are use as a fallback for the localStorage storage used probably to >> save the JWT. >> Let me explain with more detail this point. >> We have in a typical application a login page. >> When we instantiate the page we want to check if the user is authenticated >> and redirect if so. >> >From a dev perspective I just want to do: >> >> const keycloack = Keycloak({...}) >> keycloak.init({...}).then(isAuthenticated => ...) .catch(...) >> >> The complexity in the documentation between the hybrid and implicit flow, >> the redirection or not on keycloak login page. >> The way that keycloak.init without onLoad: "check-sso" doesn't load the >> JWT >> token previously saved is also complex. >> >> The library should match the default workflow and make this workflow easy. >> >> >> >> > >> >> # cordova adapter >> >> I don't look at this code, but I'm just asking myself, why a javascript >> >> adapter need a special code for cordova application? >> >> >> > >> > Cordova mode opens login page in web view or browser tab, regular mode >> > doesn't. >> > >> > >> this again is crazy, really! >> why not a react-native mode? >> If I'm not targeting cordova, I'm obliged to have this code in my bundle? >> Because the library is not decoupled into module, my bundler cannot do >> tree >> shaking automatically. >> >> >> > >> >> # keycloak promise Oo >> >> >> >> >> https://www.keycloak.org/docs/latest/upgrading/index.html#javascipt-adapter-promise >> >> A promise is standardized in javascript, so you should avoid using this >> >> term in the code if you don't return a promise. callback is a better >> term. >> >> A promise should return a unfulfilled method with then and catch >> methods >> >> attach to it. >> >> >> > >> > We have both. Look at docs and upgrade guide. >> > >> >> please, can you stop saying to look at the guide? >> I read it carefully and already update my code to fix the breaking change. >> The documentation is partially updated and at some place wrong. >> Look at the example code here >> >> https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter >> keycloak.init().then() doesn't work. final point. >> >> I think for this problem we can maybe create another thread but: >> * you call an object a Keycloak promise who is not a promise >> (documentation problem and code problem) away async doesn't work with the >> keycloak "promise" >> * you introduce a breaking change (removing the default behavior) because >> callback and native promise doesn't work well together. >> but in the same time you encourage people to add a polyfill for >> Promises >> ( >> >> https://www.keycloak.org/docs/latest/securing_apps/index.html#earlier-browsers >> )? >> (ambiguity and a lot of extra code, difficult to maintain) >> >> For me you should use only native promise >> But obviously this is only my opinion >> >> >> > >> > >> >> >> >> >> >> >> >> In French we have a proverb: "Criticism is easy, art is difficult". So >> I >> >> will definitely create a smaller javascript adapter that does not >> suffer >> >> from the problems listed above. And I would come and show the code >> here. >> >> >> >> Thanks for reading me >> >> >> >> >> >> [1] https://semver.org/ >> >> [2] >> >> >> >> >> https://github.com/redhat-cip/dci-ui/commit/e4d0208128afa05c33e72abe606cdcd93594c93e >> >> [3] https://issues.jboss.org/browse/KEYCLOAK-8839 >> >> [4] >> >> >> >> >> https://github.com/keycloak/keycloak/blob/master/adapters/oidc/js/src/main/resources/keycloak.js#L882-L893 >> >> [5] https://github.com/kelektiv/node-uuid >> >> >> >> -- >> >> >> >> Guillaume Vincent >> >> >> >> Senior FrontEnd Engineer >> >> >> >> gvincent at redhat.com >> >> >> >> TRIED. TESTED. TRUSTED. >> >> _______________________________________________ >> >> keycloak-dev mailing list >> >> keycloak-dev at lists.jboss.org >> >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> >> >> > >> >> I don't know how many javascript devs do some web application and embed >> keycloak in their application. >> But my experience was painful. >> Maybe it's only me so keep doing what your are doing. >> I will rewrite a module for my need. >> > You can also open some tickets and provide pull requests, we will be more > than happy to review them there and have some serene discussions. > >> >> Cheers >> >> Guillaume >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > -- Guillaume Vincent Senior FrontEnd Engineer gvincent at redhat.com TRIED. TESTED. TRUSTED. From david at smooth-systems.solutions Thu Nov 22 15:10:35 2018 From: david at smooth-systems.solutions (David Monichi) Date: Thu, 22 Nov 2018 21:10:35 +0100 Subject: [keycloak-dev] [keycloak-user] Extend keycloak notifications In-Reply-To: <1542064827.2535.5.camel@acutus.pro> References: <5145cc17-a0aa-ca89-3a6f-41e4ad15599e@smooth-systems.solutions> <1542064827.2535.5.camel@acutus.pro> Message-ID: <0f2330e1-5dd6-ed79-2a15-e5c876768b35@smooth-systems.solutions> Hi Dmitry, To don't bother normal users I changed to the dev group mailing list. thx a lot for your detailed feedback. Considering that you are probably right, that this feature will never be integrated to keycloak, I'll have to think about my next steps. Guess I'll follow your advise and catch internal keycloak events for notifications. Currently it seems like the best solutions. As soon as we start with this component I'll let you know. Planning to make it open source but unfortunately can't promise yet. Thx for all in the meantime /david On 13.11.18 00:20, Dmitry Telegin wrote: > Hello David, > > Just FYI, you can reach Keycloak developers via keycloak-dev mailing list; this one is more like a community of independent Keycloak experts. Being a proud member thereof, I'll put in my two cents with great pleasure :) see answers inline. > > TL;DR: the feature seems interesting, but I highly doubt it will be ever made a part of Keycloak. However, you can implement everything as a Keycloak extension (and that's what we love about Keycloak). > > On Mon, 2018-11-12 at 22:55 +0100, David Monichi wrote: >> Hi, >> >> I'm considering to create a new application and for sure I'll use >> keycloak as user backend. It's really cool stuff what you guys created. >> >> I thought about various solutions for notifications of my application >> and was wondering if you guys already thought about to extend your >> e-mail notification to a more general and flexible system. So that not >> only keycloak e-mails will be sent over keycloak but also other >> applications e-mails and even more notifications can be send over >> keycloak (I'm thinking here of SMS, etc.). Therefore applications would >> need to upload any kind of templates to keycloak and somehow be able to >> manage them. There are 2 reasons for such a step. First of all keycloak >> already provides such basic functionality to sent notifications and so >> extending it could be done with lower overhead. Second, keycloak already >> owns the recipient data, if applications manage users over keycloak. > I'd also add that Keycloak already integrates the Freemarker?template engine, which is used to generate emails (along with login forms and the account UI). > >> As additional feature of course a proper monitoring should be placed in >> such a feature, since notifications are really vital to modern applications. > Could you please elaborate what exactly you need to monitor? > >> We would be able to provide programming resources for such a feature but >> of course working together, specially for the design phase, with you guys. >> >> The alternative would be to provide a different notification system and >> forward keycloak e-mails to that service (actually the event to sent a >> notification). Don't know if this actually is the way to go ... >> >> >> My motivation for such a feature is, that a single application should be >> responsible for sending notifications of any kind and not be widespread >> over various applications. >> >> Any ideas welcome ;) Eventually I overlooked something in my design ... > My experience says that features like that rarely get incorporated into mainline Keycloak; the necessary (but not sufficient) condition is that you should be able to maintain this feature in the future. > > However, you can use Keycloak extension points (called Providers [1] in Keycloak's terms) to implement what you want. > > Here's my take on the outline of the solution: > - implement EntityProvider [2] (custom JPA entity + DB table) to store templates; > - implement RealmResourceProvider [3] (custom REST resource) for CRUD-style template management by the applications; > - implement another one to trigger notification (and potentially track its status); > - implement the actual notification code, i.e. retrieving the template, processing it with Freemarker and queueing it for delivery; > - most likely, you will need a persistent queue to store pending notifications. For that, you can employ Keycloak's built-in ActiveMQ Artemis message broker; > - optionally, integrate your system with Keycloak internal events, so that the latter could trigger your application-managed notifications. > > For the reference, I'd recommend the official keycloak examples [4] and my own BeerCloak project [5]. > > Good luck, and feel free to ask any questions :) > > 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 > > [1]https://www.keycloak.org/docs/latest/server_development/index.html#_providers > [2]https://www.keycloak.org/docs/latest/server_development/index.html#_extensions_jpa > [3]https://www.keycloak.org/docs/latest/server_development/index.html#_extensions_rest > [4]https://github.com/keycloak/keycloak/tree/master/examples/providers > [5]https://github.com/dteleguin/beercloak > >> Thx in advance for all your thoughts & all the best >> >> /david >> >> _______________________________________________ >> keycloak-user mailing list >> keycloak-user at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-user From gvincent at redhat.com Fri Nov 23 03:51:27 2018 From: gvincent at redhat.com (Guillaume Vincent) Date: Fri, 23 Nov 2018 09:51:27 +0100 Subject: [keycloak-dev] Javascript Adapter Feedback In-Reply-To: References: Message-ID: I open a bug related to the promise issue. My comment on the documentation not fully updated will be fixed by https://github.com/keycloak/keycloak-documentation/commit/da8ce0026eaae5e1728c7ed505266da68af4e1f6 But the documentation is not updated (yet?) From sthorger at redhat.com Mon Nov 26 02:44:44 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 26 Nov 2018 08:44:44 +0100 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? In-Reply-To: References: Message-ID: +1 On Wed, 14 Nov 2018 at 09:09, Marek Posolda wrote: > Right now, during each token refresh, we're verifying if the newly > refreshed access token still contains all the roles, which were present > in the refresh token. If not, the refresh token is rejected. > > I wonder if this check can be removed? This will also allow us to remove > the roles (realm_access and resource_access claims) from the refresh > token. Anyone knows a reason if this check can't be removed? > > I think the reason why this check was originally added is due the > consent. Previously we did not have clientScopes and the consents on the > consent screen were represented by individual roles and protocolMappers. > However with clientScopes, this seem to be obsolete IMO. > > During token refresh, we should check that consents represented by > clientScopes in the refresh token were not revoked by the user (or > admin). If they were rejected, the refresh token should be rejected. > We're doing this. However if some individual role was removed from the > user (or from the role scope mappings), I don't see an issue with > successfully refresh token and just ensure that the revoked role is not > in the new token anymore. > > WDYT? > > Marek > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From sthorger at redhat.com Mon Nov 26 02:46:12 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 26 Nov 2018 08:46:12 +0100 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? In-Reply-To: References: Message-ID: If I'm not mistaken the token is already updated with new roles today. On Mon, 26 Nov 2018 at 08:44, Stian Thorgersen wrote: > +1 > > On Wed, 14 Nov 2018 at 09:09, Marek Posolda wrote: > >> Right now, during each token refresh, we're verifying if the newly >> refreshed access token still contains all the roles, which were present >> in the refresh token. If not, the refresh token is rejected. >> >> I wonder if this check can be removed? This will also allow us to remove >> the roles (realm_access and resource_access claims) from the refresh >> token. Anyone knows a reason if this check can't be removed? >> >> I think the reason why this check was originally added is due the >> consent. Previously we did not have clientScopes and the consents on the >> consent screen were represented by individual roles and protocolMappers. >> However with clientScopes, this seem to be obsolete IMO. >> >> During token refresh, we should check that consents represented by >> clientScopes in the refresh token were not revoked by the user (or >> admin). If they were rejected, the refresh token should be rejected. >> We're doing this. However if some individual role was removed from the >> user (or from the role scope mappings), I don't see an issue with >> successfully refresh token and just ensure that the revoked role is not >> in the new token anymore. >> >> WDYT? >> >> Marek >> >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > From mposolda at redhat.com Mon Nov 26 02:53:01 2018 From: mposolda at redhat.com (Marek Posolda) Date: Mon, 26 Nov 2018 08:53:01 +0100 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? In-Reply-To: References: Message-ID: <3345b194-9959-acfc-fd0a-57b3f0ca3feb@redhat.com> Yes, it is updated. And new token can contain some more roles, which weren't presented before on the old refresh token. However if the newToken doesn't contain any role, which was present in the old refresh token, then refreshToken request is rejected ATM. That's what I think is not great behaviour as it is sufficient to check consents rather than roles. Marek On 26/11/2018 08:46, Stian Thorgersen wrote: > If I'm not mistaken the token is already updated with new roles today. > > On Mon, 26 Nov 2018 at 08:44, Stian Thorgersen > wrote: > > +1 > > On Wed, 14 Nov 2018 at 09:09, Marek Posolda > wrote: > > Right now, during each token refresh, we're verifying if the > newly > refreshed access token still contains all the roles, which > were present > in the refresh token. If not, the refresh token is rejected. > > I wonder if this check can be removed? This will also allow us > to remove > the roles (realm_access and resource_access claims) from the > refresh > token. Anyone knows a reason if this check can't be removed? > > I think the reason why this check was originally added is due the > consent. Previously we did not have clientScopes and the > consents on the > consent screen were represented by individual roles and > protocolMappers. > However with clientScopes, this seem to be obsolete IMO. > > During token refresh, we should check that consents > represented by > clientScopes in the refresh token were not revoked by the user > (or > admin). If they were rejected, the refresh token should be > rejected. > We're doing this. However if some individual role was removed > from the > user (or from the role scope mappings), I don't see an issue with > successfully refresh token and just ensure that the revoked > role is not > in the new token anymore. > > WDYT? > > Marek > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From sthorger at redhat.com Mon Nov 26 02:54:20 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 26 Nov 2018 08:54:20 +0100 Subject: [keycloak-dev] Issue with concurrent SSO login to same client in more browser tabs In-Reply-To: <4a54e894-3bf1-75e6-4a73-8dbd8aebf09c@redhat.com> References: <4a54e894-3bf1-75e6-4a73-8dbd8aebf09c@redhat.com> Message-ID: The ideal may be to create a code token. If it's less than 2000 characters just send it as is. If it's more than we put it in the actionTokens cache and just send a reference to it in the code param. Not sure if the reference should just be a uuid, or if it should be something more to make sure it can't be guessed. The last point is also relevant to reference tokens once/if we add support for that. On Mon, 19 Nov 2018 at 11:49, Marek Posolda wrote: > Hi, > > I've sent PR https://github.com/keycloak/keycloak/pull/5736 to fix the > issue in subject (corresponding JIRAs are KEYCLOAK-7774 KEYCLOAK-8438). > The cause is that once the user is authenticated in the browser and has > userSession, there is just 1 clientSession per the userSession+client. > So in case of concurrent SSO login in more browser tabs, there can be an > issue that each tab is writing it's state to the same clientSession, > which causes conflicts (especially attributes like nonce, scope or > redirectUri can be possibly different for each tab and shouldn't be > shared). > > The possibility can be to revert back when we had more clientSessions > per userSession+client. I think this is step back and has lots of other > issues (memory consumption, more cluster and cross-dc writes, worse > performance in general...). For the future, it will be rather ideal to > remove clientSession entirely or reduce their size even more, as they > will be needed for logout, but hopefully for nothing more. > > So the other possibility is to move most of the state to the "code" > parameter and to the refreshToken. Each browser tab has it's own "code" > and it's own refreshToken. Problem with the "code" is, that it's used as > query parameter in the URL and hence has limits for it's size. It seems > ideal is still to stick with 2000 characters per URL. And when > redirectUri itself will be part of the code, it can be problematic as we > don't know how the redirectUri provided by users will be big.... > Fortunately refreshToken doesn't have this issue as it needs to be > always sent in the POST request. > > So to solve the issue for "code", I've added an entry to the infinispan > cache "actionTokens", which encapsulates needed state and it's supposed > to be valid just for the very short time (between the > AuthenticationResponse to the application and the time when application > sends the code-to-token request) and it's lifespan corresponds to realm > code lifespan (1 minute by default). In the code-to-token request, there > is a call to "cache.remove" to remove the code. Infinispan caches > (local, distributed and hotrod caches) fortunately guarantee that > "remove(123)" is always successful just in 1 thread (Successful means > that it returns previous state). So we still have guarantee for the > single-use code. > > Marek > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From sthorger at redhat.com Mon Nov 26 02:59:27 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Mon, 26 Nov 2018 08:59:27 +0100 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? In-Reply-To: <3345b194-9959-acfc-fd0a-57b3f0ca3feb@redhat.com> References: <3345b194-9959-acfc-fd0a-57b3f0ca3feb@redhat.com> Message-ID: I think it's better if the old role is just removed. If you think about it the new access token is sent to a service in most cases and the service only has that new token as a reference for what roles the user has anyways. I don't understand what you mean about "it is sufficient to check consents rather than roles". Both need to be checked, always. Consents limits the access, while role is the permissions the user/client have. On Mon, 26 Nov 2018 at 08:53, Marek Posolda wrote: > Yes, it is updated. And new token can contain some more roles, which > weren't presented before on the old refresh token. However if the newToken > doesn't contain any role, which was present in the old refresh token, then > refreshToken request is rejected ATM. That's what I think is not great > behaviour as it is sufficient to check consents rather than roles. > > Marek > > On 26/11/2018 08:46, Stian Thorgersen wrote: > > If I'm not mistaken the token is already updated with new roles today. > > On Mon, 26 Nov 2018 at 08:44, Stian Thorgersen > wrote: > >> +1 >> >> On Wed, 14 Nov 2018 at 09:09, Marek Posolda wrote: >> >>> Right now, during each token refresh, we're verifying if the newly >>> refreshed access token still contains all the roles, which were present >>> in the refresh token. If not, the refresh token is rejected. >>> >>> I wonder if this check can be removed? This will also allow us to remove >>> the roles (realm_access and resource_access claims) from the refresh >>> token. Anyone knows a reason if this check can't be removed? >>> >>> I think the reason why this check was originally added is due the >>> consent. Previously we did not have clientScopes and the consents on the >>> consent screen were represented by individual roles and protocolMappers. >>> However with clientScopes, this seem to be obsolete IMO. >>> >>> During token refresh, we should check that consents represented by >>> clientScopes in the refresh token were not revoked by the user (or >>> admin). If they were rejected, the refresh token should be rejected. >>> We're doing this. However if some individual role was removed from the >>> user (or from the role scope mappings), I don't see an issue with >>> successfully refresh token and just ensure that the revoked role is not >>> in the new token anymore. >>> >>> WDYT? >>> >>> Marek >>> >>> _______________________________________________ >>> keycloak-dev mailing list >>> keycloak-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/keycloak-dev >>> >> > From mposolda at redhat.com Mon Nov 26 03:03:56 2018 From: mposolda at redhat.com (Marek Posolda) Date: Mon, 26 Nov 2018 09:03:56 +0100 Subject: [keycloak-dev] Issue with concurrent SSO login to same client in more browser tabs In-Reply-To: References: <4a54e894-3bf1-75e6-4a73-8dbd8aebf09c@redhat.com> Message-ID: <9b2f1cf7-d146-d997-8c9a-b72a979a28e4@redhat.com> On 26/11/2018 08:54, Stian Thorgersen wrote: > The ideal may be to create a code token. If it's less than 2000 > characters just send it as is. If it's more than we put it in the > actionTokens cache and just send a reference to it in the code param. I see. So it will be something like "hybrid" between both approaches. Was also a bit thinking about it, but didn't in the end. ATM it is always adding the item to actionTokens cache. Maybe it's possible to optimize it and add the "hybrid" possibility, but not sure about it at this stage? Maybe after new year? > Not sure if the reference should just be a uuid, or if it should be > something more to make sure it can't be guessed. The last point is > also relevant to reference tokens once/if we add support for that. ATM it is .. The userSessionId and clientUUID are needed, so if code was already used (and is removed from actionTokens cache), it is still possible to lookup userSession and remove clientSession from it as OIDC specs suggests (in case that attempt of duplicate code use was detected). Not sure how big probability is to guess UUID for the very short-lived code. It seems to me like kind of impossible thing. And if it's really guessed, then when valid user will try to exchange the code, which attacker already exchanged, the "code" will be expired (client removed from userSession as pointed above). Marek > > On Mon, 19 Nov 2018 at 11:49, Marek Posolda > wrote: > > Hi, > > I've sent PR https://github.com/keycloak/keycloak/pull/5736 to fix > the > issue in subject (corresponding JIRAs are KEYCLOAK-7774 > KEYCLOAK-8438). > The cause is that once the user is authenticated in the browser > and has > userSession, there is just 1 clientSession per the > userSession+client. > So in case of concurrent SSO login in more browser tabs, there can > be an > issue that each tab is writing it's state to the same clientSession, > which causes conflicts (especially attributes like nonce, scope or > redirectUri can be possibly different for each tab and shouldn't be > shared). > > The possibility can be to revert back when we had more clientSessions > per userSession+client. I think this is step back and has lots of > other > issues (memory consumption, more cluster and cross-dc writes, worse > performance in general...). For the future, it will be rather > ideal to > remove clientSession entirely or reduce their size even more, as they > will be needed for logout, but hopefully for nothing more. > > So the other possibility is to move most of the state to the "code" > parameter and to the refreshToken. Each browser tab has it's own > "code" > and it's own refreshToken. Problem with the "code" is, that it's > used as > query parameter in the URL and hence has limits for it's size. It > seems > ideal is still to stick with 2000 characters per URL. And when > redirectUri itself will be part of the code, it can be problematic > as we > don't know how the redirectUri provided by users will be big.... > Fortunately refreshToken doesn't have this issue as it needs to be > always sent in the POST request. > > So to solve the issue for "code", I've added an entry to the > infinispan > cache "actionTokens", which encapsulates needed state and it's > supposed > to be valid just for the very short time (between the > AuthenticationResponse to the application and the time when > application > sends the code-to-token request) and it's lifespan corresponds to > realm > code lifespan (1 minute by default). In the code-to-token request, > there > is a call to "cache.remove" to remove the code. Infinispan caches > (local, distributed and hotrod caches) fortunately guarantee that > "remove(123)" is always successful just in 1 thread (Successful means > that it returns previous state). So we still have guarantee for the > single-use code. > > Marek > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From psilva at redhat.com Mon Nov 26 07:57:24 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Mon, 26 Nov 2018 10:57:24 -0200 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? In-Reply-To: References: <3345b194-9959-acfc-fd0a-57b3f0ca3feb@redhat.com> Message-ID: Marek, please correct me if I wrong. What Marek is suggesting is remove role check entirely and only check for user consents. The reason is that from an OAuth2 perspective we *only* need to make sure that user consents are still valid. With client scopes, the user no longer consents access to individual roles but scopes where the actually granted roles could depend on the granted scopes. In case roles are granted directly to a user, during a refresh the new token will reflect the current granted roles and it does not really matter if the RT was issued before with less or more roles as the resulting AT will reflect the actual granted roles. Regards. Pedro Igor On Mon, Nov 26, 2018 at 6:02 AM Stian Thorgersen wrote: > I think it's better if the old role is just removed. If you think about it > the new access token is sent to a service in most cases and the service > only has that new token as a reference for what roles the user has anyways. > > I don't understand what you mean about "it is sufficient to check consents > rather than roles". Both need to be checked, always. Consents limits the > access, while role is the permissions the user/client have. > > On Mon, 26 Nov 2018 at 08:53, Marek Posolda wrote: > > > Yes, it is updated. And new token can contain some more roles, which > > weren't presented before on the old refresh token. However if the > newToken > > doesn't contain any role, which was present in the old refresh token, > then > > refreshToken request is rejected ATM. That's what I think is not great > > behaviour as it is sufficient to check consents rather than roles. > > > > Marek > > > > On 26/11/2018 08:46, Stian Thorgersen wrote: > > > > If I'm not mistaken the token is already updated with new roles today. > > > > On Mon, 26 Nov 2018 at 08:44, Stian Thorgersen > > wrote: > > > >> +1 > >> > >> On Wed, 14 Nov 2018 at 09:09, Marek Posolda > wrote: > >> > >>> Right now, during each token refresh, we're verifying if the newly > >>> refreshed access token still contains all the roles, which were present > >>> in the refresh token. If not, the refresh token is rejected. > >>> > >>> I wonder if this check can be removed? This will also allow us to > remove > >>> the roles (realm_access and resource_access claims) from the refresh > >>> token. Anyone knows a reason if this check can't be removed? > >>> > >>> I think the reason why this check was originally added is due the > >>> consent. Previously we did not have clientScopes and the consents on > the > >>> consent screen were represented by individual roles and > protocolMappers. > >>> However with clientScopes, this seem to be obsolete IMO. > >>> > >>> During token refresh, we should check that consents represented by > >>> clientScopes in the refresh token were not revoked by the user (or > >>> admin). If they were rejected, the refresh token should be rejected. > >>> We're doing this. However if some individual role was removed from the > >>> user (or from the role scope mappings), I don't see an issue with > >>> successfully refresh token and just ensure that the revoked role is not > >>> in the new token anymore. > >>> > >>> WDYT? > >>> > >>> Marek > >>> > >>> _______________________________________________ > >>> keycloak-dev mailing list > >>> keycloak-dev at lists.jboss.org > >>> https://lists.jboss.org/mailman/listinfo/keycloak-dev > >>> > >> > > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From mposolda at redhat.com Tue Nov 27 01:48:38 2018 From: mposolda at redhat.com (Marek Posolda) Date: Tue, 27 Nov 2018 07:48:38 +0100 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? In-Reply-To: References: <3345b194-9959-acfc-fd0a-57b3f0ca3feb@redhat.com> Message-ID: Dne 26. 11. 18 v 13:57 Pedro Igor Silva napsal(a): > Marek, please correct me if I wrong. > > What Marek is suggesting is remove role check entirely and only check > for user consents. The reason is that from an OAuth2 perspective we > *only* need to make sure that user consents are still valid. > > With client scopes, the user no longer consents access to individual > roles but scopes where the actually granted roles could depend on the > granted scopes. In case roles are granted directly to a user, during a > refresh the new token will reflect the current granted roles and it > does not really matter if the RT was issued before with less or more > roles as the resulting AT will reflect the actual granted roles. Yes, exactly Example scenario: - User authenticated to some client and the token was issued to him with roles ["role1", "role2"] - Admin removed the role "role1" from user role mappings (or from client scope role mappings of client) - Now refreshToken request is sent. I think at this moment new token can be issued, which won't contain "role1", but will contain just single role ["role2"] . What we're doing now is that refreshToken request is rejected due the TokenManager.verifyAccess and that's the behaviour, which I propose to change and remove this TokenManager.verifyAccess. Once that is removed, we will have expected behaviour (just "role2" will be present in the token). > > Regards. > Pedro Igor > > On Mon, Nov 26, 2018 at 6:02 AM Stian Thorgersen > wrote: > > I think it's better if the old role is just removed. If you think > about it > the new access token is sent to a service in most cases and the > service > only has that new token as a reference for what roles the user has > anyways. > > I don't understand what you mean about "it is sufficient to check > consents > rather than roles". Both need to be checked, always. Consents > limits the > access, while role is the permissions the user/client have. > I meant that refreshToken request should be rejected if it requires some clientScopes, which user doesn't have consent anymore. Which can happen if consent was rejected in the meantime. We're already doing it. Another example scenario: - User authenticated to some client and the token was issued to him. On the consent screen he approved scopes "profile" and "email". The token will contain those client scopes "profile email" - Consent was removed from the user (for example revoked by the user in account management) - RefreshToken request is sent. At this moment, refreshToken request should be rejected as user doesn't have required consents. And that's what we're doing. For roles, we don't need to reject the refreshToken request, but just remove the roles, which are not available anymore from the token as mentioned above. Marek > > On Mon, 26 Nov 2018 at 08:53, Marek Posolda > wrote: > > > Yes, it is updated. And new token can contain some more roles, which > > weren't presented before on the old refresh token. However if > the newToken > > doesn't contain any role, which was present in the old refresh > token, then > > refreshToken request is rejected ATM. That's what I think is not > great > > behaviour as it is sufficient to check consents rather than roles. > > > > Marek > > > > On 26/11/2018 08:46, Stian Thorgersen wrote: > > > > If I'm not mistaken the token is already updated with new roles > today. > > > > On Mon, 26 Nov 2018 at 08:44, Stian Thorgersen > > > > wrote: > > > >> +1 > >> > >> On Wed, 14 Nov 2018 at 09:09, Marek Posolda > > wrote: > >> > >>> Right now, during each token refresh, we're verifying if the newly > >>> refreshed access token still contains all the roles, which > were present > >>> in the refresh token. If not, the refresh token is rejected. > >>> > >>> I wonder if this check can be removed? This will also allow us > to remove > >>> the roles (realm_access and resource_access claims) from the > refresh > >>> token. Anyone knows a reason if this check can't be removed? > >>> > >>> I think the reason why this check was originally added is due the > >>> consent. Previously we did not have clientScopes and the > consents on the > >>> consent screen were represented by individual roles and > protocolMappers. > >>> However with clientScopes, this seem to be obsolete IMO. > >>> > >>> During token refresh, we should check that consents represented by > >>> clientScopes in the refresh token were not revoked by the user (or > >>> admin). If they were rejected, the refresh token should be > rejected. > >>> We're doing this. However if some individual role was removed > from the > >>> user (or from the role scope mappings), I don't see an issue with > >>> successfully refresh token and just ensure that the revoked > role is not > >>> in the new token anymore. > >>> > >>> WDYT? > >>> > >>> Marek > >>> > >>> _______________________________________________ > >>> keycloak-dev mailing list > >>> keycloak-dev at lists.jboss.org > >>> https://lists.jboss.org/mailman/listinfo/keycloak-dev > >>> > >> > > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From Chris.Brandhorst at topicus.nl Tue Nov 27 05:50:14 2018 From: Chris.Brandhorst at topicus.nl (Chris Brandhorst) Date: Tue, 27 Nov 2018 10:50:14 +0000 Subject: [keycloak-dev] SerializedBrokeredIdentityContext ProviderID is filled with IdP alias In-Reply-To: <9a593ecc-c99d-b03e-1cb2-2eab905dc807@redhat.com> References: <03181FD0-EF67-4B86-B79E-B759C5CFB789@topicus.nl> <9a593ecc-c99d-b03e-1cb2-2eab905dc807@redhat.com> Message-ID: Hi, I agree that the alias should be used, just not that the method used to get the alias is put in a field called identityProviderId, which is an existing but different property. Regards, Chris > On 13 Nov 2018, at 21:45, Marek Posolda wrote: > > Hi, > > the alias is here on purpose. Alias of identityProvider is guaranteed to be unique across the realm. This is not the case for providerId. For example you can have 3 SAML identity providers configured in your realm. Then all those 3 providers will have same providerId, so you won't know which one you want to work with. > > On the other hand, when you have alias, you can always lookup the providerId from it. > > Marek > > On 09/11/18 19:11, Chris Brandhorst wrote: >> Hi all, >> >> Redirect by Bruno from https://issues.jboss.org/browse/KEYCLOAK-8773: >> >> We came across the following. In SerializedBrokeredIdentityContext#serialize, the identityProviderId property is filled with the alias of the IdentityProviderModel, instead of (what we would expect) its providerId. >> >> Relevant line: >> https://github.com/keycloak/keycloak/blob/b478472b3578b8980d7b5f1642e91e75d1e78d16/services/src/main/java/org/keycloak/authentication/authenticators/broker/util/SerializedBrokeredIdentityContext.java#L300 >> >> We feel this behaviour is semantically incorrect: we were checking against this property in one of our authenticators, but our code did not work for another identity provider of the same type. After some digging we thus found that we were expecting the providerId (coded value) but were actually reading the alias (configured value). >> >> Simply throwing this in as a possible improvement. What do you think? >> >> Regards, >> Chris Brandhorst >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev > > From Chris.Brandhorst at topicus.nl Tue Nov 27 06:41:39 2018 From: Chris.Brandhorst at topicus.nl (Chris Brandhorst) Date: Tue, 27 Nov 2018 11:41:39 +0000 Subject: [keycloak-dev] Register new ProviderFactorys to Mappers Message-ID: <444BF0AA-EC5A-49B4-9B6B-9EC537871738@topicus.nl> We have developed a customised OIDCIdentityProviderFactory and OIDCIdentityProvider because some IdP does not fully adhere to the standards. However, when using this Provider, the UserAttributeMapper (and other mappers) are not used because they have a fixed list of COMPATIBLE_PROVIDERS. We would suggest adding a registerCompatibleProvider to the IdentityProviderMapper in order to extend the usage of these mappers. Just checking before we take the effort of creating a nice PR: is this something you would see fly? If yes, would you suggest changing COMPATIBLE_PROVIDERS to a List or a List and subsequently changing the getCompatibleProviders() implementations? Thanks, Chris From sthorger at redhat.com Tue Nov 27 12:02:50 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Tue, 27 Nov 2018 18:02:50 +0100 Subject: [keycloak-dev] Register new ProviderFactorys to Mappers In-Reply-To: <444BF0AA-EC5A-49B4-9B6B-9EC537871738@topicus.nl> References: <444BF0AA-EC5A-49B4-9B6B-9EC537871738@topicus.nl> Message-ID: I wonder if it would be better to have the identity provider list compatible mappers itself. On Tue, 27 Nov 2018, 12:51 Chris Brandhorst We have developed a customised OIDCIdentityProviderFactory and > OIDCIdentityProvider because some IdP does not fully adhere to the > standards. However, when using this Provider, the UserAttributeMapper (and > other mappers) are not used because they have a fixed list of > COMPATIBLE_PROVIDERS. > > We would suggest adding a registerCompatibleProvider to the > IdentityProviderMapper in order to extend the usage of these mappers. > > Just checking before we take the effort of creating a nice PR: is this > something you would see fly? If yes, would you suggest changing > COMPATIBLE_PROVIDERS to a List or a List > and subsequently changing the getCompatibleProviders() implementations? > > Thanks, > Chris > > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From sthorger at redhat.com Tue Nov 27 12:05:31 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Tue, 27 Nov 2018 18:05:31 +0100 Subject: [keycloak-dev] Remove TokenManager.verifyAccess method? In-Reply-To: References: <3345b194-9959-acfc-fd0a-57b3f0ca3feb@redhat.com> Message-ID: Sounds good to me. On Tue, 27 Nov 2018, 07:48 Marek Posolda Dne 26. 11. 18 v 13:57 Pedro Igor Silva napsal(a): > > Marek, please correct me if I wrong. > > What Marek is suggesting is remove role check entirely and only check for > user consents. The reason is that from an OAuth2 perspective we *only* need > to make sure that user consents are still valid. > > With client scopes, the user no longer consents access to individual roles > but scopes where the actually granted roles could depend on the granted > scopes. In case roles are granted directly to a user, during a refresh the > new token will reflect the current granted roles and it does not really > matter if the RT was issued before with less or more roles as the resulting > AT will reflect the actual granted roles. > > Yes, exactly > > Example scenario: > > - User authenticated to some client and the token was issued to him with > roles ["role1", "role2"] > > - Admin removed the role "role1" from user role mappings (or from client > scope role mappings of client) > > - Now refreshToken request is sent. I think at this moment new token can > be issued, which won't contain "role1", but will contain just single role > ["role2"] . What we're doing now is that refreshToken request is rejected > due the TokenManager.verifyAccess and that's the behaviour, which I propose > to change and remove this TokenManager.verifyAccess. Once that is removed, > we will have expected behaviour (just "role2" will be present in the token). > > > Regards. > Pedro Igor > > On Mon, Nov 26, 2018 at 6:02 AM Stian Thorgersen > wrote: > >> I think it's better if the old role is just removed. If you think about it >> the new access token is sent to a service in most cases and the service >> only has that new token as a reference for what roles the user has >> anyways. >> >> I don't understand what you mean about "it is sufficient to check consents >> rather than roles". Both need to be checked, always. Consents limits the >> access, while role is the permissions the user/client have. >> > I meant that refreshToken request should be rejected if it requires some > clientScopes, which user doesn't have consent anymore. Which can happen if > consent was rejected in the meantime. We're already doing it. Another > example scenario: > > - User authenticated to some client and the token was issued to him. On > the consent screen he approved scopes "profile" and "email". The token will > contain those client scopes "profile email" > > - Consent was removed from the user (for example revoked by the user in > account management) > > - RefreshToken request is sent. At this moment, refreshToken request > should be rejected as user doesn't have required consents. And that's what > we're doing. > > For roles, we don't need to reject the refreshToken request, but just > remove the roles, which are not available anymore from the token as > mentioned above. > > Marek > > >> On Mon, 26 Nov 2018 at 08:53, Marek Posolda wrote: >> >> > Yes, it is updated. And new token can contain some more roles, which >> > weren't presented before on the old refresh token. However if the >> newToken >> > doesn't contain any role, which was present in the old refresh token, >> then >> > refreshToken request is rejected ATM. That's what I think is not great >> > behaviour as it is sufficient to check consents rather than roles. >> > >> > Marek >> > >> > On 26/11/2018 08:46, Stian Thorgersen wrote: >> > >> > If I'm not mistaken the token is already updated with new roles today. >> > >> > On Mon, 26 Nov 2018 at 08:44, Stian Thorgersen >> > wrote: >> > >> >> +1 >> >> >> >> On Wed, 14 Nov 2018 at 09:09, Marek Posolda >> wrote: >> >> >> >>> Right now, during each token refresh, we're verifying if the newly >> >>> refreshed access token still contains all the roles, which were >> present >> >>> in the refresh token. If not, the refresh token is rejected. >> >>> >> >>> I wonder if this check can be removed? This will also allow us to >> remove >> >>> the roles (realm_access and resource_access claims) from the refresh >> >>> token. Anyone knows a reason if this check can't be removed? >> >>> >> >>> I think the reason why this check was originally added is due the >> >>> consent. Previously we did not have clientScopes and the consents on >> the >> >>> consent screen were represented by individual roles and >> protocolMappers. >> >>> However with clientScopes, this seem to be obsolete IMO. >> >>> >> >>> During token refresh, we should check that consents represented by >> >>> clientScopes in the refresh token were not revoked by the user (or >> >>> admin). If they were rejected, the refresh token should be rejected. >> >>> We're doing this. However if some individual role was removed from the >> >>> user (or from the role scope mappings), I don't see an issue with >> >>> successfully refresh token and just ensure that the revoked role is >> not >> >>> in the new token anymore. >> >>> >> >>> WDYT? >> >>> >> >>> Marek >> >>> >> >>> _______________________________________________ >> >>> keycloak-dev mailing list >> >>> keycloak-dev at lists.jboss.org >> >>> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> >>> >> >> >> > >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > > From sthorger at redhat.com Tue Nov 27 12:08:12 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Tue, 27 Nov 2018 18:08:12 +0100 Subject: [keycloak-dev] Issue with concurrent SSO login to same client in more browser tabs In-Reply-To: <9b2f1cf7-d146-d997-8c9a-b72a979a28e4@redhat.com> References: <4a54e894-3bf1-75e6-4a73-8dbd8aebf09c@redhat.com> <9b2f1cf7-d146-d997-8c9a-b72a979a28e4@redhat.com> Message-ID: On Mon, 26 Nov 2018, 09:04 Marek Posolda On 26/11/2018 08:54, Stian Thorgersen wrote: > > The ideal may be to create a code token. If it's less than 2000 characters > just send it as is. If it's more than we put it in the actionTokens cache > and just send a reference to it in the code param. > > I see. So it will be something like "hybrid" between both approaches. Was > also a bit thinking about it, but didn't in the end. ATM it is always > adding the item to actionTokens cache. Maybe it's possible to optimize it > and add the "hybrid" possibility, but not sure about it at this stage? > Maybe after new year? > +1 for the future. I guess one issue would be the single use aspect. Not sure if the reference should just be a uuid, or if it should be > something more to make sure it can't be guessed. The last point is also > relevant to reference tokens once/if we add support for that. > > ATM it is .. > > The userSessionId and clientUUID are needed, so if code was already used > (and is removed from actionTokens cache), it is still possible to lookup > userSession and remove clientSession from it as OIDC specs suggests (in > case that attempt of duplicate code use was detected). > > Not sure how big probability is to guess UUID for the very short-lived > code. It seems to me like kind of impossible thing. And if it's really > guessed, then when valid user will try to exchange the code, which attacker > already exchanged, the "code" will be expired (client removed from > userSession as pointed above). > uuid should be sufficiently secure, but there's a potential here for a brute force attack of sorts though. Marek > > > On Mon, 19 Nov 2018 at 11:49, Marek Posolda wrote: > >> Hi, >> >> I've sent PR https://github.com/keycloak/keycloak/pull/5736 to fix the >> issue in subject (corresponding JIRAs are KEYCLOAK-7774 KEYCLOAK-8438). >> The cause is that once the user is authenticated in the browser and has >> userSession, there is just 1 clientSession per the userSession+client. >> So in case of concurrent SSO login in more browser tabs, there can be an >> issue that each tab is writing it's state to the same clientSession, >> which causes conflicts (especially attributes like nonce, scope or >> redirectUri can be possibly different for each tab and shouldn't be >> shared). >> >> The possibility can be to revert back when we had more clientSessions >> per userSession+client. I think this is step back and has lots of other >> issues (memory consumption, more cluster and cross-dc writes, worse >> performance in general...). For the future, it will be rather ideal to >> remove clientSession entirely or reduce their size even more, as they >> will be needed for logout, but hopefully for nothing more. >> >> So the other possibility is to move most of the state to the "code" >> parameter and to the refreshToken. Each browser tab has it's own "code" >> and it's own refreshToken. Problem with the "code" is, that it's used as >> query parameter in the URL and hence has limits for it's size. It seems >> ideal is still to stick with 2000 characters per URL. And when >> redirectUri itself will be part of the code, it can be problematic as we >> don't know how the redirectUri provided by users will be big.... >> Fortunately refreshToken doesn't have this issue as it needs to be >> always sent in the POST request. >> >> So to solve the issue for "code", I've added an entry to the infinispan >> cache "actionTokens", which encapsulates needed state and it's supposed >> to be valid just for the very short time (between the >> AuthenticationResponse to the application and the time when application >> sends the code-to-token request) and it's lifespan corresponds to realm >> code lifespan (1 minute by default). In the code-to-token request, there >> is a call to "cache.remove" to remove the code. Infinispan caches >> (local, distributed and hotrod caches) fortunately guarantee that >> "remove(123)" is always successful just in 1 thread (Successful means >> that it returns previous state). So we still have guarantee for the >> single-use code. >> >> Marek >> >> _______________________________________________ >> keycloak-dev mailing list >> keycloak-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/keycloak-dev >> > > From apillai at zaizi.com Wed Nov 28 04:28:54 2018 From: apillai at zaizi.com (Aingaran Pillai) Date: Wed, 28 Nov 2018 09:28:54 +0000 Subject: [keycloak-dev] Interactive claims gathering flow Message-ID: Hi, We are looking at adding support for UMA2 interactive claims gathering flow to Keycloak (which I assume is currently not in the supported). We are a small consultancy that have implemented keycloak extensively but never extended it. Is this an area we can contribute developer time with some mentoring from the community? If so where would we get started? Regards Ainga -- This message should be regarded as confidential. If you have received this email in error please notify the sender and destroy it immediately. Statements of intent shall only become binding when confirmed in hard copy by an authorised signatory.? Zaizi Ltd is registered in England and Wales with the registration number 6440931. The Registered Office is Kings House, 174 Hammersmith Road, London W6 7JP. From psilva at redhat.com Wed Nov 28 06:20:28 2018 From: psilva at redhat.com (Pedro Igor Silva) Date: Wed, 28 Nov 2018 09:20:28 -0200 Subject: [keycloak-dev] Interactive claims gathering flow In-Reply-To: References: Message-ID: Hi Ainga, Nice to see such interest from your part. As you know, we don't support this specific part of UMA specs. The reason is that we did not have much demand from the community until now. However, to overcome the lack of claims gathering in our implementation, to provide a solution that could help non-UMA use cases, and in order to still allow permissions to be evaluated based on arbitrary claims, we allow resource servers to push claims to Keycloak so policies can use these claims to make their decisions. I do believe that your proposal would be a great addition to Keycloak, where these claims could be "gathered" more dynamically based on some user-defined flow, all that managed by Keycloak. I think it is also a step forward to step-up authentication and authorization ... I think the most challenging part of this capability is how we configure the flow in Keycloak, what we would provide OOTB (e.g.: ask 2-fator, questionnaire, etc) and how to extend Keycloak to support custom flows. Another important aspect is related to the PCT and how to manage it properly, and securely. So, how to get started ... I would suggest you to start implementing something based on your requirements and use case. I can help you during this process. Once we define this initial scope and impl we can start discussing how to make the solution generic/flexible enough to address more requirements. FYI, we have this JIRA [1]. Please, put there your requirements and use case and let's start a discussion around this. [1] https://issues.jboss.org/browse/KEYCLOAK-6868 Thanks. Pedro Igor On Wed, Nov 28, 2018 at 7:31 AM Aingaran Pillai wrote: > Hi, > > We are looking at adding support for UMA2 interactive claims gathering flow > to Keycloak (which I assume is currently not in the supported). We are a > small consultancy that have implemented keycloak extensively but never > extended it. Is this an area we can contribute developer time with some > mentoring from the community? If so where would we get started? > > Regards > Ainga > > -- > > This message should be regarded as confidential. If you have received this > email in error please notify the sender and destroy it immediately. > Statements of intent shall only become binding when confirmed in hard copy > by an authorised signatory. > > > Zaizi Ltd is registered in England and Wales > with the registration number 6440931. The Registered Office is Kings > House, > 174 Hammersmith Road, London W6 7JP. > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev From alistair.doswald at elca.ch Thu Nov 29 04:33:32 2018 From: alistair.doswald at elca.ch (Doswald Alistair) Date: Thu, 29 Nov 2018 09:33:32 +0000 Subject: [keycloak-dev] Keycloak testsuite artifacts on maven, for module testing Message-ID: <59b2788fe019432c9c46236198a92d93@elca.ch> Hello, Are the keycloak testsuite artifacts pushed to a public repository? Or if not, would it be possible to publish them alongside the other keycloak artifacts? We are currently updating the cloudtrust keycloak modules to the latest version of keycloak, and as a part of that we are moving the tests from mocks to arquillian. Since there's a lot of great work already done, we reuse the keycloak testsuite artifacts for this. For our purposes this is fine (we have them cached in our local repository), but for anybody who wishes to build our modules from github it's a bit more cumbersome. On a more general level, it would probably also help other module developers who wish to unit test with arquillian. Best regards, Alistair From sthorger at redhat.com Fri Nov 30 03:30:42 2018 From: sthorger at redhat.com (Stian Thorgersen) Date: Fri, 30 Nov 2018 09:30:42 +0100 Subject: [keycloak-dev] Keycloak testsuite artifacts on maven, for module testing In-Reply-To: <59b2788fe019432c9c46236198a92d93@elca.ch> References: <59b2788fe019432c9c46236198a92d93@elca.ch> Message-ID: Can you add a bit more details please? What modules and how are you using them? On Thu, 29 Nov 2018, 10:34 Doswald Alistair Hello, > > Are the keycloak testsuite artifacts pushed to a public repository? Or if > not, would it be possible to publish them alongside the other keycloak > artifacts? > > We are currently updating the cloudtrust keycloak modules to the latest > version of keycloak, and as a part of that we are moving the tests from > mocks to arquillian. Since there's a lot of great work already done, we > reuse the keycloak testsuite artifacts for this. For our purposes this is > fine (we have them cached in our local repository), but for anybody who > wishes to build our modules from github it's a bit more cumbersome. On a > more general level, it would probably also help other module developers who > wish to unit test with arquillian. > > Best regards, > > Alistair > _______________________________________________ > keycloak-dev mailing list > keycloak-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/keycloak-dev > From josh.cain at redhat.com Fri Nov 30 14:39:46 2018 From: josh.cain at redhat.com (Josh Cain) Date: Fri, 30 Nov 2018 13:39:46 -0600 Subject: [keycloak-dev] Wildcard for Valid Redirect URI Hostname In-Reply-To: References: Message-ID: Dredging this one up again - I've had a couple more requests and instances in which this would be useful... This still a hard "no"? we're evaluating workarounds at this point that involved doing the redirect checking and CORS in authenticators and just wildcarding the Keycloak constructs since they're not flexible enough for what we need... Josh Cain | Senior Software Applications Engineer *Identity and Access Management* *Red Hat* On Fri, Sep 23, 2016 at 4:05 AM Stian Thorgersen wrote: > > > On 22 September 2016 at 22:54, Josh Cain wrote: > >> On Thu, Sep 22, 2016 at 2:27 AM, Stian Thorgersen >> wrote: >> >>> >>> >>> On 21 September 2016 at 16:10, Josh Cain wrote: >>> >>>> On Wed, Sep 21, 2016 at 1:12 AM, Stian Thorgersen >>>> wrote: >>>> >>>>> >>>>> >>>>> On 20 September 2016 at 16:15, Josh Cain wrote: >>>>> >>>>>> So I certainly get that we want to be as close to the spec as >>>>>> possible - wholeheartedly agree. However, I'd also like to reiterate that >>>>>> the main purpose of this is for lower/developer environments in which there >>>>>> are a large number of developers who are frequently spinning up sanboxes >>>>>> with apps that need SSO capabilities. Unless I want to open up the GUI in >>>>>> these environments to the world, I'm left without a good CM option for >>>>>> Keycloak. Any suggestions on the management of this? Right now I'm >>>>>> looking at a high amount of manual overhead, or scripting it out with some >>>>>> one-off config scripts that I'll have to wind up maintaining. Neither >>>>>> option sounds appealing. >>>>>> >>>>> >>>>> +1 This is a use-case we need to find a solution to >>>>> >>>> >>>> Cool. Keep me posted - in the meantime I've started cobbling together >>>> a few JAXRS scripts against the admin endpoint, but would ideally like >>>> something more CM-y. Maybe something like ansible integration... >>>> >>>>> >>>>> >>>>>> >>>>>> Hope you didn't get the wrong impression from the PR - I noted a >>>>>> javascript library that was shared across several pages within a number of >>>>>> subdomains. All pages share a similar look and feel, but due to the nature >>>>>> of the content and topic can live at different subdomains or even have >>>>>> slightly different page content implementations. Are we really going to >>>>>> make the assertion that a 'client' cannot span subdomains? That seems to >>>>>> be the implication here. And if so, is that necessarily more 'secure', or >>>>>> does that just mean that implementers could simply favor a single domain >>>>>> name with varying paths instead of categorically organized subdomains? >>>>>> Seems like an implementation detail that can easily be circumvented and >>>>>> does not inherently make an enclave more or less secure. >>>>>> >>>>> >>>>> A shared JavaScript library is not an client/application it's a >>>>> library. Not sure how you can argue that it's a client. A client has more >>>>> than just a redirect uri. It has: >>>>> >>>>> * Base URL - so users can find the application. This will be more >>>>> useful in the future once we introduce a SSO landing page and provide links >>>>> to applications from the account management console >>>>> * Consent - clients that require consents should allow users to give >>>>> consent per-application, not per-library >>>>> * Audit/log - audit and log both in admin console and account >>>>> management relies on knowing what application, not what library, accessed a >>>>> users account >>>>> >>>>> I really think you are misusing the concept of a client when you are >>>>> using a client for a library and I disagree that this is a valid use-case. >>>>> You are doing something wrong here. >>>>> >>>> >>>> Thanks for further examining this use case, and I'm certainly open to >>>> hearing you on this one if we're 'doing something wrong.' I do have some >>>> further questions clarifying what that 'something' is. >>>> >>>> - Where does the Base URL requirement come from? I've not seen >>>> that in any of the specifications. Is it more of a pragmatic >>>> best-practice-ish kind of approach? If so, do we have evidence of >>>> industry-wide adherence such that we can enforce it with a product? >>>> - Let me make sure I understand your point about mis-using a >>>> javascript 'library'. It feels like you're indicating that something like >>>> a javascript status bar that uses keycloak.js can share the same 'client' >>>> if, and only if, they share the same domain. So to illustrate, this would >>>> be allowed: >>>> >>>> ? >>>> >>>> ?Since the above pages share the same 'Base URL', they may rightfully >>>> be considered as 'valid' by Keycloak. However, according to the current >>>> Keycloak implementation, the below diagram demonstrates how the same >>>> application would *not* be allowed to delineate itself with the use of >>>> subdomains: >>>> >>>> ? >>>> >>>> ?This constrains seems superficial for this use case. Am I >>>> understanding this correctly? >>>> >>>> Again, I would contest that a logical 'application' can be comprised of >>>> pages split across subdomains. What's more, sharing the same base URL >>>> provides no guarantee of proper granularity for definition of a single >>>> 'application'. >>>> >>> Your example there makes sense to me and I agree that in this case it >>> could make sense to use the same client across multiple subdomains. I >>> assumed you had a login status library that was reused on different >>> applications. >>> >>> That doesn't justify having a wildcard for subdomain though. You should >>> have separate redirect uris for each subdomain. >>> >> >> I think we might have to just agree to disagree on this one. I think >> that there remains a justification for wildcarding a subdomain since it can >> be secured properly and would save on administrative burden. Same use case >> for wildcards in the path, just a different URL element. >> >>> >>>>> >>>>>> >>>>>> I completely agree with your argument that we should be striving for >>>>>> the finest level of granularity with respect to client definition. I >>>>>> understand the intentional segregation of logical clients by the >>>>>> specification so as to keep one compromised client from affecting the >>>>>> entire SSO ecosystem. However, I do think that there is a solid case for a >>>>>> single 'client' that does stuff like spans subdomains, and that such a >>>>>> client could be used in a secure manner. >>>>>> >>>>> >>>>> Can you give me a real example of where an application has multiple >>>>> subdomains? I just don't see it. >>>>> >>>> >>>> Sure. amazon.com uses smile.amazon.com for its charitable donation >>>> giving. At the end of the day it's exactly the *same* site, but with >>>> slightly different content. Same "Application", but residing on a >>>> different subdomain. Could probably crawl some frequently used sites to >>>> find more, but that one came to mind first. >>>> >>> >>> Actually I think that's a bad example and in that case it should be two >>> separate clients. >>> >>> >> >> Really? So an app that has almost *exactly* identical function with some >> stylistic and business rule differences deserves to be treated as a >> different client altogether. >> >> Will kindly disagree, but note that there's also disagreement on this one >> in implementations across the internet. For instance, Stack overflow >> treats each different topic's forum as a client, and these happen to be >> delineated by subdomains (however, notifications are shared across all >> sites which is a bit of a mixed message if you asked me). Whereas github ( >> gist.github.com), Facebook (m.facebook.com, touch.facebook.com, etc), or >> Amazon (smile.amazon.com) will let a single app/account span subdomains. >> >> I suppose the point was not so much to argue about which way is the >> purest implementation, but more to align product features with valid, >> real-world use cases. >> > > No point in discussing that any further you're right. End of the day it > doesn't matter as you've convinced me that an app can span multiple > subdomains. > > >> >> >>> >>>> Are there any standards/restrictions/stated best practices against >>>> this? This is the first time I've run up against problems with subdomains >>>> used in this way, but I'm certainly open to hearing if it's in violation of >>>> one of the above. >>>> >>> >>> OIDC for one says simple string matching for redirect uris. I don't have >>> any issue with splitting a client into subdomains if that makes sense >>> (didn't think it did, but you've convinced me). My issue was purely with >>> accepting wildcard for the subdomain as that allows all subdomains, not a >>> clearly specified set. >>> >> >> See above - don't see how we can allow wildcards in path for pragmatic >> purposes (outside the spec) but exclude the domain from the same >> treatment. I'm for allowing both. >> > > To be honest we shouldn't have had in the path either. We should never > have had the wildcard in the first place. It's down to a slightly less than > optimal implementation of our adapters. They use any current URI as the > redirect URI, but they should have had a specific callback URI > ('.../app/oidc-callback' or something) that is the only callback URI for > the app. The specific path should have been encoded into the state variable > instead and once authenticated the adapter should forward to that page. > That reduces the chance of any malicious code and especially any js > snippets from intercepting the callback. > > You could for instance using something similar in your app. Have a > callback for all subdomains then redirect once you've set cookies > accordingly. However, you do need a list of subdomains for an app to set a > cookie, so that kinda implies you need a static list of subdomains involved > in one "app" in either case. > > >> >> Will take this one as a hard 'no' since the discussion has been ongoing >> for so long. I think all the points are out there and have been fleshed >> out; no use in beating a dead horse. Thanks again for the good discussion >> - has been educational for me and more importantly very amiable ;-) >> >> I do have some follow-up questions on the client registration >> functionality in Keycloak. Another thread perhaps? >> > > Yep > > >> >> >>> >>> >>>> >>>>> >>>>>> >>>>>> At the end of the day, it feels like we're trying to force a >>>>>> definition on what is a client. The discussion seems to acknowledge that >>>>>> 'real world' application of this spec find wildcards useful (as your >>>>>> suggestion for supporting them in the path), however the manner in which >>>>>> they're used appropriately is up for debate. If we're living outside the >>>>>> spec anyway, do we really have a firm leg to stand on for the assertion >>>>>> that clients can have different paths but not subdomains? I don't see a >>>>>> solid reason for this one. >>>>>> >>>>> >>>>> We shouldn't have had the wildcard in the first place. The reason we >>>>> need it is that our adapters use the current path for the application as >>>>> the redirect-uri. In other OIDC providers you are limited to a simple >>>>> string matching in which case it's usual to have a callback endpoint and >>>>> encode the path in the state parameter. >>>>> >>>>> >>>>>> >>>>>> Some other thoughts I had on this that might be useful: >>>>>> >>>>>> - Some of the rub here is that maintaining a list of valid >>>>>> redirects for something like string matching is a CM nightmare >>>>>> (particularly in dev-ish environments). Something like an SPI to drop an >>>>>> implementation in here where I can apply a little more powerful logic would >>>>>> also do the job. Could this be used nefariously or poorly to circumvent >>>>>> the specification? yeah, sure - but so can Authenticators, and they're >>>>>> seen as a useful tool whereby developers can extend necessary functionality. >>>>>> - Would you also consider something like a 'development mode' >>>>>> flag that allowed for different options such as wildcards in different URL >>>>>> parts? Would have to add a little more validation to define what is and is >>>>>> not allowed, but would be useful for this case. >>>>>> >>>>>> I had the idea of an SPI or a developer mode, but ideally we'd find >>>>> another way to deal with this. >>>>> >>>>> Have you looked at dynamic client registration by the way? That allows >>>>> registering clients without UI access and with a limited initial access >>>>> token. We're also soon going to have a client registration CLI that allows >>>>> doing this. >>>>> >>>> >>>> I'll dig into that more - I've not taken more than a cursory glance at >>>> it. If we have more fine-grained control over token/client access it could >>>> certainly be useful. >>>> >>>> >>>>> >>>>> >>>>>> Thanks for good the discussion. As always, learning much and >>>>>> enjoying it! >>>>>> >>>>>> Josh Cain | Software Applications Engineer >>>>>> *Identity and Access Management* >>>>>> *Red Hat* >>>>>> +1 256-452-0150 >>>>>> >>>>>> On Tue, Sep 20, 2016 at 1:20 AM, Stian Thorgersen < >>>>>> sthorger at redhat.com> wrote: >>>>>> >>>>>>> I appreciate this feature might be useful, so there's no need to >>>>>>> discuss that aspect. The only issue I have with this PR is with regards to >>>>>>> security and especially as it enables doing the "wrong" thing. >>>>>>> >>>>>>> With regards to redirect URIs with confidential clients they are >>>>>>> still important, but not quite as important as they are for public client. >>>>>>> This means redirect URIs can typically be more flexible with confidential >>>>>>> clients without a significant risk. >>>>>>> >>>>>>> For public clients it's very important to lock these down as much as >>>>>>> possible as they are the ONLY way to prevent malicious clients to gain >>>>>>> access to the SSO session. This means we should actually tighten the >>>>>>> requirements for redirect URIs not further relax them. For public clients >>>>>>> the redirect URIs: >>>>>>> >>>>>>> * Should be as specific as possible. We should only allow wildcard >>>>>>> in the path. I believe we should introduce this for both public and >>>>>>> confidential clients. >>>>>>> * Require HTTPs unless it's http://localhost. This is not so easy >>>>>>> in development, so maybe we should have an option to run the server in >>>>>>> "unsafe" mode for developers. >>>>>>> >>>>>>> Here's a quote from the OIDC spec around this: >>>>>>> >>>>>>> *"REQUIRED. Redirection URI to which the response will be sent. This >>>>>>> URI MUST exactly match one of the Redirection URI values for the Client >>>>>>> pre-registered at the OpenID Provider, with the matching performed as >>>>>>> described in Section 6.2.1 of [RFC3986] (Simple String Comparison). The >>>>>>> Redirection URI SHOULD use the https scheme; however, it MAY use the http >>>>>>> scheme, provided that the Client Type is confidential, as defined in >>>>>>> Section 2.1 of OAuth 2.0, and provided the OP allows the use of http >>>>>>> Redirection URIs in this case. The Redirection URI MAY use an alternate >>>>>>> scheme, such as one that is intended to identify a callback into a native >>>>>>> application."* >>>>>>> >>>>>>> Looking at your comments on the PR it worries me slightly that you >>>>>>> have a shared client for a "library". A library is not a client. A client >>>>>>> is an instance of an application. Sharing the client will have impact on >>>>>>> audit, what clients a user believes they are authenticated to. With regards >>>>>>> to wildcard to allow any subdomains that is scary as your allowing any >>>>>>> piece of code running on any subdomain within your domain to authenticate >>>>>>> via that particular client. That could be an infected forum, something any >>>>>>> user has executing, etc.. As long as the redirect URI permits it an >>>>>>> application can obtain a token for a client for a user that is >>>>>>> authenticated without the user knowing about it. Unless you enable consent >>>>>>> that is, but if the user used the "real" client they would have given >>>>>>> consent and the malicious client on a different subdomain can take >>>>>>> advantage of it. >>>>>>> >>>>>>> In summary my opinion is that we can't accept this PR and that we >>>>>>> further: >>>>>>> >>>>>>> * Allow wildcard only in path. This is actually still looser than >>>>>>> the OIDC spec mandates as it requires a simple string comparison. >>>>>>> * Require HTTPS (or custom scheme) for public clients. We may need a >>>>>>> development mode that disables this. >>>>>>> >>>>>>> >>>>>>> >>>>>>> On 19 September 2016 at 16:50, Josh Cain >>>>>>> wrote: >>>>>>> >>>>>>>> Per KEYCLOAK-3585: >>>>>>>> >>>>>>>> Currently, valid redirect URI hostnames allow for wildcards at the >>>>>>>> end like so: >>>>>>>> >>>>>>>> http://www.redhat.com/* >>>>>>>> >>>>>>>> I'm managing several environments where clients need 'n' number of >>>>>>>> available redirect URI's with different hostnames, I.E. >>>>>>>> >>>>>>>> http://developer1.env.redhat.com >>>>>>>> >>>>>>>> http://developer2.env.redhat.com >>>>>>>> >>>>>>>> http://developer3.env.redhat.com >>>>>>>> >>>>>>>> Would really help to have the ability to wildcard hostnames too, >>>>>>>> I.E.: >>>>>>>> >>>>>>>> http://*.env.redhat.com >>>>>>>> >>>>>>>> >>>>>>>> I've submitted #3241 >>>>>>>> to address this >>>>>>>> issue, but there seem to be some concerns about allowing wildcards in other >>>>>>>> parts of the URL. See the PR for a more fleshed out discussion, but wanted >>>>>>>> to start a thread here on the mailing list. Particularly with respect to: >>>>>>>> >>>>>>>> - Does anyone have need of this feature or would find it useful? >>>>>>>> - Should this kind of wildcard be allowed as a configuration >>>>>>>> option by Keycloak? >>>>>>>> >>>>>>>> Josh Cain | Software Applications Engineer >>>>>>>> *Identity and Access Management* >>>>>>>> *Red Hat* >>>>>>>> +1 256-452-0150 >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> keycloak-dev mailing list >>>>>>>> keycloak-dev at lists.jboss.org >>>>>>>> https://lists.jboss.org/mailman/listinfo/keycloak-dev >>>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: javascriptlibpath.png Type: image/png Size: 63746 bytes Desc: not available Url : http://lists.jboss.org/pipermail/keycloak-dev/attachments/20181130/d44a2428/attachment-0002.png -------------- next part -------------- A non-text attachment was scrubbed... Name: javascriptlibdomain.png Type: image/png Size: 73920 bytes Desc: not available Url : http://lists.jboss.org/pipermail/keycloak-dev/attachments/20181130/d44a2428/attachment-0003.png From jramos at redhat.com Fri Nov 30 14:52:26 2018 From: jramos at redhat.com (Joao Paulo Ramos) Date: Fri, 30 Nov 2018 17:52:26 -0200 Subject: [keycloak-dev] Issue with CORS on Keycloak (RH-SSO) Message-ID: Hi guys, Sorry if it's not the correct place to make this question (please guide me to the correct place). I'm facing some problems with CORS when using rh-sso 7.1. I'm using the following environment: - JBoss EAP 7.1 with Resteasy in the backend -> localhost:8080/accountmovement/api - ReactJS in the frontend -> localhost:3000 - RH-SSO (7.1 and 7.2) -> localhost:8180 The JBoss EAP is using the Wildfly/EAP Adapter from Red Hat, with the configurations made on the standalone.xml file as a subsystem: demo accountmovement-backend true true http://localhost:8180/auth EXTERNAL true I Already enabled the Web Origins to " * " in the RH-SSO Admin console for both of the clients I'm using. The error I receive is the following: "" Failed to load http://localhost:8080/accountmovement/api/accounts?_=1543522008489: Redirect from ' http://localhost:8080/accountmovement/api/accounts?_=1543522008489' to ' http://localhost:8180/auth/realms/demo/protocol/openid-connect/auth?response_type=code&client_id=accountmovement-backend&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Faccountmovement%2Fapi%2Faccounts?_%3D1543522008489&state=ce5ee16c-f5f7-4a9e-affd-3316c4fad78f&login=true&scope=openid' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. "" Do you have any idea for what can I do? If you need more information just let me know! Thank you, JO?O PAULO RAMOS BUSINESS FINANCE - DATA SCIENCE INTERN Red Hat Brasil jramos at redhat.com M: +55-11-96505-6159 From gideonray at gmail.com Fri Nov 30 18:49:21 2018 From: gideonray at gmail.com (Gideon Caranzo) Date: Fri, 30 Nov 2018 17:49:21 -0600 Subject: [keycloak-dev] passing saml authentication context to custom authenticator Message-ID: Hi Guys, Is there a way to get SAML authentication context in custom authenticators? In the code, looks like it's not possible since it is not set anywhere in AuthenticationSessionModel. So if this is true, what would be the best way to pass it considering it may contain multiple information? It can be set as client session note just like other values from SAML request, but there has to be a way to serialize and de-serialize it since it's a complex object. What approach do you recommend? Thanks, Gideon