Compare commits

...
350 Commits
Author SHA1 Message Date
vramik 55f90ff09f KEYCLOAK-8837 Adapt TS to be able to test migration from 7.2.5.GA (instead from 7.2.0.GA) 2018-11-19 18:06:33 +01:00
Cédric Couralet dc06a8cee3 Fix KEYCLOAK-8832 (#5735)
Avoid NullPointerException when browser sends "Origin" header and
allowedOrigin is null. This happens on chrome with admin console
2018-11-19 17:53:05 +01:00
Stian Thorgersen f3bf1456ab KEYCLOAK-8781 Mark OpenShift integration as preview. Fix issue in Profile where preview features was not enabled in preview mode. (#5738) 2018-11-19 17:32:21 +01:00
Hynek Mlnarik 548950ed8e KEYCLOAK-8756 Consider also required actions of AuthenticationSession 2018-11-19 16:04:43 +01:00
Marek Posolda f67d6f9660 KEYCLOAK-8482 Access token should never contain azp as an audience (#5719) 2018-11-19 14:38:41 +01:00
Stian Thorgersen a1d86fbce8 Prepare for RH-SSO 7.2.0.ER1 (#5729)
* Prepare for RH-SSO 7.2.0.ER1

* Update pom.xml
2018-11-19 14:33:20 +01:00
Stian Thorgersen 3756cf629b KEYCLOAK-7081 Fixes for manual/qr mode switches on login config otp page (#5717) 2018-11-19 14:32:28 +01:00
Takashi Norimatsu 0793234c19 KEYCLOAK-8460 Request Object Signature Verification Other Than RS256 (#5603)
* KEYCLOAK-8460 Request Object Signature Verification Other Than RS256

also support client signed signature verification by refactored token
verification mechanism

* KEYCLOAK-8460 Request Object Signature Verification Other Than RS256

incorporate feedbacks and refactor client public key loading mechanism

* KEYCLOAK-8460 Request Object Signature Verification Other Than RS256

unsigned request object not allowed

* KEYCLOAK-8460 Request Object Signature Verification Other Than RS256

revert to re-support "none"
2018-11-19 14:28:32 +01:00
Hynek Mlnarik 461dae20de KEYCLOAK-8731 Ensure password history is kept in line with password policy 2018-11-19 12:48:51 +01:00
Stefan Guilhen a3d4612edd KEYCLOAK-8854 Updated UserSessionPredicate.ExternalizerImpl to include the remember-me properties 2018-11-19 12:17:03 +01:00
mposolda 0533782d90 KEYCLOAK-7275 KEYCLOAK-5479 Faster offline sessions preloading at startup. Track lastSessionRefresh timestamps more properly by support bulk update to DB 2018-11-16 14:23:28 +01:00
Michael Gottlieb 3bdbbf41af KEYCLOAK-8702:Fix Offline Sessions requires column
Prevent RemoveDuplicateOfflineSessions from running when migration to 3.2.0 has been run.
This prevents running when the  database has already dropped CLIENT_SESSION_ID from  OFFLINE_CLIENT_SESSION table.
This change unblocks migrating from 3.2.0 to 4.4.0 and later.
2018-11-16 12:03:57 +01:00
Stan Silvert 0b36020bf5 KEYCLOAK-8759: Wrong RH-SSO name on Welcome Page 2018-11-15 13:00:55 -05:00
Leon Graser 85f11873c3 KEYCLOAK-8613 Group Membership Pagination 2018-11-15 17:54:07 +01:00
Gideon Caranzo 39bf08e1b9 KEYCLOAK-8783 also checked admin roles when realm admin client is specified 2018-11-15 14:23:18 +01:00
Gideon Caranzo 9f88abb022 KEYCLOAK-8783 only checked master and realm admin roles when roles are specified in imported realm 2018-11-15 14:23:18 +01:00
Boleslaw Dawidowicz 78b2067f73 List of adopters and contributors (#5709)
* List of adopters

* Update ADOPTERS.md
2018-11-15 08:14:38 +01:00
Thomas Darimont cf57a1bc4b KEYCLOAK-1267 Add dedicated SSO timeouts for Remember-Me
Previously remember-me sessions where tied to the SSO max session
timeout which could lead to unexpected early session timeouts.
We now allow SSO timeouts to be configured separately for sessions
with enabled remember-me. This enables users to opt-in for longer
session timeouts.

SSO session timeouts for remember-me can now be configured in the
tokens tab in the realm admin console. This new configuration is
optional and will tipically host values larger than the regular
max SSO timeouts. If no value is specified for remember-me timeouts
then the regular max SSO timeouts will be used.

Work based on PR https://github.com/keycloak/keycloak/pull/3161 by
Thomas Darimont <thomas.darimont@gmail.com>
2018-11-15 06:11:22 +01:00
vmuzikar 8c650f9f6a KEYCLOAK-8793 Fix backward compatibility testing for adapters 2018-11-14 22:35:47 +01:00
vramik 22d8fb17f5 KEYCLOAK-8771 add jboss-jsp-api_2.3_spec dependency to app-server-undertow 2018-11-14 22:34:14 +01:00
vmuzikar 6cee8b126b KEYCLOAK-8792 Stabilize and fix Admin Console UI tests for RH-SSO 2018-11-14 22:32:11 +01:00
Pedro Igor f5ae76d8e3 [KEYCLOAK-8768] - Policy evaluation tool failing when client is used and identity.getId is called 2018-11-14 19:16:41 -02:00
stianst e391328b5d Don't fail on JavaDoc errors 2018-11-14 20:51:54 +01:00
stianst ecd476fb10 Prepare for 4.7.0.Final 2018-11-14 20:10:59 +01:00
Hynek Mlnarik c3778e66db KEYCLOAK-8260 Improve SAML conditions handling 2018-11-14 20:09:22 +01:00
Martin Kanis 6a23eb19f5 KEYCLOAK-8166 2018-11-14 20:09:22 +01:00
Martin Kanis 72b23c1357 KEYCLOAK-8160 2018-11-14 20:09:22 +01:00
Martin Kanis 0cb6053699 KEYCLOAK-8125 2018-11-14 20:09:22 +01:00
vramik 6564cebc0f KEYCLOAK-7707 2018-11-14 20:09:22 +01:00
Bruno Oliveira da Silva a957e118e6 Redirect URLs are not normalized 2018-11-14 20:09:22 +01:00
mposolda 0897d969b1 KEYCLOAK-7340 2018-11-14 20:09:22 +01:00
mposolda 1b5a83c4f1 KEYCLOAK-6980 Check if client_assertion was already used during signed JWT client authentication 2018-11-14 20:09:22 +01:00
Martin Bartos RH f090b39e85 [KEYCLOAK-8411] Migrate ModelClass: ClientModelTest 2018-11-14 19:15:45 +01:00
vmuzikar 5b72bd8da6 KEYCLOAK-8791 Fix AggregatePolicyManagementTest Admin Console UI test 2018-11-14 09:00:36 +01:00
mhajas 602a6e201d KEYCLOAK-8660 Workaround photoz tests on EAP6 2018-11-13 15:57:46 +01:00
Stan Silvert 086dbae5ca KEYCLOAK-8604: Figure out how forms will be handled 2018-11-13 07:45:50 -05:00
Douglas Palmer 4f5b41c65b Update CD release version 2018-11-12 20:06:15 +01:00
Adil ARLI 28eb1007fb Add Turkish Language File (#5678)
* Add Turkish Language File

* Resolve typo

* Resolve typo

* Capital letters corrections.
2018-11-12 11:49:56 +01:00
Hynek Mlnarik 7703d81389 KEYCLOAK-7421 Support SAML cluster logout for Elytron SAML adapter 2018-11-09 21:06:50 +01:00
Pedro Igor cd96d6cc35 [KEYCLOAK-8694] - Mark Drools policy as tech preview 2018-11-09 11:08:49 -02:00
stianst 1ee6fd7130 KEYCLOAK-8619 Fix check-sso when there is no cookie 2018-11-09 10:36:31 -02:00
mhajas 6450a457d0 Run adapter tests in different group in Travis 2018-11-09 12:45:38 +01:00
mhajas 6d04247947 KEYCLOAK-8047 Make Photoz tests great: run them on undertow + make them
stable
2018-11-09 12:45:38 +01:00
vramik 29f8187978 KEYCLOAK-8770 add keycloak-wildfly-adduser dependency to base testsuite 2018-11-09 11:02:18 +01:00
Jacob van Lingen e7b7307b4f Update messages_nl.properties (#5677)
* Update messages_nl.properties

Updated it to latest keys.

* Update messages_nl.properties
2018-11-08 16:29:18 +01:00
Mohammad Sarbandi 5e1d85c9a8 Update README.md
fixed a typo in the readme.
2018-11-08 16:22:39 +01:00
vramik 560d76b7ee KEYCLOAK-6748 undertow saml adapter tests 2018-11-06 21:17:07 +01:00
Pedro Igor bce2aee144 [KEYCLOAK-8646] - Error deleting policies when admin events are enabled 2018-11-06 11:27:32 -02:00
Stan Silvert 94f2ce2eae KEYCLOAK-8250: Save not disabled properly in token settings 2018-11-06 07:58:57 -05:00
Stefan Guilhen 3be2c35561 KEYCLOAK-8528 Change getRelativePath to include the servlet path followed by the path info 2018-11-06 13:43:50 +01:00
rmartinc cbe59f03b7 KEYCLOAK-8708: Provide aggregation of group attributes for mappers 2018-11-06 13:42:38 +01:00
Torbjørn Skyberg Knutsen 36b0d8b80e KEYCLOAK-7166 Added the possibility of not logging out of remote idp on browser logout, by passing a query param containing the id of the identity provider 2018-11-06 13:39:19 +01:00
scranen 5880efe775 KEYCLOAK-4342 Make naming consistent 2018-11-06 10:28:06 -02:00
scranen e6b9364c39 KEYCLOAK-4342 PR comments 2018-11-06 10:28:06 -02:00
scranen 0c6b20e862 [KEYCLOAK-4342] Make adapter state cookie path configurable 2018-11-06 10:28:06 -02:00
Pedro Igor 327991bd73 [KEYCLOAK-8716] - Issue with caching resolved roles in KeycloakSession 2018-11-06 10:27:04 -02:00
Pedro Igor 234b7a06a1 [KEYCLOAK-7798] - Spring security adapter does not renew expired tokens 2018-11-06 10:26:40 -02:00
stianst 00cee1d8cf KEYCLOAK-8654 Update licenses 2018-11-01 08:52:39 +01:00
Stan Silvert d0f75c8766 KEYCLOAK-8541: Upgrade AngularJS to 1.6.10 2018-11-01 08:51:50 +01:00
vramik b2aa324ee4 KEYCLOAK-8631 skip AddUserTest on app-server-undertow 2018-10-31 18:08:42 +01:00
vramik 76e4253a21 KEYCLOAK-8670 remove support for migration.mode=import as there are separate tests 2018-10-31 18:07:20 +01:00
mposolda ffcd8e09e7 KEYCLOAK-8175 Possibility of clientScope not being used if user doesn't have a role 2018-10-31 18:04:41 +01:00
mposolda cfeb56e18a KEYCLOAK-8641 Remove aud from the authorization tickets 2018-10-31 13:31:26 +01:00
mposolda 9652748ba9 KEYCLOAK-8484 Remove audience client scope template 2018-10-31 11:11:02 +01:00
BaHwan Han 91c4bfa81c The Keycloak JS adapter should not mutate browser history state 2018-10-29 20:08:32 +01:00
Alex Szczuczko e843297238 KEYCLOAK-8673 Disable maven-plugin-plugin helpmojo
It's suddenly started breaking the build, not obvious why. Disabling it is the
easiest solution. It's not required for these plugins that are only needed to
serve the keycloak build itself.
2018-10-29 20:00:22 +01:00
Tomas Kyjovsky f5425f916a KEYCLOAK-8632 Configuration of keycloak server in performance testsuite fails 2018-10-29 19:32:57 +01:00
Pedro Igor f6943296c7 [KEYCLOAK-8489] - RPT request: Authorized Party's protocol mappers are being applied instead of the Audience's ones 2018-10-26 09:40:32 -03:00
vmuzikar 6bf91a3956 KEYCLOAK-8644 Fix and stabilize Admin Console UI Tests 2018-10-26 08:06:01 +02:00
vramik 4d2300f17e KEYCLOAK-8664 KEYCLOAK-8665 KEYCLOAK-8666 fix assertions in testsuite 2018-10-25 21:42:01 +02:00
vramik f449b8b454 KEYCLOAK-8637 Add support for OIDC multitenancy adapter test for jboss based containers 2018-10-25 20:45:45 +02:00
Graser Leon 9ef4c7fffd KEYCLOAK-8377 Role Attributes 2018-10-24 22:04:28 +02:00
Pedro Igor 460cdf4508 [KEYCLOAK-8617] - Permission cache not handling decisions from negative policies correctly 2018-10-24 15:03:22 -03:00
Pedro Igor 2af9d002b6 [KEYCLOAK-8172] - Evaluation not considering scopes inherited from parent resources 2018-10-24 12:50:27 -03:00
Stan Silvert 7e12b60158 KEYCLOAK-8140: User Fed table header doesn't span all rows 2018-10-24 11:07:43 -04:00
Pedro Igor a2b13715ed [KEYCLOAK-8625] - Saving client settings will cause always adding default authorization settings 2018-10-24 10:18:04 -03:00
Stan Silvert f55264499c KEYCLOAK-7700: Add realm broken when page width < 992px 2018-10-24 08:47:16 -04:00
Jan Lieskovsky f3796d2eb8 [KEYCLOAK-8452] Return the definition of the 'keycloak' cache-container
into the infinispan subsystem

Signed-off-by: Jan Lieskovsky <jlieskov@redhat.com>
2018-10-24 08:22:43 +02:00
Stan Silvert ec335629b4 KEYCLOAK: 8601: Evaluate REST/HTTP packages for React 2018-10-23 08:51:38 -04:00
mposolda c36b577566 KEYCLOAK-8483 Remove application from the aud claim of accessToken and refreshToken 2018-10-23 13:52:09 +02:00
Pedro Igor 6f8f8e6a28 [KEYCLOAK-8449] - Option to automatically map HTTP verbs to scopes when configuring the policy enforcer 2018-10-23 08:40:54 -03:00
Pedro Igor c536955b70 [KEYCLOAK-7826] - My resource pages does not support resources without scopes 2018-10-23 08:38:22 -03:00
Bruno Oliveira da Silva 7d195deece [KEYCLOAK-8607] mod_auth_mellon integration tests not compiling 2018-10-22 20:15:32 +02:00
Gideon Caranzo 7d85ce93bb KEYCLOAK-8555 queried only realms with user storage provider to speed up user storage sync bootstrap 2018-10-19 09:53:58 +02:00
vramikandMarek Posolda 7a96911a83 KEYCLOAK-8300 KEYCLOAK-8301 Wildfly 14 upgrade
Co-authored-by: Marek Posolda <mposolda@redhat.com>
2018-10-17 20:01:07 +02:00
wildloop 096d749411 Added missing key executeActionsBodyHtml 2018-10-17 19:04:00 +02:00
vramik 623d985e7f KEYCLOAK-8454 KeycloakHttpServerAuthenticationMechanism uses wrong status code when logout page not set 2018-10-17 19:03:24 +02:00
Stan Silvert 68ab08aa56 KEYCLOAK-8421: POC for account management extension 2018-10-17 09:29:42 -04:00
MICHEL Arnault (UA 2118) ab8789739f [KEYCLOAK-8580] Add Nginx certificate lookup provider 2018-10-16 07:53:18 +02:00
mposolda 60a8267576 KEYCLOAK-8530 KEYCLOAK-8531 Fix MigrationTest and migration from 2.5.5.Final and 3.4.3.Final 2018-10-15 16:38:24 +02:00
stianst 5f0424fb11 KEYCLOAK-8310 Change scheme option to alwaysHttps option 2018-10-15 14:00:00 +02:00
vmuzikar 393ff50b8d KEYCLOAK-6757 Fix Microsoft Social Login test 2018-10-15 12:57:31 +02:00
Stefan Guilhen 68a54abb09 KEYCLOAK-6757 Update MicrosoftIdentityProvider to use the Microsoft Graph endpoints 2018-10-15 12:46:15 +02:00
stianst 8cecbcffb8 KEYCLOAK-8556 Fix typo 2018-10-15 08:38:54 +02:00
Martin Bartos RH 102628dc59 [KEYCLOAK-4935] Migrate AddUserTest from old testsuite 2018-10-15 08:14:34 +02:00
stianst 11374a2707 KEYCLOAK-8556 Improvements to profile 2018-10-12 12:26:37 +02:00
mposolda 4483677cdd KEYCLOAK-8529 Fix most of adapter tests on EAP6 2018-10-12 12:01:33 +02:00
Gideon Caranzo 0e8d79bbfb KEYCLOAK-8554 checked if master realm exist instead of number of realms for new installation check 2018-10-12 09:43:41 +02:00
Tobias Gippert c71f6e2188 The Keycloak JS adapter should not create a new browser history entry,
when it is redirecting the user, unless the user is in the admin console.
2018-10-12 09:42:26 +02:00
Alex Szczuczko 371bca57aa Remove drools-bom dependencyExclusion from prod-arguments
6.x is no longer valid and causes product build failures since the community
was upgraded to Drools 7.x. This change will allow BOMREST to select the
version automatically based on the community version.
2018-10-12 09:41:05 +02:00
mposolda f254675a5e KEYCLOAK-8568 DemoServletsAdapterTest.testVersion is unstable on travis 2018-10-12 09:27:37 +02:00
Leon Graser 066bef744f KEYCLOAK-6658 Fine Grain Permissions via Java Client
Signed-off-by: Leon Graser <leon.graser@bosch-si.com>
2018-10-11 09:44:57 -03:00
Moritz Becker fbe3445c48 fix KEYCLOAK-8513 remove data dependency between testUpdateProfile and testGetProfile in org.keycloak.testsuite.account.AccountRestServiceTest 2018-10-11 08:08:51 +02:00
mposolda 5b51c000af KEYCLOAK-8481 Don't include empty resource_access in access token 2018-10-11 08:04:07 +02:00
stianst aaa33ad883 KEYCLOAK-8509 Improvements to session iframe 2018-10-10 21:01:05 +02:00
stianst 9be8bef575 KEYCLOAK-7920 Changes to native promises in JS adapter. Native promises have to be explicitly enabled and when they are old success/error functions are no longer supported. Internally we don't use native promises. 2018-10-10 21:00:19 +02:00
rmartinc 0a6f43c1a1 KEYCLOAK-8490: Direct grants returns invalid credentials when user has pending actions 2018-10-10 20:18:20 +02:00
Frank Schmager 6b59c2f44c try to register node during authentication attempt in filter
* PreAuthActionsFilter registers deployment during authentication attempt to enable, well,
  node registration if filter is used by itself (if no securityConstraints when using spring boot and spring security)
* deregistering node during clean shutdown
* added unit test
2018-10-09 10:30:37 -03:00
sebastienblanc fd0ab4a626 removing spring factories from core module 2018-10-09 14:17:33 +02:00
Toni Ristola 22d64368a6 KEYCLOAK-8191 Fixed DI that was not working 2018-10-09 08:22:43 -03:00
Pedro Igor 79ca722b49 [KEYCLOAK-7605] - Make sure Evaluation API is read-only 2018-10-09 08:09:29 -03:00
Takashi Mogi c3f1bd5a25 KEYCLOAK-8342 Add core-management module to standalone and standaloen-ha 2018-10-08 22:21:07 +02:00
mposolda 3ca386f223 KEYCLOAK-8148 Duplication of listed roles assigned through groups in userinfo endpoint 2018-10-08 22:18:06 +02:00
Sebastian Häni 00f4b54730 themes: add german messages to admin theme 2018-10-08 21:54:30 +02:00
Stan Silvert a8ab1fea58 KEYCLOAK-8420: Create Hello React 2018-10-08 15:43:35 -04:00
Pedro Igor 8e57cee30f [KEYCLOAK-8445] - Owner not granted with permissions when using only scope-based permissions 2018-10-08 09:57:21 -03:00
Hynek Mlnarik 7f1c03a122 KEYCLOAK-8462 Close delegates properly 2018-10-08 14:45:48 +02:00
Pedro Igor 6fd4a02f95 [KEYCLOAK-8444] - Error when producing KeycloakSpringBootConfigResolver from spring security configuration 2018-10-08 09:29:59 -03:00
Hynek Mlnarik 531ee3a1be KEYCLOAK-8494 Use c3p0 connection pool in testsuite 2018-10-08 14:24:56 +02:00
Mark True 28b6e4dd5b cleaning up to do PR 2018-10-08 09:16:53 +02:00
Moritz Becker f17b5f0f49 fix KEYCLOAK-7572 consistently perform duplicate user checks during account update only if email changes
Fix test
2018-10-05 09:35:05 +02:00
stianst 86a2f28561 KEYCLOAK-8310 Add support to set fixed scheme on fixed hostname provider 2018-10-05 09:34:17 +02:00
mposolda 0d9b1e73b8 KEYCLOAK-7855 Cannot reset Client Consent Screen Text 2018-10-04 21:00:48 +02:00
k-tamura fe0db7fe44 Update Japanese properties for 4.0 2018-10-04 20:59:38 +02:00
stianst 6ebc6c0354 KEYCLOAK-8437 Remove Keycloak demo dist 2018-10-04 20:54:23 +02:00
wildloop a82f0ab657 Translation to Polish language 2018-10-04 20:50:58 +02:00
Pedro Igor 0a6e22ba54 [KEYCLOAK-8412] - Upgrade to Drools 7.11.0.Final 2018-10-04 09:41:41 -03:00
Hynek Mlnarik 211774ccbc KEYCLOAK-7810 Fix NPE in Elytron SAML adapter 2018-10-04 14:38:45 +02:00
gbtec-igormartens c41bcddd8d Update UserResource.java
In my opinion, the old documentation does not match the actual behaviour of the resetPassword method.
2018-10-04 12:54:49 +02:00
mposolda 2a4cee6044 KEYCLOAK-6884 KEYCLOAK-3454 KEYCLOAK-8298 Default 'roles' and 'web-origins' client scopes. Add roles and allowed-origins to the token through protocol mappers 2018-10-04 12:00:38 +02:00
Stan Silvert dba513c921 KEYCLOAK-8419: Make most act mgt APIs only active in preview mode 2018-10-02 16:32:56 -04:00
Pedro Igor b4b3527df7 [KEYCLOAK-7950] - Fixes user pagination when using filtering users members of groups 2018-10-02 15:44:23 -03:00
Hynek Mlnarik 17a1a33987 KEYCLOAK-7740 Support parsing of xs:date type 2018-10-02 19:54:40 +02:00
mposolda 4b9b189016 KEYCLOAK-8008 Ensure InputStream are closed 2018-10-01 16:06:32 +02:00
Sebastian Laskawiec e1ecf94428 KEYCLOAK-6807 Refactor TestHelper 2018-10-01 09:39:42 -03:00
Pedro Igor 2da758ac86 [KEYCLOAK-6928] - Selecting first bearer if multiple values exists in authorization header 2018-10-01 09:36:10 -03:00
Martin Kanis efe6a38648 KEYCLOAK-6718 Auth Flow does not Check Client Protocol 2018-09-26 21:00:02 +02:00
stianst c3fc9e9815 Set version to 4.6.0.Final-SNAPSHOT 2018-09-26 20:58:41 +02:00
Pedro Igor 43f5983613 [KEYCLOAK-8289] - Remove authorization services from product preview profile 2018-09-26 18:27:27 +02:00
vramik 723ba42264 KEYCLOAK-8425 fix NPE during adapter cluster tests 2018-09-26 12:43:21 +02:00
Pedro Igor 081e9883e6 [KEYCLOAK-7659] - k_version not supporting cors 2018-09-25 11:50:17 -03:00
Pedro Igor df311b60b4 [KEYCLOAK-8168] - PEP is resolving claims twice under certain circumstances 2018-09-25 11:47:50 -03:00
Alex Szczuczko 0ff0dcecec KEYCLOAK-8378 Drop dependencyOverride for infinispan-core in prod-arguments.json
This will allow automated BOMREST alignment for the version configured in the
root keycloak POM, when built as the product.
2018-09-24 09:35:20 +02:00
Zed Spencer-Milnes eda09d2b32 Add documentation and logging for the default admin account in test suite 2018-09-21 14:36:42 +02:00
Takashi Norimatsu 340c8e8426 KEYCLOAK-8327 Token Introspect Test for Refresh Token Mistake 2018-09-21 11:38:04 +02:00
mposolda 3777dc45d0 KEYCLOAK-3058 Support for validation of "aud" in adapters through verify-token-audience configuration switch 2018-09-21 11:17:05 +02:00
Pedro Igor adf0a19f9d [KEYCLOAK-8133] - Can't Sucessfully inject a custom KeycloakSpringBootConfigResolver in the Keycloak Spring Boot Security Adapter 2018-09-20 11:11:12 -03:00
Douglas Palmer b748e269ec [KEYCLOAK-7435] Added code to delete a specific session and tests for session deletion 2018-09-20 15:57:58 +02:00
Christopher 25b390b2ae Fixing hyperlink content in german language
The hyperlink for emailVerificationBodyHtml should contain a short message and not the link itself
2018-09-20 15:48:15 +02:00
Jacob van Lingen 52b7fd8c45 Fix Dutch translation
'Overnieuw' is considered a colloquialism in Dutch at best, others considered it as just wrong.
2018-09-20 15:42:43 +02:00
vmuzikar 4268dd1777 KEYCLOAK-7742,KEYCLOAK-6332 Switch Admin Console UI tests to GeckoDriver 2018-09-20 10:32:59 +02:00
vramik 24b7d080af KEYCLOAK-8268 unify fuse70 and fuse71 modules into fuse7x module 2018-09-20 10:27:17 +02:00
Pedro Igor 39f0e4528a [KEYCLOAK-8270] - Cannot remove 'Not Before' or 'Not On or After' from a Time Policy 2018-09-19 09:47:22 -03:00
Pedro Igor 6b0bc0b3be [KEYCLOAK-8308] - Deprecate token_introspection_endpoint claim from OIDC discovery document 2018-09-19 09:46:50 -03:00
Hynek Mlnarik 2bf6d75e57 KEYCLOAK-8010 Improve handling of Conditions SAML tag 2018-09-19 14:00:28 +02:00
Rafael Weingärtner 3dd6f9cb85 Enable "DockerComposeYamlInstallationProviderTest" to run on Windows 2018-09-19 11:22:57 +02:00
Pedro Igor 044d153c37 [KEYCLOAK-8273] - Failed to evaluate permissions when in permissive mode and using UMA tickets 2018-09-18 18:59:15 -03:00
Pedro Igor 609c521c17 [KEYCLOAK-8281] - Deletion of client with token exchange policy leads to breaking errors 2018-09-18 18:58:45 -03:00
Hynek Mlnarikandwyvie 0b893d5634 KEYCLOAK-8187 Fix Undertow imports for Fuse
Co-Authored-By: wyvie <irum@redhat.com>
2018-09-18 16:54:03 +02:00
Pedro Igor aaf78297c9 [KEYCLOAK-7987] - Can't set authorization enabled when using kcreg 2018-09-18 10:00:16 -03:00
Pedro Igor 64f8fe4987 [KEYCLOAK-8070] - wrong expose headers when enable cors and policyenforcer 2018-09-17 17:02:15 -03:00
Stan Silvert e85a396572 KEYCLOAK-8016: js sometimes loaded out of order 2018-09-17 08:55:33 -04:00
mposolda 99a16dcc1f KEYCLOAK-6638 Support for adding audiences to tokens 2018-09-13 21:40:16 +02:00
Bruno Oliveira da Silva 8b6db21e56 [KEYCLOAK-8285] Remove user-storage-jpa and user-storage-simple from Keycloak repository 2018-09-13 20:50:09 +02:00
wyvie 01051016f5 [KEYCLOAK-8185] add clear method to exportimport resource 2018-09-13 11:54:28 +02:00
slominskir c4a651bcac KEYCLOAK-7270 - Support for automatically linking brokered identities 2018-09-12 18:50:35 +02:00
vmuzikar 62c1ffcb52 KEYCLOAK-8189 Fix broken Google Social Login test 2018-09-12 16:40:28 +02:00
vmuzikar 00da3e3669 KEYCLOAK-8190 Fix compilation errors in Node.js adapter UI tests 2018-09-12 16:40:28 +02:00
Johannes Knutsen d4a5c81034 KEYCLOAK-8146: Extract LocaleSelectorSPI to allow custom overrides of locale selection 2018-09-11 20:35:48 +02:00
stianst 26f257a6ac KEYCLOAK-8264 Update OpenShift Token Review endpoint to support additional algorithms and to update session last refresh on token introspection 2018-09-11 19:57:38 +02:00
stianst 12f3d2115d KEYCLOAK-8263 Add option to client to override access token timeout 2018-09-11 12:40:51 +02:00
stianst 24e60747b6 KEYCLOAK-7560 Refactor token signature SPI PR
Also incorporates:
KEYCLOAK-6770 ES256/384/512 providers
KEYCLOAK-4622 Use HS256 for refresh tokens
KEYCLOAK-4623 Use HS256 for client reg tokens
2018-09-11 08:14:10 +02:00
Takashi Norimatsu 5b6036525c KEYCLOAK-7560 Refactor Token Sign and Verify by Token Signature SPI 2018-09-11 08:14:10 +02:00
vramik bd4098191b KEYCLOAK-7604-rename-ids-saml-clients 2018-09-10 21:17:00 +02:00
Leon Graser df22c4d613 changed user and resource entity to fetch mode select with batch size 20 2018-09-10 20:31:04 +02:00
Pedro Igor 0561d73ae2 [KEYCLOAK-6285] - HTTP Challenge Authentication Flow 2018-09-10 19:02:49 +02:00
stianst bf758809ba KEYCLOAK-6229 OpenShift Token Review interface 2018-09-07 08:21:28 +02:00
stianst 1fb4ca4525 Set version to 4.5.0.Final 2018-09-06 20:08:02 +02:00
vmuzikar e59646aafb KEYCLOAK-8246 Disable Base UI tests by default 2018-09-06 14:56:57 +02:00
vmuzikar bd8510f4da KEYCLOAK-7925 Initial tests for the new Account Console 2018-09-06 09:59:28 +02:00
stianst c56e171f3a KEYCLOAK-7608 Check if themes dir is null in FolderThemeProvider 2018-09-06 08:52:17 +02:00
Hynek Mlnarik 812e76c39b KEYCLOAK-8163 Improve SAML validations 2018-09-05 15:47:03 +02:00
vramik 8761819b24 KEYCLOAK-8176 fix export issue for required action 2018-09-05 08:40:31 +02:00
Pedro Igor 47066e1b89 [KEYCLOAK-8012] - Fix offline session support in authorization services 2018-09-04 15:07:49 -03:00
Pedro Igor 6a0a1031a1 [KEYCLOAK-7754] - Fixing compat issues with UMA spec in RPT Introspection Provider 2018-09-04 11:41:09 -03:00
Pedro Igor 33efcc6b93 [KEYCLOAK-8142] - Fixing regression when setting path enforcement mode to disabled 2018-09-04 10:32:06 -03:00
Pedro Igor 2eddfd3ea8 [KEYCLOAK-7160] - Completely broken AuthZ Configs in IE 2018-09-04 14:40:14 +02:00
Dmitry Telegin bc8763ccf3 KEYCLOAK-7858 - OIDC servlet filter adapter OSGi support 2018-09-04 11:29:45 +02:00
Hynek Mlnarik 9f839f001f KEYCLOAK-8218 Do not clear SAML REDIRECT query parameters 2018-09-04 11:16:06 +02:00
June Zhang 237318dfd3 KEYCLOAK-7751 Auth welcome page 2018-09-04 07:55:08 +02:00
Hynek Mlnarik 5fe1905e4b KEYCLOAK-6803 Prevent duplicating required actions in JPA user storage 2018-09-03 19:42:18 +02:00
mposolda f0ba8f6591 KEYCLOAK-8139 Added wildfly-deprecated module for adapters testing. Remove wildfly9 and wildfly10 2018-09-03 08:56:09 +02:00
Hynek Mlnarik 54b5ec206e KEYCLOAK-8183 Improve authz caching for negative cases 2018-08-31 18:31:55 +02:00
mposolda befee75917 KEYCLOAK-8174 Admin console test for the "Client Scopes" tab of the client 2018-08-31 12:32:17 +02:00
mposolda 5ae126b10e KEYCLOAK-7584 Fix some admin console tests broken by adding clientScopes support 2018-08-31 12:32:17 +02:00
Johannes Knutsen c0b5c12dee KEYCLOAK-8147: Add support for Content-Security-Policy-Report-Only response headers 2018-08-31 10:38:56 +02:00
vramik 214a8e1fed KEYCLOAK-8176 fix requiredActionsPriority test 2018-08-31 10:25:28 +02:00
vramik f89637bd8f KEYCLOAK-8178 fix AdminEventTest 2018-08-30 15:16:33 +02:00
Hynek Mlnarik bee3894cdf KEYCLOAK-8150 Improve loading user list 2018-08-30 13:03:49 +02:00
vramik df76afb513 KEYCLOAK-8167 fix ExportImportTest on undertow 2018-08-29 15:18:24 +02:00
vramik c266e90a77 KEYCLOAK-6746 ability to skip adapter test 2018-08-29 14:40:44 +02:00
mposolda b70468341e KEYCLOAK-7470 Ability to order client scopes 2018-08-29 14:37:27 +02:00
mhajas 21b71e83dd KEYCLOAK-7161 Stabilize authz tests as they are running on undertow -> in Travis 2018-08-29 13:13:06 +02:00
mhajas ccba07a5c0 KEYCLOAK-7213 Make example tests running on app-server-undertow 2018-08-29 13:13:06 +02:00
Jani 42553cdc44 [KEYCLOAK-7695] Restore token_type and expires_in for implicit flow
As KEYCLOAK-6585 concerns only hybrid flow, this commit restores the behavior for implicit flow.

This commit partially reverts #5041 (061049e41a6b0e6fb45c75f05748023ad7ab7d92).
2018-08-29 13:00:57 +02:00
Hynek Mlnarik 8a7a545628 KEYCLOAK-7944 Remove duplicate offline client sessions 2018-08-29 10:55:38 +02:00
Pavel Drozd d37eb5d10b KEYCLOAK-8138 Fixed tests for product profile 2018-08-29 10:31:10 +02:00
AlistairDoswald 36837ae4b6 Added a ScriptMapper for SAML for KEYCLOAK-5520
Added mapper, tests and entry in the ProtocolMapper file.
This code is adapted from the following module: https://github.com/cloudtrust/keycloak-client-mappers
2018-08-29 09:39:30 +02:00
mposolda 31270e2f52 KEYCLOAK-7437 Support for prompt=consent 2018-08-29 08:35:29 +02:00
Pedro Igor 3ccffdb77e [KEYCLOAK-8145] - Configure keystore when running KeycloakServer using TLS 2018-08-29 08:33:16 +02:00
Johannes Knutsen 56c97407d4 KEYCLOAK-8152: Allow passing the current locale to OAuth2 identity providers 2018-08-28 15:52:23 +02:00
Grzegorz Grzybek bf7a173e1e [KEYCLOAK-7394] Change Content-Type to x-www-form-urlencoded for RealmAdminResource#testLDAPConnection 2018-08-28 04:56:08 -03:00
Hynek Mlnarik 2077975b1c KEYCLOAK-6411 Fix list of keywords on MySQL/MariaDB 2018-08-28 09:51:58 +02:00
mposolda e4d05a7852 KEYCLOAK-8127 Added support for app-server-eap71. Make sure ConsoleProtectionTest is executed just for app-server-eap71 2018-08-27 12:52:53 +02:00
6fc99cd749 KEYCLOAK-7594 Upgrade to Wildfly 13. Cross-DC: Upgrade to infinispan server 9.2.4 and JDG 7.2
Co-authored-by: Douglas Palmer <dpalmer@redhat.com>
Co-authored-by: stianst <stianst@gmail.com>
Co-authored-by: Hynek Mlnarik <hmlnarik@redhat.com>
2018-08-27 12:52:53 +02:00
vramik 01b0b6b345 KEYCLOAK-7975 fix updating execution with Oracle DB 2018-08-24 15:04:48 +02:00
Martin Kanis 59082e0b5f KEYCLOAK-7943 NPE when SAML User Property mapper is empty 2018-08-24 14:39:24 +02:00
vramik 9e072cb174 KEYCLOAK-8119 Migration tests doesn't reflect if authorization features is enabled or not 2018-08-24 14:38:36 +02:00
Pedro Igor c0508aded7 [KEYCLOAK-7757] - Deleting scopes in account console doesn't work 2018-08-24 09:35:52 -03:00
Pedro Igor 9882341ecf [KEYCLOAK-7725] - CORS should be set based on client making the request 2018-08-24 09:35:38 -03:00
Pedro Igor 3c2339ba33 [KEYCLOAK-4902] - Only set effect if result exists and removing ignore from tests 2018-08-24 09:34:39 -03:00
Hynek Mlnařík 457c6a9d80 KEYCLOAK-5226 Test with trusty image 2018-08-24 13:21:51 +02:00
Hynek Mlnarik 1f840b1fbc KEYCLOAK-8109 Fix getDOMElement 2018-08-24 10:03:33 +02:00
mhajas 694966b613 KEYCLOAK-8120 Fix NullPointerException in ClaimInformationPointProviderTest 2018-08-24 09:00:35 +02:00
Dan Hooper 0a8fca7ec4 Created common interface for parsed tokens in typescript declaration file 2018-08-23 16:14:17 -04:00
Frank Schmager 3e2e0ac91c Renamed factory and java doc 2018-08-22 16:39:55 +02:00
Frank Schmager b21e784826 ignoring bin/ directories instead of bin files 2018-08-22 16:39:55 +02:00
Frank Schmager dda365e002 initial exposing of BasicAuthRequestAuthenticator to make extensible 2018-08-22 16:39:55 +02:00
vmuzikar 653d3f4f5d KEYCLOAK-8093 Add IDs to HTML elements in new Account Console 2018-08-22 09:30:20 -04:00
Alex Szczuczko 3dcc106c59 KEYCLOAK-8054 Switch to BOMREST as the source for productized 3rd party versions
This will allow the versions to be kept up to date automatically by DA within PNC.

A side effect is fixing issues like KEYCLOAK-7896.

Also remove additional dependencyExclusions that can be filled by PME BOMREST
2018-08-22 10:24:07 +02:00
Martin Kanis 248654a75e KEYCLOAK-6706 E-mail verification won't let user back into the app 2018-08-21 16:30:15 +02:00
Grzegorz Grzybek fdc9882709 [KEYCLOAK-8101] Return just cached deployment to prevent NPE 2018-08-21 09:56:58 +02:00
Gregor Tudan b606a25684 KEYCLOAK-7991: add pagination params to the RoleResource 2018-08-21 08:19:33 +02:00
rmartinc 1b88eaf817 KEYCLOAK-8080 Audit the realm event configuration change 2018-08-20 21:01:38 +02:00
stianst dc8268b30c Update triggers for Docker Hub 2018-08-20 20:38:57 +02:00
Corentin Dupont b80701589c [KEYCLOAK-7804] - Option to return resource body 2018-08-20 13:07:29 -03:00
Martin Kanis d04791243c KEYCLOAK-7970-KEYCLOAK-7222 Add clientId to action tokens 2018-08-20 15:25:24 +02:00
Wolfgang Zenker c5f861a522 Make cli usable on FreeBSD 2018-08-20 09:08:02 +02:00
Alex Szczuczko b6d545b332 KEYCLOAK-7815 Set product.filename.version based on the value of product.rhsso.version
When `product.filename.version` is hardcoded to 7.2, it obviously doesn't
update when `product.rhsso.version` changes. By using
build-helper-maven-plugin, it's now derived automatically, and we shouldn't see
this issue pop up again for e.g. 7.4.
2018-08-20 09:06:45 +02:00
Alex Szczuczko a35ed671e6 KEYCLOAK-7480 Make fuse7 tomcat8 adapter community-only 2018-08-20 09:06:45 +02:00
Alex Szczuczko f0a2f7a675 KEYCLOAK-7480 Make fuse7 adapter's jetty94 conditional on the community profile
In commit d70859ef keycloak-pax-web-jetty94 was added.

org.keycloak:keycloak-jetty94-adapter:jar is a dependency of this module, and
isn't produced outside of the community profile. So, the jetty94 module here
must be consistent with that.
2018-08-20 09:06:45 +02:00
stianst 4cb9944067 Trigger Docker hub image on merge to master 2018-08-20 09:05:01 +02:00
Pedro Igor 625f613128 [KEYCLOAK-4902] - Using streams to process requested permissions and limit support for scope responses 2018-08-17 11:00:53 -03:00
stianst e406e8f1f0 KEYCLOAK-8069 Simplify config for fixed hostname provider 2018-08-17 14:47:14 +02:00
stianst 90bafee5eb Fixes to examples-dist for removed Fuse example 2018-08-15 16:57:23 +02:00
stianst ab77140454 KEYCLOAK-8036 Fix misplaced IdP buttons 2018-08-15 11:32:02 +02:00
stianst d1ae13c208 Fix product versions 2018-08-15 11:04:18 +02:00
Sebastian Laskawiec e9604a49e1 KEYCLOAK-8046 Prevent from sending Client twice 2018-08-14 17:35:37 +02:00
Hynek Mlnarik 645a72482b KEYCLOAK-8048 Fix testsuite compilation issue 2018-08-14 13:56:45 +02:00
Hiroyuki Wada 730377a843 KEYCLOAK-7528 Set Cache-Control and Pragma header in token endpoint 2018-08-14 11:41:12 +02:00
Stefan Guilhen f36e45cb10 [KEYCLOAK-4902] - Using streams to process scopes and cache improvements 2018-08-14 06:29:10 -03:00
Steffen Kreutz ed72097862 KEYCLOAK-5289 Add support for Google's hd parameter 2018-08-14 11:08:57 +02:00
Stefan Guilhen 0b95cdacb8 [KEYCLOAK-7885] Add user policy support to the policy API 2018-08-13 22:09:17 -03:00
Stefan Guilhen 1912a8acf4 [KEYCLOAK-7885] Fix javadoc/log message typos 2018-08-13 22:09:17 -03:00
vmuzikar 79774d2f07 KEYCLOAK-8035 Fix failing GitLab Social Login test 2018-08-13 08:46:06 -04:00
Erin Recachinas fa8cb004a1 KEYCLOAK-6086 Casting Jetty WebAppContext in Spring Adapter checks validity and unwraps 2018-08-13 11:16:19 +02:00
Sebastian Laskawiec 3449401ae2 KEYCLOAK-7635: Subject DN validation for x509ClientAuthenticator 2018-08-13 09:36:02 +02:00
sebastienblanc 02b2a8aab0 KEYCLOAK-7635 : Authenticate clients with x509 certificate 2018-08-13 09:36:02 +02:00
mposolda 575851d45c KEYCLOAK-6038 Kerberos cross-realm trust test 2018-08-10 13:31:36 +02:00
Stefan Guilhen 060b3b8d0f [KEYCLOAK-4902] - Using streams when fetching resources 2018-08-09 16:28:31 -03:00
Hynek Mlnarik a8a9631d4f KEYCLOAK-6832 Unify Destination attribute handling 2018-08-09 10:30:30 +02:00
vmuzikar 2efc7ebb48 KEYCLOAK-8007 Fix compilation errors in Console UI and WelcomePage tests 2018-08-09 07:26:07 +02:00
Pedro Igor 905fd3ae00 [KEYCLOAK-8003] - Migration to 4.2.1 extracting RESOURCE_URIs fails with fine-grained admin permissions 2018-08-08 11:00:25 +02:00
Martin Kanis ee8c35a48e KEYCLOAK-6119 Create CI job for Postgres with schema 2018-08-08 08:57:11 +02:00
Hynek Mlnarik fb58214fcc KEYCLOAK-7994 Move examples to test-apps 2018-08-08 08:55:38 +02:00
ssilvert@win.redhat.com 4554798cec KEYCLOAK-8002: Add missing TS files to notification component 2018-08-07 15:27:42 -04:00
Pedro Igor 80e5227bcd [KEYCLOAK-4902] - Refactoring and improvements to processing of authz requests 2018-08-07 10:53:40 -03:00
vmuzikar 65f51b7b83 KEYCLOAK-6736 Base UI tests for mobile and desktop browsers 2018-08-07 13:53:31 +02:00
Richard Kolkovich 72750b9882 KEYCLOAK-7954 treat empty string as null for skipping token verification 2018-08-07 11:13:15 +02:00
mposolda 27719565ae KEYCLOAK-4298 Migrate LDAP tests to the new testsuite 2018-08-06 12:08:19 +02:00
Hynek Mlnarik 65030e2c73 KEYCLOAK-7993 Fix failing Fuse 7 tests 2018-08-06 08:22:30 +02:00
wyvie b5d56e2f3b [KEYCLOAK-7838] made tests ordered so they don't fail because of order 2018-08-03 20:52:54 +02:00
mposolda a63676ce93 KEYCLOAK-7989 Running server config migration fails due the Hostname SPI 2018-08-03 13:47:17 +02:00
wyvie 01af40413e [KEYCLOAK-7868] code fixed, unignoring the test 2018-08-02 15:33:31 +02:00
Hynek Mlnarik f6a4ba98de KEYCLOAK-7986 Fix realm definition 2018-08-02 15:32:42 +02:00
Hiroyuki Wada 263792a4ab KEYCLOAK-7984 Fix migration issue 2018-08-02 14:58:20 +02:00
alva.huang 3380fdc119 [KEYCLOAK-7985] fix the table name error, from RESOURCE_URI to RESOURCE_URIS
Signed-off-by: alva.huang <alva@izhiju.cn>
2018-08-02 08:31:44 -03:00
mposolda 959cd035ba Set version to 4.3.0.Final-SNAPSHOT 2018-08-01 22:40:05 +02:00
ssilvert@win.redhat.com e7e15652cf KEYCLOAK-7479: Sanitize 2018-08-01 14:22:39 -04:00
Hynek Mlnarik f57cc3a9c0 KEYCLOAK-5257 Clarify usage of TokenVerifier 2018-08-01 13:38:31 +02:00
mposolda 29da7d3d90 KEYCLOAK-7562 Fix ClientInitiatedAccountLinkTest#testErrorConditions 2018-08-01 13:33:23 +02:00
stianst f99299ee39 KEYCLOAK-7967 Introduce Hostname SPI 2018-08-01 11:57:45 +02:00
stianst ae47b7fa80 KEYCLOAK-7967 Remove injection of UriInfo 2018-08-01 11:57:45 +02:00
mposolda a2afe7c205 KEYCLOAK-7977 Release failing due the NPE during swagger2markup-maven-plugin execution 2018-07-31 22:05:34 +02:00
Cedric Veilleux f32e258a18 i18n : Unicode encoding issue in french email
One accentuated character was missing unicode escaping in french reset email translation.
2018-07-31 21:55:34 +02:00
Takashi Norimatsu 665bcaebbb KEYCLOAK-7959 OAuth 2.0 Certificate Bound Access Tokens in Rev Proxy 2018-07-31 21:53:46 +02:00
Hiroyuki Wada 398f7d950f KEYCLOAK-7910 Store credentials when updating user via Admin REST API 2018-07-31 15:36:21 +02:00
Martin Kanis e6ad0d63a1 KEYCLOAK-7974 Fix typo in remove credentials alert 2018-07-31 15:29:50 +02:00
Martin Kanis f0808d6882 KEYCLOAK-7973 Possibility to add classpath elements to KeycloakServer 2018-07-31 14:32:58 +02:00
Martin Kanis a4fd7e9f7f KEYCLOAK-6308 Disable secret question credentials fails 2018-07-31 12:15:48 +02:00
Hynek Mlnarik 7a978ff3f6 KEYCLOAK-4407 Execute cross-dc tests selectively in travis 2018-07-31 10:30:38 +02:00
mhajas 9b0930a289 KEYCLOAK-7792 Add tests for fragment in redirect URL 2018-07-31 10:24:58 +02:00
Takashi Mogi 959e7b1b01 KEYCLOAK-7201 OIDC Identity Brokering with Client parameter forward
Forward "custom" (non-standard) query parameters to external IDP
2018-07-31 10:18:29 +02:00
ssilvert@win.redhat.com 40cc826586 Fix test side effect. 2018-07-30 13:15:02 -04:00
ssilvert@win.redhat.com 6c593bab5a Check credential confirmation on server side. 2018-07-30 13:15:02 -04:00
Timothy Lee 9c18d0e628 remove a redundant div end tag 2018-07-30 18:41:03 +02:00
vramikandHynek Mlnarik ecd3fcc0af KEYCLOAK-7924 Speed-up crossdc tests
Co-Authored-By: Hynek Mlnarik <hmlnarik@redhat.com>
2018-07-27 20:53:58 +02:00
vramik 38017d3cec KEYCLOAK-4407 Ability to restart arquillian containers from test
Co-Authored-By: Hynek Mlnarik <hmlnarik@redhat.com>
KEYCLOAK-4407 Fix connection error if underlying container restarts (63b9da857a8174a0b5e65e70c47ef2e2842f4d4e)
2018-07-27 20:53:58 +02:00
Tair Sabirgaliev d88568266f KEYCLOAK-7821 Enable tomcat-specific features: * (all roles), ** (authenticated user) in authRoles constraint 2018-07-27 14:24:49 +02:00
Hynek Mlnarik f43519a16e KEYCLOAK-6708 Fix NPE when email not set for email NameIDFormat 2018-07-27 11:10:35 +02:00
fisache 771d7f1724 [KEYCLOAK-7872] Fix. Remove Identity Provider Mapper when remove identity provider 2018-07-26 08:45:26 +02:00
ssilvert@win.redhat.com 0844aa8d68 KEYCLOAK-7857: Fix notifications 2018-07-25 08:59:25 -04:00
ssilvert@win.redhat.com d73c4288ae KEYCLOAK-7294: Password page - Angular 2018-07-25 08:59:25 -04:00
vramik 9c1a411c6e KEYCLOAK-7310 Add migration test from 3.4.x to 4.x 2018-07-25 13:48:02 +02:00
Tomas Kyjovsky 8eabd4ae89 KEYCLOAK-7934 Dataset generator cannot create "empty" mappings 2018-07-24 23:53:48 +02:00
vramik 524ab44160 KEYCLOAK-6866 Error 404 after changing locale while authenticating using X.509 2018-07-24 17:24:32 +02:00
Tomas Kyjovsky ea8eaaff07 KEYCLOAK-7599 Improve handling of test datasets 2018-07-24 15:07:32 +02:00
mhajas a6e4f4f9aa KEYCLOAK-7922 Use Time.currentTimeMillis() instead of System.currentTimeMillis() in PathCache 2018-07-24 08:52:48 -03:00
Daniil Filippov af72c1374a KEYCLOAK-7823 Fix HTTP status returned during SPNEGO auth 2018-07-24 10:38:42 +02:00
Hiroyuki Wada 7c0ca9aad2 KEYCLOAK-6313 Add required action's priority for customizing the execution order 2018-07-23 22:21:04 +02:00
Hynek Mlnarik b43392bac8 KEYCLOAK-6577 KEYCLOAK-5609 Support dot in claim names by escaping with backslash 2018-07-23 14:46:25 +02:00
Hynek Mlnarik c8bc0d6d7b KEYCLOAK-7400 Remove dead code
This commit can only be merged once the Camel 2.21.2 would be
released, otherwise the code won't compile due to missing dependencies.

See https://issues.apache.org/jira/browse/CAMEL-12514 for details.
2018-07-23 14:46:00 +02:00
Peter Zaoral c4b375c1fc KEYCLOAK-7802 Fix broken HoKTest
Signed-off-by: Peter Zaoral <pzaoral@redhat.com>
2018-07-23 12:30:54 +02:00
mhajas 1308a3231d KEYCLOAK-7931 Correct wrong JPA changelog filenames 2018-07-23 11:49:54 +02:00
pskopek 2eefd60344 [KEYCLOAK-7898] Align versions to match EAP 7.1.4.CR1 2018-07-20 21:32:48 +02:00
sebastienblanc 5472364265 fixed the bom 2018-07-20 10:02:20 +02:00
Hynek Mlnarik 26bf7f251d KEYCLOAK-7888 Update Fuse adapter examples to new CXF registration 2018-07-19 15:22:42 +02:00
Pedro Igor 7c14a6a503 [KEYCLOAK-6547] - AuthenticatedActionsHandler should process responses after identity is established 2018-07-19 10:05:04 -03:00
Pedro Igor acc5f5c6d1 [KEYCLOAK-7864] - Authorization claim not set in refresh token when issuing a new refresh token 2018-07-19 09:56:59 -03:00
Grzegorz Grzybek 2cb7ec9432 [KEYCLOAK-7703] HierarchicalPathBasedKeycloakConfigResolver for more fine/coarse grained Keycloak configuration in Karaf 2018-07-19 14:25:52 +02:00
Pedro Igor 8b6979ac18 [KEYCLOAK-7849] - Improvements to RPT upgrade 2018-07-18 16:40:55 -03:00
Martin Kanis 34407957b9 KEYCLOAK-6314 Internal server error after T&C rejection 2018-07-18 15:05:22 +02:00
Jannik Hüls 44f5cf3020 KEYCLOAK-6707 change verfiyEmail tooltip 2018-07-18 09:14:41 -03:00
vramik 54fcbf12b0 KEYCLOAK-7666 - adapter tests - eap6-fuse6 provider 2018-07-18 13:46:56 +02:00
wyvie 31f6cf9ab5 [KEYCLOAK-7868] fix correct condition for spring boot tests
Also ignore the AccountLinkSpringBootTest#testErrorConditions for now
until we have a clue why it does not work as intended
2018-07-18 13:46:07 +02:00
Gregor Tudan 3417b569c0 KEYCLOAK-2606: add support for native browsers on cordova
KEYCLOAK-2606 Added cordova native

KEYCLOAK-2606 Some more fixes and tweaks

Fix redirect in example realm

feature(cordova-native): fix universalLinks and kc options

Added 'cordova-native' to typings

Added an option to define a "default" redirectUri in keycloak.js

Added 'login' and 'logout' event to universalLinks configuration in config.xml

Improved 'cordova-native' example to always use a redirectUri and
update state after successfull logout

Setting the 'authenticated' flag for the keycloak instance to 'false'
after a logout redirect

KEYCLOAK-2606: Simplify example for cordova-native

I wanted to make it explicit which options are actually needed, so I didn't want to reuse the keycloak conf

KEYCLOAK-2606: simplify example

The update state after logout shouldn't be necessary as it is set in `keycloak.onAuthLogout = updateState;`
Not sure why it is called after the login promise...

Fixes
2018-07-18 10:51:59 +02:00
vramik 8e20986335 KEYCLOAK-7876 Improve stability of fuse7 hawtio test 2018-07-18 10:51:32 +02:00
ssilvert@win.redhat.com 385e1c6122 KEYCLOAK-7846: Add missing features.ts file 2018-07-17 12:44:06 -04:00
ssilvert@win.redhat.com 3e158c0321 KEYCLOAK-7846: Turn off disallowed features 2018-07-17 12:44:06 -04:00
ssilvert@win.redhat.com c969c4c903 Cleanup console.log 2018-07-17 12:43:20 -04:00
ssilvert@win.redhat.com 8533bc7f00 KEYCLOAK-7795: "Back to <app>" missing from Welcome Page 2018-07-17 12:43:20 -04:00
ssilvert@win.redhat.com 2adff375db KEYCLOAK-7497: Remove babel transpiler. Use UMD files from
patternfly-ng.
2018-07-17 12:42:14 -04:00
ssilvert@win.redhat.com d959e501ae KEYCLOAK-7524: Vertical Nav doesn't close on secondary click 2018-07-17 12:42:14 -04:00
Phani Kiran Thaticharla 886362ebf2 Fixed typo in misc/Testsuite.md 2018-07-17 10:05:05 +02:00
wyvie 8e221ea597 [KEYCLOAK-7835] BrokerLinkAndTokenExchangeTest turned off
Until TOKEN_ECHANGE is enabled (means currently turned off
for prod profile)
2018-07-16 10:27:56 +02:00
mhajas 432ea277a7 KEYCLOAK-7816 Assume preview profile in authz tests 2018-07-13 12:53:46 -03:00
Martin Kanis b520dda3ef KEYCLOAK-4662 Keycloak adapter missing configuration attribute proxy-url 2018-07-13 14:30:40 +02:00
Pedro Igor 90bfa2bff5 [KEYCLOAK-7781] - More validations to authorization requests 2018-07-13 09:18:05 -03:00
Pedro Igor 3fc6eed1ce [KEYCLOAK-7827] - Missing org.jboss.logging dependency to keycloak-authz-client module 2018-07-13 09:17:49 -03:00
Juravenator fbbc670d1f KEYCLOAK-7854: Tiny typo in ExampleServiceImpl.java 2018-07-13 09:11:17 -03:00
stianst f022bc1269 [KEYCLOAK-5629] Add credential endpoints to account service 2018-07-12 13:00:25 -04:00
mhajas 5aebc74f8c KEYCLOAK-7269 Setting more uris for Authorization Resource 2018-07-11 17:48:34 -03:00
Tommy Cheng fba2bf0b2f [KEYCLOAK-7822] - Fix access token and refresh token timeout in resource server 2018-07-11 15:13:50 -03:00
Pedro Igor 55550f2023 [KEYCLOAK-6547] - AuthenticatedActionsHandler should process responses after identity is established 2018-07-11 11:33:31 -03:00
vramik 401a347f6f KEYCLOAK-7817 Update eap6.version in testsuite 2018-07-11 15:28:33 +02:00
vmuzikar 0432a566dd KEYCLOAK-7805 Fix PayPal and Bitbucket Social Login tests 2018-07-11 10:19:24 +02:00
rmartinc 4a82979792 KEYCLOAK-1925: SAML adapter multitenant support 2018-07-10 13:21:11 +02:00
Sebastian Laskawiec 3918dbed59 KEYCLOAK-2886 Turn off clustered tests from IDE 2018-07-10 12:37:21 +02:00
zhutaoredhat b80b480769 Fixes KEYCLOAK-7535 - reupdate resource html 2018-07-06 07:40:41 -03:00
mposolda d0a824dde4 Updating version to 4.2.0.Final-SNAPSHOT 2018-07-05 07:42:48 -04:00
2406 changed files with 91542 additions and 37382 deletions

No files matched your search

+10 -1
View File
@@ -8,6 +8,11 @@
.project
.settings
.classpath
# reverting this as e.g. /distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/
# should not be ignored
#bin/
.factorypath
# NetBeans #
############
@@ -54,4 +59,8 @@ target
##########
# KEYCLOAK-5391: We will re-exclude node_modules when node_modules handling is worked out.
# For now, we keep our js libraries checked into GitHub, so we don't ignore.
#node_modules
#node_modules
# testsuite #
#############
*offline-token.txt
+7 -2
View File
@@ -1,5 +1,4 @@
language: java
dist: precise
cache:
cache: false
@@ -14,8 +13,11 @@ env:
- TESTS=server-group2
- TESTS=server-group3
- TESTS=server-group4
- TESTS=adapter-tests
- TESTS=old
- TESTS=crossdc
- TESTS=crossdc-server
- TESTS=crossdc-adapter
- TESTS=ssl
jdk:
- oraclejdk8
@@ -35,4 +37,7 @@ before_install:
script:
- ./travis-run-tests.sh $TESTS
after_success:
- .travis/docker-hub-master-trigger.sh
sudo: false
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
if [ "$DOCKER_HUB_TOKEN" != "" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_REPO_SLUG" == "keycloak/keycloak" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
curl -H "Content-Type: application/json" --data '{"docker_tag": "master"}' -X POST https://registry.hub.docker.com/u/jboss/keycloak/trigger/$DOCKER_HUB_TOKEN/
echo "Triggered Docker hub build"
elif [ "$DOCKER_HUB_TOKEN" != "" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_REPO_SLUG" == "keycloak/keycloak" ] && [ "$TRAVIS_BRANCH" == "openshift-integration2" ]; then
curl -H "Content-Type: application/json" --data '{"docker_tag": "nightly-openshift-integration2"}' -X POST https://registry.hub.docker.com/u/jboss/keycloak/trigger/$DOCKER_HUB_TOKEN/
echo "Triggered Docker hub build"
fi
+54
View File
@@ -0,0 +1,54 @@
ADOPTERS
========
PUBLIC REFERENCES
-----------------
List of organization names below is based on information collected using Keycloak Community Survey. It contains company names from participants who agreed to serve as public reference. If organizations would like get added or removed please make a PR.
* Accenture
* Actinver
* Akvo Foundation
* Appier
* BISPRO
* Bluestem Brands, Inc
* Bundesversicherungsamt
* Capgemini
* Chassi
* CloudNative Inc.
* Copenhagen Optimization
* Curecomp GmbH
* Cybertech
* Devsu
* Devoxx / Voxxed
* DUENE e.V - project
* DukeCon
* European Synchrotron Radiation Facility
* Fluance AG
* Hewlett-Packard Enterprise
* Hitachi
* INEAT
* Inventage
* ISAAC
* ITROI Solutions
* Kindly Ops, LLC
* msg systems ag
* Netdava International
* Ohio Supercomputer Center
* Okta
* PharmaPartners B.V.
* Plivo
* Price Insight
* Prodesan
* Quest Software
* Research Industrial Software Engineering (RISE)
* Sportsbet.com.au
* Stack Labs
* Storebrand
* Synekus
* Synetek Solutions
* Taklane
* TrackingSport
* TRT9 - Brasil
* UnitedHealthcare
* ...More individuals
+1
View File
@@ -44,6 +44,7 @@ To start Keycloak during development first build as specified above, then run:
mvn -f testsuite/utils/pom.xml exec:java -Pkeycloak-server
When running testsuite, by default an account with username `admin` and password `admin` will be created within the master realm at start.
To start Keycloak from the server distribution first build the distribution it as specified above, then run:
+4 -11
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -31,6 +31,9 @@
<description/>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<keycloak.osgi.export>
org.keycloak.adapters.*
</keycloak.osgi.export>
@@ -61,7 +64,6 @@
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -107,15 +109,6 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -307,6 +307,16 @@ public class AdapterDeploymentContext {
delegate.setTokenStore(tokenStore);
}
@Override
public String getAdapterStateCookiePath() {
return delegate.getAdapterStateCookiePath();
}
@Override
public void setAdapterStateCookiePath(String adapterStateCookiePath) {
delegate.setAdapterStateCookiePath(adapterStateCookiePath);
}
@Override
public String getStateCookieName() {
return delegate.getStateCookieName();
@@ -482,6 +492,16 @@ public class AdapterDeploymentContext {
public void setPublicKeyCacheTtl(int publicKeyCacheTtl) {
delegate.setPublicKeyCacheTtl(publicKeyCacheTtl);
}
@Override
public boolean isVerifyTokenAudience() {
return delegate.isVerifyTokenAudience();
}
@Override
public void setVerifyTokenAudience(boolean verifyTokenAudience) {
delegate.setVerifyTokenAudience(verifyTokenAudience);
}
}
protected KeycloakUriBuilder getBaseBuilder(HttpFacade facade, String base) {
@@ -106,7 +106,10 @@ public class AuthenticatedActionsHandler {
if (deployment.getPolicyEnforcer() != null) {
if (exposeHeaders != null) {
exposeHeaders += ",";
} else {
exposeHeaders = "";
}
exposeHeaders += "WWW-Authenticate";
}
@@ -85,7 +85,7 @@ public class BasicAuthRequestAuthenticator extends BearerTokenRequestAuthenticat
return authenticateToken(exchange, atr.getToken());
}
private AccessTokenResponse getToken(String username, String password) throws Exception {
protected AccessTokenResponse getToken(String username, String password) throws Exception {
AccessTokenResponse tokenResponse=null;
HttpClient client = deployment.getClient();
@@ -18,7 +18,7 @@
package org.keycloak.adapters;
import org.jboss.logging.Logger;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.adapters.spi.AuthChallenge;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
@@ -72,8 +72,12 @@ public class BearerTokenRequestAuthenticator {
for (String authHeader : authHeaders) {
String[] split = authHeader.trim().split("\\s+");
if (split == null || split.length != 2) continue;
if (!split[0].equalsIgnoreCase("Bearer")) continue;
tokenString = split[1];
if (split[0].equalsIgnoreCase("Bearer")) {
tokenString = split[1];
log.debugf("Found [%d] values in authorization header, selecting the first value for Bearer.", (Integer) authHeaders.size());
break;
};
}
if (tokenString == null) {
@@ -96,7 +100,7 @@ public class BearerTokenRequestAuthenticator {
}
}
try {
token = AdapterRSATokenVerifier.verifyToken(tokenString, deployment);
token = AdapterTokenVerifier.verifyToken(tokenString, deployment);
} catch (VerificationException e) {
log.error("Failed to verify token", e);
challenge = challengeResponse(exchange, OIDCAuthenticationError.Reason.INVALID_TOKEN, "invalid_token", e.getMessage());
@@ -19,7 +19,8 @@ package org.keycloak.adapters;
import org.jboss.logging.Logger;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.TokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.KeycloakUriBuilder;
@@ -46,7 +47,7 @@ public class CookieTokenStore {
.append(idToken).append(DELIM)
.append(refreshToken).toString();
String cookiePath = getContextPath(facade);
String cookiePath = getCookiePath(deployment, facade);
facade.getResponse().setCookie(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE, cookie, cookiePath, null, -1, deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr()), true);
}
@@ -71,7 +72,11 @@ public class CookieTokenStore {
try {
// Skip check if token is active now. It's supposed to be done later by the caller
AccessToken accessToken = AdapterRSATokenVerifier.verifyToken(accessTokenString, deployment, false, true);
TokenVerifier<AccessToken> tokenVerifier = AdapterTokenVerifier.createVerifier(accessTokenString, deployment, true, AccessToken.class)
.checkActive(false)
.verify();
AccessToken accessToken = tokenVerifier.getToken();
IDToken idToken;
if (idTokenString != null && idTokenString.length() > 0) {
try {
@@ -93,14 +98,30 @@ public class CookieTokenStore {
}
}
public static void removeCookie(HttpFacade facade) {
String cookiePath = getContextPath(facade);
public static void removeCookie(KeycloakDeployment deployment, HttpFacade facade) {
String cookiePath = getCookiePath(deployment, facade);
facade.getResponse().resetCookie(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE, cookiePath);
}
private static String getContextPath(HttpFacade facade) {
static String getCookiePath(KeycloakDeployment deployment, HttpFacade facade) {
String path = deployment.getAdapterStateCookiePath() == null ? "" : deployment.getAdapterStateCookiePath().trim();
if (path.startsWith("/")) {
return path;
}
String contextPath = getContextPath(facade);
StringBuilder cookiePath = new StringBuilder(contextPath);
if (!contextPath.endsWith("/") && !path.isEmpty()) {
cookiePath.append("/");
}
return cookiePath.append(path).toString();
}
static String getContextPath(HttpFacade facade) {
String uri = facade.getRequest().getURI();
String path = KeycloakUriBuilder.fromUri(uri).getPath();
if (path == null || path.isEmpty()) {
return "/";
}
int index = path.indexOf("/", 1);
return index == -1 ? path : path.substring(0, index);
}
@@ -70,6 +70,7 @@ public class KeycloakDeployment {
protected SslRequired sslRequired = SslRequired.ALL;
protected int confidentialPort = -1;
protected TokenStore tokenStore = TokenStore.SESSION;
protected String adapterStateCookiePath = "";
protected String stateCookieName = "OAuth_Token_Request_State";
protected boolean useResourceRoleMappings;
protected boolean cors;
@@ -92,10 +93,11 @@ public class KeycloakDeployment {
// https://tools.ietf.org/html/rfc7636
protected boolean pkce = false;
protected boolean ignoreOAuthQueryParameter;
protected Map<String, String> redirectRewriteRules;
protected boolean delegateBearerErrorResponseSending = false;
protected boolean verifyTokenAudience = false;
public KeycloakDeployment() {
}
@@ -296,6 +298,14 @@ public class KeycloakDeployment {
this.tokenStore = tokenStore;
}
public String getAdapterStateCookiePath() {
return adapterStateCookiePath;
}
public void setAdapterStateCookiePath(String adapterStateCookiePath) {
this.adapterStateCookiePath = adapterStateCookiePath;
}
public String getStateCookieName() {
return stateCookieName;
}
@@ -477,4 +487,12 @@ public class KeycloakDeployment {
public void setDelegateBearerErrorResponseSending(boolean delegateBearerErrorResponseSending) {
this.delegateBearerErrorResponseSending = delegateBearerErrorResponseSending;
}
public boolean isVerifyTokenAudience() {
return verifyTokenAudience;
}
public void setVerifyTokenAudience(boolean verifyTokenAudience) {
this.verifyTokenAudience = verifyTokenAudience;
}
}
@@ -88,6 +88,9 @@ public class KeycloakDeploymentBuilder {
} else {
deployment.setTokenStore(TokenStore.SESSION);
}
if (adapterConfig.getTokenCookiePath() != null) {
deployment.setAdapterStateCookiePath(adapterConfig.getTokenCookiePath());
}
if (adapterConfig.getPrincipalAttribute() != null) deployment.setPrincipalAttribute(adapterConfig.getPrincipalAttribute());
deployment.setResourceCredentials(adapterConfig.getCredentials());
@@ -122,6 +125,7 @@ public class KeycloakDeploymentBuilder {
deployment.setPublicKeyCacheTtl(adapterConfig.getPublicKeyCacheTtl());
deployment.setIgnoreOAuthQueryParameter(adapterConfig.isIgnoreOAuthQueryParameter());
deployment.setRewriteRedirectRules(adapterConfig.getRedirectRewriteRules());
deployment.setVerifyTokenAudience(adapterConfig.isVerifyTokenAudience());
if (realmKeyPem == null && adapterConfig.isBearerOnly() && adapterConfig.getAuthServerUrl() == null) {
throw new IllegalArgumentException("For bearer auth, you must set the realm-public-key or auth-server-url");
@@ -19,7 +19,7 @@ package org.keycloak.adapters;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.adapters.spi.AdapterSessionStore;
import org.keycloak.adapters.spi.AuthChallenge;
import org.keycloak.adapters.spi.AuthOutcome;
@@ -40,7 +40,6 @@ import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.logging.Level;
/**
@@ -359,15 +358,9 @@ public class OAuthRequestAuthenticator {
}
try {
token = AdapterRSATokenVerifier.verifyToken(tokenString, deployment);
if (idTokenString != null) {
try {
JWSInput input = new JWSInput(idTokenString);
idToken = input.readJsonContent(IDToken.class);
} catch (JWSInputException e) {
throw new VerificationException();
}
}
AdapterTokenVerifier.VerifiedTokens tokens = AdapterTokenVerifier.verifyTokens(tokenString, idTokenString, deployment);
token = tokens.getAccessToken();
idToken = tokens.getIdToken();
log.debug("Token Verification succeeded!");
} catch (VerificationException e) {
log.error("failed verification of token: " + e.getMessage());
@@ -20,30 +20,27 @@ package org.keycloak.adapters;
import java.security.PublicKey;
import org.jboss.logging.Logger;
import org.keycloak.TokenVerifier;
import org.keycloak.adapters.authentication.ClientCredentialsProvider;
import org.keycloak.adapters.authentication.JWTClientCredentialsProvider;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.spi.UserSessionManagement;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.StreamUtil;
import org.keycloak.jose.jwk.JSONWebKeySet;
import org.keycloak.jose.jwk.JWK;
import org.keycloak.jose.jwk.JWKBuilder;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.representations.JsonWebToken;
import org.keycloak.representations.VersionRepresentation;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.representations.VersionRepresentation;
import org.keycloak.representations.adapters.action.AdminAction;
import org.keycloak.representations.adapters.action.LogoutAction;
import org.keycloak.representations.adapters.action.PushNotBeforeAction;
import org.keycloak.representations.adapters.action.TestAvailabilityAction;
import org.keycloak.util.JsonSerialization;
import java.security.PublicKey;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@@ -213,17 +210,19 @@ public class PreAuthActionsHandler {
}
try {
JWSInput input = new JWSInput(token);
PublicKey publicKey = AdapterRSATokenVerifier.getPublicKey(input.getHeader().getKeyId(), deployment);
if (RSAProvider.verify(input, publicKey)) {
return input;
// Check just signature. Other things checked in validateAction
TokenVerifier tokenVerifier = AdapterTokenVerifier.createVerifier(token, deployment, false, JsonWebToken.class);
tokenVerifier.verify();
return new JWSInput(token);
} catch (VerificationException ignore) {
log.warn("admin request failed, unable to verify token: " + ignore.getMessage());
if (log.isDebugEnabled()) {
log.debug(ignore.getMessage(), ignore);
}
} catch (JWSInputException ignore) {
}
log.warn("admin request failed, unable to verify token");
facade.getResponse().sendError(403, "no token");
return null;
facade.getResponse().sendError(403, "token failed verification");
return null;
}
}
@@ -250,6 +249,15 @@ public class PreAuthActionsHandler {
protected void handleVersion() {
try {
facade.getResponse().setStatus(200);
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
if (deployment.isCors()) {
String origin = facade.getRequest().getHeader(CorsHeaders.ORIGIN);
if (origin == null) {
log.debug("no origin header set in request");
} else {
facade.getResponse().setHeader(CorsHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
}
}
facade.getResponse().setHeader("Content-Type", "application/json");
JsonSerialization.writeValueToStream(facade.getResponse().getOutputStream(), VersionRepresentation.SINGLETON);
} catch (Exception e) {
@@ -20,7 +20,7 @@ package org.keycloak.adapters;
import org.jboss.logging.Logger;
import org.keycloak.AuthorizationContext;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.Time;
import org.keycloak.representations.AccessToken;
@@ -130,7 +130,8 @@ public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext
String tokenString = response.getToken();
AccessToken token = null;
try {
token = AdapterRSATokenVerifier.verifyToken(tokenString, deployment);
AdapterTokenVerifier.VerifiedTokens tokens = AdapterTokenVerifier.verifyTokens(tokenString, response.getIdToken(), deployment);
token = tokens.getAccessToken();
log.debug("Token Verification succeeded!");
} catch (VerificationException e) {
log.error("failed verification of token");
@@ -17,6 +17,8 @@
*/
package org.keycloak.adapters.authorization;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -69,7 +71,11 @@ public abstract class AbstractPolicyEnforcer {
if (securityContext == null) {
if (!isDefaultAccessDeniedUri(request)) {
if (pathConfig != null) {
challenge(pathConfig, getRequiredScopes(pathConfig, request), httpFacade);
if (EnforcementMode.DISABLED.equals(pathConfig.getEnforcementMode())) {
return createEmptyAuthorizationContext(true);
} else {
challenge(pathConfig, getRequiredScopes(pathConfig, request), httpFacade);
}
} else {
handleAccessDenied(httpFacade);
}
@@ -107,8 +113,9 @@ public abstract class AbstractPolicyEnforcer {
}
MethodConfig methodConfig = getRequiredScopes(pathConfig, request);
Map<String, List<String>> claims = resolveClaims(pathConfig, httpFacade);
if (isAuthorized(pathConfig, methodConfig, accessToken, httpFacade)) {
if (isAuthorized(pathConfig, methodConfig, accessToken, httpFacade, claims)) {
try {
return createAuthorizationContext(accessToken, pathConfig);
} catch (Exception e) {
@@ -137,7 +144,7 @@ public abstract class AbstractPolicyEnforcer {
protected abstract boolean challenge(PathConfig pathConfig, MethodConfig methodConfig, OIDCHttpFacade facade);
protected boolean isAuthorized(PathConfig actualPathConfig, MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade) {
protected boolean isAuthorized(PathConfig actualPathConfig, MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade, Map<String, List<String>> claims) {
Request request = httpFacade.getRequest();
if (isDefaultAccessDeniedUri(request)) {
@@ -151,7 +158,7 @@ public abstract class AbstractPolicyEnforcer {
}
boolean hasPermission = false;
List<Permission> grantedPermissions = authorization.getPermissions();
Collection<Permission> grantedPermissions = authorization.getPermissions();
for (Permission permission : grantedPermissions) {
if (permission.getResourceId() != null) {
@@ -170,7 +177,7 @@ public abstract class AbstractPolicyEnforcer {
policyEnforcer.getPathMatcher().removeFromCache(getPath(request));
}
return hasValidClaims(actualPathConfig, permission, httpFacade, authorization);
return hasValidClaims(permission, claims);
}
}
} else {
@@ -192,12 +199,10 @@ public abstract class AbstractPolicyEnforcer {
return false;
}
private boolean hasValidClaims(PathConfig actualPathConfig, Permission permission, OIDCHttpFacade httpFacade, Authorization authorization) {
private boolean hasValidClaims(Permission permission, Map<String, List<String>> claims) {
Map<String, Set<String>> grantedClaims = permission.getClaims();
if (grantedClaims != null) {
Map<String, List<String>> claims = resolveClaims(actualPathConfig, httpFacade);
if (claims.isEmpty()) {
return false;
}
@@ -305,7 +310,15 @@ public abstract class AbstractPolicyEnforcer {
MethodConfig methodConfig = new MethodConfig();
methodConfig.setMethod(request.getMethod());
methodConfig.setScopes(pathConfig.getScopes());
List scopes = new ArrayList<>();
if (Boolean.TRUE.equals(getEnforcerConfig().getHttpMethodAsScope())) {
scopes.add(request.getMethod());
} else {
scopes.addAll(pathConfig.getScopes());
}
methodConfig.setScopes(scopes);
methodConfig.setScopesEnforcementMode(PolicyEnforcerConfig.ScopeEnforcementMode.ANY);
return methodConfig;
@@ -344,18 +357,16 @@ public abstract class AbstractPolicyEnforcer {
}
private Map<String, List<String>> getClaims(Map<String, Map<String, Object>>claimInformationPointConfig, HttpFacade httpFacade) {
Map<String, List<String>> claims = new HashMap<>();
if (claimInformationPointConfig != null) {
for (Entry<String, Map<String, Object>> claimDef : claimInformationPointConfig.entrySet()) {
ClaimInformationPointProviderFactory factory = getPolicyEnforcer().getClaimInformationPointProviderFactories().get(claimDef.getKey());
if (factory != null) {
claims.putAll(factory.create(claimDef.getValue()).resolve(httpFacade));
return factory.create(claimDef.getValue()).resolve(httpFacade);
}
}
}
return claims;
return new HashMap<>();
}
}
@@ -18,7 +18,7 @@
package org.keycloak.adapters.authorization;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -27,7 +27,7 @@ import org.jboss.logging.Logger;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OIDCHttpFacade;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.authorization.client.AuthorizationDeniedException;
import org.keycloak.authorization.client.AuthzClient;
@@ -55,14 +55,14 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
}
@Override
protected boolean isAuthorized(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade) {
protected boolean isAuthorized(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade, Map<String, List<String>> claims) {
AccessToken original = accessToken;
if (super.isAuthorized(pathConfig, methodConfig, accessToken, httpFacade)) {
if (super.isAuthorized(pathConfig, methodConfig, accessToken, httpFacade, claims)) {
return true;
}
accessToken = requestAuthorizationToken(pathConfig, methodConfig, httpFacade);
accessToken = requestAuthorizationToken(pathConfig, methodConfig, httpFacade, claims);
if (accessToken == null) {
return false;
@@ -78,8 +78,8 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
AccessToken.Authorization newAuthorization = accessToken.getAuthorization();
if (newAuthorization != null) {
List<Permission> grantedPermissions = authorization.getPermissions();
List<Permission> newPermissions = newAuthorization.getPermissions();
Collection<Permission> grantedPermissions = authorization.getPermissions();
Collection<Permission> newPermissions = newAuthorization.getPermissions();
for (Permission newPermission : newPermissions) {
if (!grantedPermissions.contains(newPermission)) {
@@ -90,7 +90,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
original.setAuthorization(authorization);
return super.isAuthorized(pathConfig, methodConfig, accessToken, httpFacade);
return super.isAuthorized(pathConfig, methodConfig, accessToken, httpFacade, claims);
}
@Override
@@ -133,7 +133,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
}
}
private AccessToken requestAuthorizationToken(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, OIDCHttpFacade httpFacade) {
private AccessToken requestAuthorizationToken(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, OIDCHttpFacade httpFacade, Map<String, List<String>> claims) {
if (getEnforcerConfig().getUserManagedAccess() != null) {
return null;
}
@@ -149,8 +149,6 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
authzRequest.addPermission(pathConfig.getId(), methodConfig.getScopes());
}
Map<String, List<String>> claims = resolveClaims(pathConfig, httpFacade);
if (!claims.isEmpty()) {
authzRequest.setClaimTokenFormat("urn:ietf:params:oauth:token-type:jwt");
authzRequest.setClaimToken(Base64.encodeBytes(JsonSerialization.writeValueAsBytes(claims)));
@@ -171,7 +169,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
}
if (authzResponse != null) {
return AdapterRSATokenVerifier.verifyToken(authzResponse.getToken(), deployment);
return AdapterTokenVerifier.verifyToken(authzResponse.getToken(), deployment);
}
} catch (AuthorizationDeniedException ignore) {
LOGGER.debug("Authorization denied", ignore);
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
import org.keycloak.common.util.Time;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
/**
@@ -154,7 +155,7 @@ public class PathCache {
if(maxAge == -1) {
expiration = -1;
} else {
expiration = System.currentTimeMillis() + maxAge;
expiration = Time.currentTimeMillis() + maxAge;
}
}
@@ -167,7 +168,7 @@ public class PathCache {
}
boolean isExpired() {
return expiration != -1 ? System.currentTimeMillis() > expiration : false;
return expiration != -1 ? Time.currentTimeMillis() > expiration : false;
}
}
}
@@ -225,9 +225,10 @@ public class PolicyEnforcer {
for (String id : protectedResource.findAll()) {
ResourceRepresentation resourceDescription = protectedResource.findById(id);
if (resourceDescription.getUri() != null) {
PathConfig pathConfig = PathConfig.createPathConfig(resourceDescription);
paths.put(pathConfig.getPath(), pathConfig);
if (resourceDescription.getUris() != null && !resourceDescription.getUris().isEmpty()) {
for(PathConfig pathConfig : PathConfig.createPathConfigs(resourceDescription)) {
paths.put(pathConfig.getPath(), pathConfig);
}
}
}
}
@@ -277,7 +278,7 @@ public class PolicyEnforcer {
cipConfig = pathConfig.getClaimInformationPointConfig();
}
pathConfig = PathConfig.createPathConfig(matchingResources.get(0));
pathConfig = PathConfig.createPathConfigs(matchingResources.get(0)).iterator().next();
if (cipConfig != null) {
pathConfig.setClaimInformationPointConfig(cipConfig);
@@ -323,7 +324,7 @@ public class PolicyEnforcer {
if (!search.isEmpty()) {
ResourceRepresentation targetResource = search.get(0);
PathConfig config = PathConfig.createPathConfig(targetResource);
PathConfig config = PathConfig.createPathConfigs(targetResource).iterator().next();
config.setScopes(originalConfig.getScopes());
config.setMethods(originalConfig.getMethods());
@@ -23,7 +23,7 @@ import org.keycloak.adapters.AdapterUtils;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.FindFile;
import org.keycloak.common.util.reflections.Reflections;
@@ -202,8 +202,16 @@ public abstract class AbstractKeycloakLoginModule implements LoginModule {
protected Auth bearerAuth(String tokenString) throws VerificationException {
AccessToken token = AdapterRSATokenVerifier.verifyToken(tokenString, deployment);
AccessToken token = AdapterTokenVerifier.verifyToken(tokenString, deployment);
return postTokenVerification(tokenString, token);
}
/**
* Called after accessToken was verified (including signature, expiration etc)
*
*/
protected Auth postTokenVerification(String tokenString, AccessToken token) {
boolean verifyCaller;
if (deployment.isUseResourceRoleMappings()) {
verifyCaller = token.isVerifyCaller(deployment.getResourceName());
@@ -27,6 +27,7 @@ import org.apache.http.message.BasicNameValuePair;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.authentication.ClientCredentialsProviderUtils;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.constants.ServiceUrlConstants;
@@ -56,11 +57,15 @@ public class DirectAccessGrantsLoginModule extends AbstractKeycloakLoginModule {
private static final Logger log = Logger.getLogger(DirectAccessGrantsLoginModule.class);
public static final String SCOPE_OPTION = "scope";
private String refreshToken;
private String scope;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
super.initialize(subject, callbackHandler, sharedState, options);
this.scope = (String)options.get(SCOPE_OPTION);
// This is used just for logout
Iterator<RefreshTokenHolder> iterator = subject.getPrivateCredentials(RefreshTokenHolder.class).iterator();
@@ -89,6 +94,10 @@ public class DirectAccessGrantsLoginModule extends AbstractKeycloakLoginModule {
formparams.add(new BasicNameValuePair("username", username));
formparams.add(new BasicNameValuePair("password", password));
if (scope != null) {
formparams.add(new BasicNameValuePair(OAuth2Constants.SCOPE, scope));
}
ClientCredentialsProviderUtils.setClientCredentials(deployment, post, formparams);
UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
@@ -121,7 +130,8 @@ public class DirectAccessGrantsLoginModule extends AbstractKeycloakLoginModule {
// refreshToken will be saved to privateCreds of Subject for now
refreshToken = tokenResponse.getRefreshToken();
return bearerAuth(tokenResponse.getToken());
AdapterTokenVerifier.VerifiedTokens tokens = AdapterTokenVerifier.verifyTokens(tokenResponse.getToken(), tokenResponse.getIdToken(), deployment);
return postTokenVerification(tokenResponse.getToken(), tokens.getAccessToken());
}
@Override
@@ -1,58 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.rotation;
import org.jboss.logging.Logger;
import org.keycloak.RSATokenVerifier;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.common.VerificationException;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessToken;
import java.security.PublicKey;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AdapterRSATokenVerifier {
private static final Logger log = Logger.getLogger(AdapterRSATokenVerifier.class);
public static AccessToken verifyToken(String tokenString, KeycloakDeployment deployment) throws VerificationException {
return verifyToken(tokenString, deployment, true, true);
}
public static PublicKey getPublicKey(String kid, KeycloakDeployment deployment) throws VerificationException {
PublicKeyLocator pkLocator = deployment.getPublicKeyLocator();
PublicKey publicKey = pkLocator.getPublicKey(kid, deployment);
if (publicKey == null) {
log.errorf("Didn't find publicKey for kid: %s", kid);
throw new VerificationException("Didn't find publicKey for specified kid");
}
return publicKey;
}
public static AccessToken verifyToken(String tokenString, KeycloakDeployment deployment, boolean checkActive, boolean checkTokenType) throws VerificationException {
RSATokenVerifier verifier = RSATokenVerifier.create(tokenString).realmUrl(deployment.getRealmInfoUrl()).checkActive(checkActive).checkTokenType(checkTokenType);
PublicKey publicKey = getPublicKey(verifier.getHeader().getKeyId(), deployment);
return verifier.publicKey(publicKey).verify().getToken();
}
}
@@ -0,0 +1,150 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.rotation;
import org.jboss.logging.Logger;
import org.keycloak.TokenVerifier;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.common.VerificationException;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.IDToken;
import org.keycloak.representations.JsonWebToken;
import java.security.PublicKey;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AdapterTokenVerifier {
private static final Logger log = Logger.getLogger(AdapterTokenVerifier.class);
/**
* Verifies bearer token. Typically called when bearer token (access token) is sent to the service, which wants to verify it. Hence it also checks the audience in the token.
*
* @param tokenString
* @param deployment
* @return
* @throws VerificationException
*/
public static AccessToken verifyToken(String tokenString, KeycloakDeployment deployment) throws VerificationException {
TokenVerifier<AccessToken> tokenVerifier = createVerifier(tokenString, deployment, true, AccessToken.class);
// Verify audience of bearer-token
if (deployment.isVerifyTokenAudience()) {
tokenVerifier.audience(deployment.getResourceName());
}
return tokenVerifier.verify().getToken();
}
/**
* Verify access token and ID token. Typically called after successful tokenResponse is received from Keycloak
*
* @param accessTokenString
* @param idTokenString
* @param deployment
* @return verified and parsed accessToken and idToken
* @throws VerificationException
*/
public static VerifiedTokens verifyTokens(String accessTokenString, String idTokenString, KeycloakDeployment deployment) throws VerificationException {
// Adapters currently do most of the checks including signature etc on the access token
TokenVerifier<AccessToken> tokenVerifier = createVerifier(accessTokenString, deployment, true, AccessToken.class);
AccessToken accessToken = tokenVerifier.verify().getToken();
if (idTokenString != null) {
// Don't verify signature again on IDToken
IDToken idToken = TokenVerifier.create(idTokenString, IDToken.class).getToken();
TokenVerifier<IDToken> idTokenVerifier = TokenVerifier.createWithoutSignature(idToken);
// Always verify audience and azp on IDToken
idTokenVerifier.audience(deployment.getResourceName());
idTokenVerifier.issuedFor(deployment.getResourceName());
idTokenVerifier.verify();
return new VerifiedTokens(accessToken, idToken);
} else {
return new VerifiedTokens(accessToken, null);
}
}
/**
* Creates verifier, initializes it from the KeycloakDeployment and adds the publicKey and some default basic checks (activeness and tokenType). Useful if caller wants to add/remove/update
* some checks
*
* @param tokenString
* @param deployment
* @param withDefaultChecks
* @param tokenClass
* @param <T>
* @return tokenVerifier
* @throws VerificationException
*/
public static <T extends JsonWebToken> TokenVerifier<T> createVerifier(String tokenString, KeycloakDeployment deployment, boolean withDefaultChecks, Class<T> tokenClass) throws VerificationException {
TokenVerifier<T> tokenVerifier = TokenVerifier.create(tokenString, tokenClass);
if (withDefaultChecks) {
tokenVerifier
.withDefaultChecks()
.realmUrl(deployment.getRealmInfoUrl());
}
String kid = tokenVerifier.getHeader().getKeyId();
PublicKey publicKey = getPublicKey(kid, deployment);
tokenVerifier.publicKey(publicKey);
return tokenVerifier;
}
private static PublicKey getPublicKey(String kid, KeycloakDeployment deployment) throws VerificationException {
PublicKeyLocator pkLocator = deployment.getPublicKeyLocator();
PublicKey publicKey = pkLocator.getPublicKey(kid, deployment);
if (publicKey == null) {
log.errorf("Didn't find publicKey for kid: %s", kid);
throw new VerificationException("Didn't find publicKey for specified kid");
}
return publicKey;
}
public static class VerifiedTokens {
private final AccessToken accessToken;
private final IDToken idToken;
public VerifiedTokens(AccessToken accessToken, IDToken idToken) {
this.accessToken = accessToken;
this.idToken = idToken;
}
public AccessToken getAccessToken() {
return accessToken;
}
public IDToken getIdToken() {
return idToken;
}
}
}
@@ -77,6 +77,7 @@ public class KeycloakDeploymentBuilderTest {
assertEquals(20, deployment.getMinTimeBetweenJwksRequests());
assertEquals(120, deployment.getPublicKeyCacheTtl());
assertEquals("/api/$1", deployment.getRedirectRewriteRules().get("^/wsmaster/api/(.*)$"));
assertTrue(deployment.isVerifyTokenAudience());
}
@Test
@@ -34,6 +34,7 @@
"min-time-between-jwks-requests": 20,
"public-key-cache-ttl": 120,
"ignore-oauth-query-parameter": true,
"verify-token-audience": true,
"redirect-rewrite-rules" : {
"^/wsmaster/api/(.*)$" : "/api/$1"
}
+1 -15
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -47,7 +47,6 @@
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -86,17 +85,4 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
+1 -14
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -118,17 +118,4 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-integration-pom</artifactId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -98,6 +98,12 @@ class SecureDeploymentDefinition extends SimpleResourceDefinition {
.setValidator(new IntRangeValidator(-1, true))
.setAllowExpression(true)
.build();
protected static final SimpleAttributeDefinition PUBLIC_KEY_CACHE_TTL =
new SimpleAttributeDefinitionBuilder("public-key-cache-ttl", ModelType.INT, true)
.setXmlName("public-key-cache-ttl")
.setAllowExpression(true)
.setValidator(new IntRangeValidator(-1, true))
.build();
protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
static {
@@ -110,6 +116,7 @@ class SecureDeploymentDefinition extends SimpleResourceDefinition {
DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
DEPLOYMENT_ONLY_ATTRIBUTES.add(TOKEN_MINIMUM_TIME_TO_LIVE);
DEPLOYMENT_ONLY_ATTRIBUTES.add(MIN_TIME_BETWEEN_JWKS_REQUESTS);
DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_KEY_CACHE_TTL);
}
protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
@@ -166,6 +166,20 @@ class SharedAttributeDefinitons {
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition PROXY_URL =
new SimpleAttributeDefinitionBuilder("proxy-url", ModelType.STRING, true)
.setXmlName("proxy-url")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition VERIFY_TOKEN_AUDIENCE =
new SimpleAttributeDefinitionBuilder("verify-token-audience", ModelType.BOOLEAN, true)
.setXmlName("verify-token-audience")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final List<SimpleAttributeDefinition> ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
@@ -192,6 +206,8 @@ class SharedAttributeDefinitons {
ATTRIBUTES.add(REGISTER_NODE_PERIOD);
ATTRIBUTES.add(TOKEN_STORE);
ATTRIBUTES.add(PRINCIPAL_ATTRIBUTE);
ATTRIBUTES.add(PROXY_URL);
ATTRIBUTES.add(VERIFY_TOKEN_AUDIENCE);
}
/**
@@ -46,6 +46,8 @@ keycloak.realm.register-node-at-startup=Cluster setting
keycloak.realm.register-node-period=how often to re-register node
keycloak.realm.token-store=cookie or session storage for auth session data
keycloak.realm.principal-attribute=token attribute to use to set Principal name
keycloak.realm.proxy-url=The URL for the HTTP proxy if one is used.
keycloak.realm.verify-token-audience=If true, then during bearer-only authentication, the adapter will verify if token contains this client name (resource) as an audience
keycloak.secure-deployment=A deployment secured by Keycloak
keycloak.secure-deployment.add=Add a deployment to be secured by Keycloak
@@ -82,7 +84,9 @@ keycloak.secure-deployment.principal-attribute=token attribute to use to set Pri
keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login. Change this to true if you want to turn this off
keycloak.secure-deployment.token-minimum-time-to-live=The adapter will refresh the token if the current token is expired OR will expire in 'token-minimum-time-to-live' seconds or less
keycloak.secure-deployment.min-time-between-jwks-requests=If adapter recognize token signed by unknown public key, it will try to download new public key from keycloak server. However it won't try to download if already tried it in less than 'min-time-between-jwks-requests' seconds
keycloak.secure-deployment.public-key-cache-ttl=Maximum time the downloaded public keys are considered valid. When this time reach, the adapter is forced to download public keys from keycloak server
keycloak.secure-deployment.proxy-url=The URL for the HTTP proxy if one is used.
keycloak.secure-deployment.verify-token-audience=If true, then during bearer-only authentication, the adapter will verify if token contains this client name (resource) as an audience
keycloak.secure-deployment.credential=Credential value
keycloak.credential=Credential
@@ -65,6 +65,8 @@
<xs:element name="register-node-period" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
@@ -107,6 +109,9 @@
<xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="token-minimum-time-to-live" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="min-time-between-jwks-requests" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="public-key-cache-ttl" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
+7 -2
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
@@ -30,6 +30,11 @@
<artifactId>keycloak-as7-integration-pom</artifactId>
<packaging>pom</packaging>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
@@ -47,4 +52,4 @@
<module>as7-adapter</module>
<module>as7-subsystem</module>
</modules>
</project>
</project>
+7 -13
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-fuse7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -31,6 +31,9 @@
<packaging>bundle</packaging>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<keycloak.osgi.export>
org.keycloak.adapters.camel.undertow;version="${project.version}"
</keycloak.osgi.export>
@@ -38,7 +41,7 @@
org.keycloak.*;version="${project.version}",
org.apache.camel.*,
org.apache.camel.component.undertow,
io.undertow.*,
io.undertow.*;version="[1.4,3)",
*;resolution:=optional
</keycloak.osgi.import>
</properties>
@@ -87,26 +90,17 @@
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-undertow</artifactId>
<version>2.21.0</version>
<version>2.21.2</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.21.0</version>
<version>2.21.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -19,20 +19,9 @@ package org.keycloak.adapters.camel.undertow;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.component.undertow.RestUndertowHttpBinding;
import org.apache.camel.component.undertow.UndertowComponent;
import org.apache.camel.component.undertow.UndertowEndpoint;
import org.apache.camel.spi.RestConfiguration;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.HostUtils;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.URISupport;
/**
*
@@ -52,136 +41,8 @@ public class UndertowKeycloakComponent extends UndertowComponent {
return new UndertowKeycloakEndpoint(endpointUri.toString(), component);
}
// TODO: uncomment line below after backport of https://issues.apache.org/jira/browse/CAMEL-12514 into fuse
// @Override
@Override
protected String getComponentName() {
return "undertow-keycloak";
}
// TODO: remove all below this line after backport of https://issues.apache.org/jira/browse/CAMEL-12514 into fuse
@Override
public Consumer createConsumer(CamelContext camelContext, Processor processor, String verb, String basePath, String uriTemplate,
String consumes, String produces, RestConfiguration configuration, Map<String, Object> parameters) throws Exception {
return doCreateConsumer(camelContext, processor, verb, basePath, uriTemplate, consumes, produces, configuration, parameters, false);
}
@Override
public Consumer createApiConsumer(CamelContext camelContext, Processor processor, String contextPath,
RestConfiguration configuration, Map<String, Object> parameters) throws Exception {
// reuse the createConsumer method we already have. The api need to use GET and match on uri prefix
return doCreateConsumer(camelContext, processor, "GET", contextPath, null, null, null, configuration, parameters, true);
}
Consumer doCreateConsumer(CamelContext camelContext, Processor processor, String verb, String basePath, String uriTemplate,
String consumes, String produces, RestConfiguration configuration, Map<String, Object> parameters, boolean api) throws Exception {
String path = basePath;
if (uriTemplate != null) {
// make sure to avoid double slashes
if (uriTemplate.startsWith("/")) {
path = path + uriTemplate;
} else {
path = path + "/" + uriTemplate;
}
}
path = FileUtil.stripLeadingSeparator(path);
String scheme = "http";
String host = "";
int port = 0;
RestConfiguration config = configuration;
if (config == null) {
config = camelContext.getRestConfiguration(getComponentName(), true);
}
if (config.getScheme() != null) {
scheme = config.getScheme();
}
if (config.getHost() != null) {
host = config.getHost();
}
int num = config.getPort();
if (num > 0) {
port = num;
}
// prefix path with context-path if configured in rest-dsl configuration
String contextPath = config.getContextPath();
if (ObjectHelper.isNotEmpty(contextPath)) {
contextPath = FileUtil.stripTrailingSeparator(contextPath);
contextPath = FileUtil.stripLeadingSeparator(contextPath);
if (ObjectHelper.isNotEmpty(contextPath)) {
path = contextPath + "/" + path;
}
}
// if no explicit hostname set then resolve the hostname
if (ObjectHelper.isEmpty(host)) {
if (config.getRestHostNameResolver() == RestConfiguration.RestHostNameResolver.allLocalIp) {
host = "0.0.0.0";
} else if (config.getRestHostNameResolver() == RestConfiguration.RestHostNameResolver.localHostName) {
host = HostUtils.getLocalHostName();
} else if (config.getRestHostNameResolver() == RestConfiguration.RestHostNameResolver.localIp) {
host = HostUtils.getLocalIp();
}
}
Map<String, Object> map = new HashMap<String, Object>();
// build query string, and append any endpoint configuration properties
if (config.getComponent() == null || config.getComponent().equals(getComponentName())) {
// setup endpoint options
if (config.getEndpointProperties() != null && !config.getEndpointProperties().isEmpty()) {
map.putAll(config.getEndpointProperties());
}
}
boolean explicitOptions = true;
// must use upper case for restrict
String restrict = verb.toUpperCase(Locale.US);
// allow OPTIONS in rest-dsl to allow clients to call the API and have responses with ALLOW headers
if (!restrict.contains("OPTIONS")) {
restrict += ",OPTIONS";
// this is not an explicit OPTIONS path in the rest-dsl
explicitOptions = false;
}
boolean cors = config.isEnableCORS();
if (cors) {
// allow HTTP Options as we want to handle CORS in rest-dsl
map.put("optionsEnabled", "true");
} else if (explicitOptions) {
// the rest-dsl is using OPTIONS
map.put("optionsEnabled", "true");
}
String query = URISupport.createQueryString(map);
String url;
if (api) {
url = getComponentName() + ":%s://%s:%s/%s?matchOnUriPrefix=true&httpMethodRestrict=%s";
} else {
url = getComponentName() + ":%s://%s:%s/%s?matchOnUriPrefix=false&httpMethodRestrict=%s";
}
// get the endpoint
url = String.format(url, scheme, host, port, path, restrict);
if (!query.isEmpty()) {
url = url + "&" + query;
}
UndertowEndpoint endpoint = camelContext.getEndpoint(url, UndertowEndpoint.class);
setProperties(camelContext, endpoint, parameters);
if (!map.containsKey("undertowHttpBinding")) {
// use the rest binding, if not using a custom http binding
endpoint.setUndertowHttpBinding(new RestUndertowHttpBinding());
}
// configure consumer properties
Consumer consumer = endpoint.createConsumer(processor);
if (config.getConsumerProperties() != null && !config.getConsumerProperties().isEmpty()) {
setProperties(camelContext, consumer, config.getConsumerProperties());
}
return consumer;
}
}
+1 -10
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-fuse7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -85,15 +85,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
+16 -3
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -38,8 +38,21 @@
<modules>
<module>camel-undertow</module>
<module>jetty94</module>
<module>tomcat8</module>
<module>undertow</module>
</modules>
<profiles>
<profile>
<id>community</id>
<activation>
<property>
<name>!product</name>
</property>
</activation>
<modules>
<module>jetty94</module>
<module>tomcat8</module>
</modules>
</profile>
</profiles>
</project>
+1 -10
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-fuse7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -70,15 +70,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
+5 -11
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-fuse7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -31,6 +31,9 @@
<packaging>bundle</packaging>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<keycloak.osgi.export>
org.keycloak.adapters.osgi.undertow.*;version="${project.version}"
</keycloak.osgi.export>
@@ -43,7 +46,7 @@
org.apache.cxf.transport.http;resolution:=optional;version="[3,4)",
org.apache.cxf.transport.http_undertow;resolution:=optional;version="[3,4)",
org.apache.cxf.transport.servlet;resolution:=optional;version="[3,4)",
io.undertow.*,
io.undertow.*;version="[1.4,3)",
*;resolution:=optional
</keycloak.osgi.import>
<keycloak.osgi.fragment>org.ops4j.pax.web.pax-web-undertow</keycloak.osgi.fragment>
@@ -107,15 +110,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
+2 -15
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -69,22 +69,9 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -24,16 +24,13 @@ import org.keycloak.OAuthErrorException;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.ServerRequest;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.adapters.rotation.AdapterTokenVerifier;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.IDToken;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.HttpHeaders;
@@ -537,15 +534,9 @@ public class KeycloakInstalled {
refreshToken = tokenResponse.getRefreshToken();
idTokenString = tokenResponse.getIdToken();
token = AdapterRSATokenVerifier.verifyToken(tokenString, deployment);
if (idTokenString != null) {
try {
JWSInput input = new JWSInput(idTokenString);
idToken = input.readJsonContent(IDToken.class);
} catch (JWSInputException e) {
throw new VerificationException();
}
}
AdapterTokenVerifier.VerifiedTokens tokens = AdapterTokenVerifier.verifyTokens(tokenString, idTokenString, deployment);
token = tokens.getAccessToken();
idToken = tokens.getIdToken();
}
public AccessToken getToken() {
+2 -14
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -33,7 +33,7 @@
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
@@ -87,17 +87,5 @@
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
+45 -52
View File
@@ -14,21 +14,24 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-jetty-core</artifactId>
<name>Keycloak Jetty Core Integration</name>
<artifactId>keycloak-jetty-core</artifactId>
<name>Keycloak Jetty Core Integration</name>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<jetty9.version>8.1.17.v20150415</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.core.*
@@ -40,18 +43,17 @@
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
@@ -61,29 +63,29 @@
<artifactId>keycloak-jetty-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -105,23 +107,14 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -154,7 +147,7 @@
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</plugins>
</build>
</project>
@@ -85,7 +85,7 @@ public class JettyCookieTokenStore implements AdapterTokenStore {
@Override
public void logout() {
CookieTokenStore.removeCookie(facade);
CookieTokenStore.removeCookie(deployment, facade);
}
@@ -113,7 +113,7 @@ public class JettyCookieTokenStore implements AdapterTokenStore {
if (success && session.isActive()) return principal;
log.debugf("Cleanup and expire cookie for user %s after failed refresh", principal.getName());
CookieTokenStore.removeCookie(facade);
CookieTokenStore.removeCookie(deployment, facade);
return null;
}
+42 -49
View File
@@ -14,21 +14,24 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-jetty81-adapter</artifactId>
<name>Keycloak Jetty 8.1.x Integration</name>
<artifactId>keycloak-jetty81-adapter</artifactId>
<name>Keycloak Jetty 8.1.x Integration</name>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<jetty9.version>8.1.17.v20150415</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.*
@@ -39,18 +42,17 @@
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
@@ -63,26 +65,26 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-jetty-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -104,23 +106,14 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -153,7 +146,7 @@
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</plugins>
</build>
</project>
+48 -49
View File
@@ -14,20 +14,20 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-jetty91-adapter</artifactId>
<name>Keycloak Jetty 9.1.x Integration</name>
<artifactId>keycloak-jetty91-adapter</artifactId>
<name>Keycloak Jetty 9.1.x Integration</name>
<properties>
<jetty9.version>9.1.5.v20140505</jetty9.version>
<keycloak.osgi.export>
@@ -40,18 +40,17 @@
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
@@ -67,33 +66,33 @@
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</exclusion>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -115,22 +114,22 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
@@ -164,7 +163,7 @@
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</plugins>
</build>
</project>
+42 -49
View File
@@ -14,21 +14,24 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-jetty92-adapter</artifactId>
<name>Keycloak Jetty 9.2.x Integration</name>
<artifactId>keycloak-jetty92-adapter</artifactId>
<name>Keycloak Jetty 9.2.x Integration</name>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<jetty9.version>9.2.4.v20141103</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.*
@@ -40,18 +43,17 @@
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
@@ -60,26 +62,26 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-jetty-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -101,23 +103,14 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -150,7 +143,7 @@
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</plugins>
</build>
</project>
+39 -49
View File
@@ -14,20 +14,20 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-jetty93-adapter</artifactId>
<name>Keycloak Jetty 9.3.x Integration</name>
<artifactId>keycloak-jetty93-adapter</artifactId>
<name>Keycloak Jetty 9.3.x Integration</name>
<properties>
<jetty9.version>9.3.9.v20160517</jetty9.version>
<keycloak.osgi.export>
@@ -40,18 +40,17 @@
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
@@ -60,26 +59,26 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-jetty-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -101,23 +100,14 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -150,7 +140,7 @@
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</plugins>
</build>
</project>
+39 -49
View File
@@ -14,20 +14,20 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-jetty94-adapter</artifactId>
<name>Keycloak Jetty 9.4.x Integration</name>
<artifactId>keycloak-jetty94-adapter</artifactId>
<name>Keycloak Jetty 9.4.x Integration</name>
<properties>
<jetty9.version>9.4.2.v20170220</jetty9.version>
<keycloak.osgi.export>
@@ -40,18 +40,17 @@
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
@@ -60,26 +59,26 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-jetty-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -101,23 +100,14 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -150,7 +140,7 @@
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</plugins>
</build>
</project>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Jetty Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+20 -12
View File
@@ -29,7 +29,7 @@ export = Keycloak;
declare function Keycloak(config?: string|{}): Keycloak.KeycloakInstance;
declare namespace Keycloak {
type KeycloakAdapterName = 'cordova'|'default' | any;
type KeycloakAdapterName = 'cordova' | 'cordova-native' |'default' | any;
type KeycloakOnLoad = 'login-required'|'check-sso';
type KeycloakResponseMode = 'query'|'fragment';
type KeycloakResponseType = 'code'|'id_token token'|'code id_token token';
@@ -98,6 +98,12 @@ declare namespace Keycloak {
*/
responseMode?: KeycloakResponseMode;
/**
* Specifies a default uri to redirect to after login or logout.
* This is currently supported for adapter 'cordova-native' and 'default'
*/
redirectUri?: string;
/**
* Set the OpenID Connect flow.
* @default standard
@@ -210,6 +216,16 @@ declare namespace Keycloak {
createdTimestamp?: number;
}
interface KeycloakTokenParsed {
exp?: number;
iat?: number;
nonce?: string;
sub?: string;
session_state?: string;
realm_access?: { roles: string[] };
resource_access?: string[];
}
// export interface KeycloakUserInfo {}
/**
@@ -263,15 +279,7 @@ declare namespace Keycloak {
/**
* The parsed token as a JavaScript object.
*/
tokenParsed?: {
exp?: number;
iat?: number;
nonce?: string;
sub?: string;
session_state?: string;
realm_access?: { roles: string[] };
resource_access?: string[];
};
tokenParsed?: KeycloakTokenParsed;
/**
* The base64 encoded refresh token that can be used to retrieve a new token.
@@ -281,7 +289,7 @@ declare namespace Keycloak {
/**
* The parsed refresh token as a JavaScript object.
*/
refreshTokenParsed?: { nonce?: string };
refreshTokenParsed?: KeycloakTokenParsed;
/**
* The base64 encoded ID token.
@@ -291,7 +299,7 @@ declare namespace Keycloak {
/**
* The parsed id token as a JavaScript object.
*/
idTokenParsed?: { nonce?: string };
idTokenParsed?: KeycloakTokenParsed;
/**
* The estimated time difference between the browser time and the Keycloak
+135 -53
View File
@@ -46,11 +46,10 @@
kc.authenticated = false;
callbackStorage = createCallbackStorage();
var adapters = ['default', 'cordova', 'cordova-native'];
if (initOptions && initOptions.adapter === 'cordova') {
adapter = loadAdapter('cordova');
} else if (initOptions && initOptions.adapter === 'default') {
adapter = loadAdapter();
if (initOptions && adapters.indexOf(initOptions.adapter) > -1) {
adapter = loadAdapter(initOptions.adapter);
} else if (initOptions && typeof initOptions.adapter === "object") {
adapter = initOptions.adapter;
} else {
@@ -74,6 +73,12 @@
loginIframe.interval = initOptions.checkLoginIframeInterval;
}
if (initOptions.promiseType === 'native') {
kc.useNativePromise = typeof Promise === "function";
} else {
kc.useNativePromise = false;
}
if (initOptions.onLoad === 'login-required') {
kc.loginRequired = true;
}
@@ -106,6 +111,10 @@
if (initOptions.timeSkew != null) {
kc.timeSkew = initOptions.timeSkew;
}
if(initOptions.redirectUri) {
kc.redirectUri = initOptions.redirectUri;
}
}
if (!kc.responseMode) {
@@ -116,9 +125,9 @@
kc.flow = 'standard';
}
var promise = createPromise();
var promise = createPromise(false);
var initPromise = createPromise();
var initPromise = createPromise(true);
initPromise.promise.success(function() {
kc.onReady && kc.onReady(kc.authenticated);
promise.setSuccess(kc.authenticated);
@@ -145,10 +154,14 @@
case 'check-sso':
if (loginIframe.enable) {
setupCheckLoginIframe().success(function() {
checkLoginIframe().success(function () {
doLogin(false);
checkLoginIframe().success(function (unchanged) {
if (!unchanged) {
doLogin(false);
} else {
initPromise.setSuccess();
}
}).error(function () {
initPromise.setSuccess();
initPromise.setError();
});
});
} else {
@@ -167,7 +180,7 @@
var callback = parseCallback(window.location.href);
if (callback) {
window.history.replaceState({}, null, callback.newUrl);
window.history.replaceState(window.history.state, null, callback.newUrl);
}
if (callback && callback.valid) {
@@ -182,12 +195,16 @@
if (loginIframe.enable) {
setupCheckLoginIframe().success(function() {
checkLoginIframe().success(function () {
kc.onAuthSuccess && kc.onAuthSuccess();
initPromise.setSuccess();
checkLoginIframe().success(function (unchanged) {
if (unchanged) {
kc.onAuthSuccess && kc.onAuthSuccess();
initPromise.setSuccess();
scheduleCheckIframe();
} else {
initPromise.setSuccess();
}
}).error(function () {
setToken(null, null, null);
initPromise.setSuccess();
initPromise.setError();
});
});
} else {
@@ -359,7 +376,7 @@
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Authorization', 'bearer ' + kc.token);
var promise = createPromise();
var promise = createPromise(false);
req.onreadystatechange = function () {
if (req.readyState == 4) {
@@ -384,7 +401,7 @@
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Authorization', 'bearer ' + kc.token);
var promise = createPromise();
var promise = createPromise(false);
req.onreadystatechange = function () {
if (req.readyState == 4) {
@@ -420,7 +437,7 @@
}
kc.updateToken = function(minValidity) {
var promise = createPromise();
var promise = createPromise(false);
if (!kc.refreshToken) {
promise.setError();
@@ -584,6 +601,7 @@
var tokenResponse = JSON.parse(req.responseText);
authSuccess(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token'], kc.flow === 'standard');
scheduleCheckIframe();
} else {
kc.onAuthError && kc.onAuthError();
promise && promise.setError();
@@ -617,7 +635,7 @@
}
function loadConfig(url) {
var promise = createPromise();
var promise = createPromise(true);
var configUrl;
if (!config) {
@@ -907,7 +925,7 @@
supportedParams = ['code', 'state', 'session_state'];
break;
case 'implicit':
supportedParams = ['access_token', 'id_token', 'state', 'session_state'];
supportedParams = ['access_token', 'token_type', 'id_token', 'state', 'session_state', 'expires_in'];
break;
case 'hybrid':
supportedParams = ['access_token', 'id_token', 'code', 'state', 'session_state'];
@@ -976,8 +994,8 @@
return result;
}
function createPromise() {
if (typeof Promise === "function") {
function createPromise(internal) {
if (!internal && kc.useNativePromise) {
return createNativePromise();
} else {
return createLegacyPromise();
@@ -989,12 +1007,10 @@
// interface of the custom promise type previously used by the API
var p = {
setSuccess: function(result) {
p.success = true;
p.resolve(result);
},
setError: function(result) {
p.success = false;
p.reject(result);
}
};
@@ -1002,14 +1018,6 @@
p.resolve = resolve;
p.reject = reject;
});
p.promise.success = function(callback) {
p.promise.then(callback);
return p.promise;
}
p.promise.error = function(callback) {
p.promise.catch(callback);
return p.promise;
}
return p;
}
@@ -1054,7 +1062,7 @@
}
function setupCheckLoginIframe() {
var promise = createPromise();
var promise = createPromise(true);
if (!loginIframe.enable) {
promise.setSuccess();
@@ -1077,8 +1085,6 @@
loginIframe.iframeOrigin = authUrl.substring(0, authUrl.indexOf('/', 8));
}
promise.setSuccess();
setTimeout(check, loginIframe.interval * 1000);
}
var src = kc.endpoints.checkSessionIframe();
@@ -1105,31 +1111,38 @@
for (var i = callbacks.length - 1; i >= 0; --i) {
var promise = callbacks[i];
if (event.data == 'unchanged') {
promise.setSuccess();
} else {
if (event.data == 'error') {
promise.setError();
} else {
promise.setSuccess(event.data == 'unchanged');
}
}
};
window.addEventListener('message', messageCallback, false);
var check = function() {
checkLoginIframe();
if (kc.token) {
setTimeout(check, loginIframe.interval * 1000);
}
};
return promise.promise;
}
function scheduleCheckIframe() {
if (loginIframe.enable) {
if (kc.token) {
setTimeout(function() {
checkLoginIframe().success(function(unchanged) {
if (unchanged) {
scheduleCheckIframe();
}
});
}, loginIframe.interval * 1000);
}
}
}
function checkLoginIframe() {
var promise = createPromise();
var promise = createPromise(true);
if (loginIframe.iframe && loginIframe.iframeOrigin ) {
var msg = kc.clientId + ' ' + kc.sessionId;
var msg = kc.clientId + ' ' + (kc.sessionId ? kc.sessionId : '');
loginIframe.callbackList.push(promise);
var origin = loginIframe.iframeOrigin;
if (loginIframe.callbackList.length == 1) {
@@ -1146,17 +1159,17 @@
if (!type || type == 'default') {
return {
login: function(options) {
window.location.href = kc.createLoginUrl(options);
window.location.replace(kc.createLoginUrl(options));
return createPromise().promise;
},
logout: function(options) {
window.location.href = kc.createLogoutUrl(options);
window.location.replace(kc.createLogoutUrl(options));
return createPromise().promise;
},
register: function(options) {
window.location.href = kc.createRegisterUrl(options);
window.location.replace(kc.createRegisterUrl(options));
return createPromise().promise;
},
@@ -1167,7 +1180,7 @@
} else {
throw "Not supported by the OIDC server";
}
return createPromise().promise;
return createPromise(false).promise;
},
redirectUri: function(options, encodeHash) {
@@ -1226,7 +1239,7 @@
return {
login: function(options) {
var promise = createPromise();
var promise = createPromise(false);
var cordovaOptions = createCordovaOptions(options);
var loginUrl = kc.createLoginUrl(options);
@@ -1274,7 +1287,7 @@
},
logout: function(options) {
var promise = createPromise();
var promise = createPromise(false);
var logoutUrl = kc.createLogoutUrl(options);
var ref = cordovaOpenWindowWrapper(logoutUrl, '_blank', 'location=no,hidden=yes');
@@ -1339,6 +1352,75 @@
}
}
if (type == 'cordova-native') {
loginIframe.enable = false;
return {
login: function(options) {
var promise = createPromise(false);
var loginUrl = kc.createLoginUrl(options);
universalLinks.subscribe('keycloak', function(event) {
universalLinks.unsubscribe('keycloak');
window.cordova.plugins.browsertab.close();
var oauth = parseCallback(event.url);
processCallback(oauth, promise);
});
window.cordova.plugins.browsertab.openUrl(loginUrl);
return promise.promise;
},
logout: function(options) {
var promise = createPromise(false);
var logoutUrl = kc.createLogoutUrl(options);
universalLinks.subscribe('keycloak', function(event) {
universalLinks.unsubscribe('keycloak');
window.cordova.plugins.browsertab.close();
kc.clearToken();
promise.setSuccess();
});
window.cordova.plugins.browsertab.openUrl(logoutUrl);
return promise.promise;
},
register : function(options) {
var promise = createPromise(false);
var registerUrl = kc.createRegisterUrl(options);
universalLinks.subscribe('keycloak' , function(event) {
universalLinks.unsubscribe('keycloak');
window.cordova.plugins.browsertab.close();
var oauth = parseCallback(event.url);
processCallback(oauth, promise);
});
window.cordova.plugins.browsertab.openUrl(registerUrl);
return promise.promise;
},
accountManagement : function() {
var accountUrl = kc.createAccountUrl();
if (typeof accountUrl !== 'undefined') {
window.cordova.plugins.browsertab.openUrl(accountUrl);
} else {
throw "Not supported by the OIDC server";
}
},
redirectUri: function(options) {
if (options && options.redirectUri) {
return options.redirectUri;
} else if (kc.redirectUri) {
return kc.redirectUri;
} else {
return "http://localhost";
}
}
}
}
throw 'invalid adapter type: ' + type;
}
@@ -23,9 +23,20 @@
function checkState(clientId, origin, sessionState, callback) {
var cookie = getCookie();
if (!cookie) {
callback('changed');
} else if (!init) {
var checkCookie = function() {
if (clientId === init.clientId && origin === init.origin) {
var c = cookie.split('/');
if (sessionState === c[2]) {
callback('unchanged');
} else {
callback('changed');
}
} else {
callback('error');
}
}
if (!init) {
var req = new XMLHttpRequest();
var url = location.href.split("?")[0] + "/init";
@@ -41,9 +52,15 @@
clientId: clientId,
origin: origin
}
callback('unchanged');
} else if (req.status === 404) {
callback('changed');
if (!cookie) {
if (sessionState != '') {
callback('changed');
} else {
callback('unchanged');
}
} else {
checkCookie();
}
} else {
callback('error');
}
@@ -51,17 +68,14 @@
};
req.send();
} else {
if (clientId === init.clientId && origin === init.origin) {
var c = cookie.split('/');
if (sessionState === c[2]) {
callback('unchanged');
} else {
callback('changed');
}
} else if (!cookie) {
if (sessionState != '') {
callback('changed');
} else {
callback('error');
callback('unchanged');
}
} else {
checkCookie();
}
}
+1 -9
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -39,14 +39,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
+4 -10
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -31,6 +31,9 @@
<packaging>jar</packaging>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<jetty9.version>8.1.17.v20150415</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.osgi.*
@@ -104,15 +107,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -0,0 +1,89 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.osgi;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.jboss.logging.Logger;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OIDCHttpFacade;
/**
* This {@link KeycloakConfigResolver} tries to resolve most specific configuration for given URI path. If not found,
* <em>parent</em> path is checked up to top-level path.
*/
public class HierarchicalPathBasedKeycloakConfigResolver extends PathBasedKeycloakConfigResolver {
protected static final Logger log = Logger.getLogger(HierarchicalPathBasedKeycloakConfigResolver.class);
public HierarchicalPathBasedKeycloakConfigResolver() {
prepopulateCache();
}
@Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
// we cached all available deployments initially and now we'll try to check them from
// most specific to most general
URI uri = URI.create(request.getURI());
String path = uri.getPath();
if (path != null) {
while (path.startsWith("/")) {
path = path.substring(1);
}
String[] segments = path.split("/");
List<String> paths = collectPaths(segments);
for (String pathFragment: paths) {
KeycloakDeployment cachedDeployment = super.getCachedDeployment(pathFragment);
if (cachedDeployment != null) {
return cachedDeployment;
}
}
}
throw new IllegalStateException("Can't find Keycloak configuration related to URI path " + uri);
}
/**
* <p>For segments like "a, b, c, d", returns:<ul>
* <li>"a-b-c-d"</li>
* <li>"a-b-c"</li>
* <li>"a-b"</li>
* <li>"a"</li>
* <li>""</li>
* </ul></p>
* @param segments
* @return
*/
private List<String> collectPaths(String[] segments) {
List<String> result = new ArrayList<>(segments.length + 1);
for (int idx = segments.length; idx >= 0; idx--) {
StringBuilder sb = null;
for (int i = 0; i < idx; i++) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append("-").append(segments[i]);
}
result.add(sb == null ? "" : sb.toString().substring(1));
}
return result;
}
}
@@ -16,12 +16,15 @@
*/
package org.keycloak.adapters.osgi;
import org.jboss.logging.Logger;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.OIDCHttpFacade;
import org.keycloak.adapters.spi.HttpFacade;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
@@ -31,10 +34,118 @@ import java.util.concurrent.ConcurrentHashMap;
public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
protected static final Logger log = Logger.getLogger(PathBasedKeycloakConfigResolver.class);
private final Map<String, KeycloakDeployment> cache = new ConcurrentHashMap<String, KeycloakDeployment>();
private File keycloakConfigLocation = null;
public PathBasedKeycloakConfigResolver() {
String location = null;
String keycloakConfig = (String) System.getProperties().get("keycloak.config");
if (keycloakConfig != null && !"".equals(keycloakConfig.trim())) {
location = keycloakConfig;
} else {
String karafEtc = (String) System.getProperties().get("karaf.etc");
if (karafEtc != null && !"".equals(karafEtc.trim())) {
location = karafEtc;
}
}
if (location != null) {
File loc = new File(location);
if (loc.isDirectory()) {
keycloakConfigLocation = loc;
}
}
}
@Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
String webContext = getDeploymentKeyForURI(request);
return getOrCreateDeployment(webContext);
}
/**
* {@code pathFragment} is a key for {@link KeycloakDeployment deployments}. The key is used to construct
* a path relative to {@code keycloak.config} or {@code karaf.etc} system properties.
* For given key, {@code <key>-keycloak.json} file is checked.
* @param pathFragment
* @return
*/
protected synchronized KeycloakDeployment getOrCreateDeployment(String pathFragment) {
KeycloakDeployment deployment = getCachedDeployment(pathFragment);
if (null == deployment) {
// not found on the simple cache, try to load it from the file system
if (keycloakConfigLocation == null) {
throw new IllegalStateException("Neither \"keycloak.config\" nor \"karaf.etc\" java properties are set." +
" Please set one of them.");
}
File configuration = new File(keycloakConfigLocation, pathFragment + ("".equals(pathFragment) ? "" : "-")
+ "keycloak.json");
if (!cacheConfiguration(pathFragment, configuration)) {
throw new IllegalStateException("Not able to read the file " + configuration);
}
deployment = getCachedDeployment(pathFragment);
}
return deployment;
}
protected synchronized KeycloakDeployment getCachedDeployment(String pathFragment) {
return cache.get(pathFragment);
}
/**
* If there's a need, we can pre populate the cache of deployments.
*/
protected void prepopulateCache() {
if (keycloakConfigLocation == null || !keycloakConfigLocation.isDirectory()) {
log.warn("Can't cache Keycloak configurations. No configuration storage is accessible." +
" Please set either \"keycloak.config\" or \"karaf.etc\" system properties");
return;
}
File[] configs = keycloakConfigLocation.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile() && pathname.getName().endsWith("keycloak.json");
}
});
if (configs != null) {
for (File config: configs) {
String pathFragment = null;
if ("keycloak.json".equals(config.getName())) {
pathFragment = "";
} else if (config.getName().endsWith("-keycloak.json")) {
pathFragment = config.getName()
.substring(0, config.getName().length() - "-keycloak.json".length());
}
cacheConfiguration(pathFragment, config);
}
}
}
private boolean cacheConfiguration(String key, File config) {
try {
InputStream is = new FileInputStream(config);
KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(is);
cache.put(key, deployment);
return true;
} catch (FileNotFoundException | RuntimeException e) {
log.warn("Can't cache " + config + ": " + e.getMessage(), e);
return false;
}
}
/**
* Finds a context path from given {@link HttpFacade.Request}. For default context, first path segment
* is returned.
* @param request
* @return
*/
private String getDeploymentKeyForURI(HttpFacade.Request request) {
String uri = request.getURI();
String relativePath = request.getRelativePath();
String webContext = null;
@@ -48,7 +159,9 @@ public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
} else {
URI parsedURI = URI.create(uri);
String path = parsedURI.getPath();
path = path.substring(0, path.indexOf(relativePath));
if (path.contains(relativePath)) {
path = path.substring(0, path.indexOf(relativePath));
}
while (path.startsWith("/")) {
path = path.substring(1);
}
@@ -65,31 +178,7 @@ public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
}
}
KeycloakDeployment deployment = cache.get(webContext);
if (null == deployment) {
// not found on the simple cache, try to load it from the file system
String keycloakConfig = (String) System.getProperties().get("keycloak.config");
if(keycloakConfig == null || "".equals(keycloakConfig.trim())){
String karafEtc = (String) System.getProperties().get("karaf.etc");
if(karafEtc == null || "".equals(karafEtc.trim())){
throw new IllegalStateException("Neither \"keycloak.config\" nor \"karaf.etc\" java properties are set. Please set one of them.");
}
keycloakConfig = karafEtc;
}
String absolutePath = keycloakConfig + File.separator + webContext + ("".equals(webContext) ? "" : "-")
+ "keycloak.json";
InputStream is = null;
try {
is = new FileInputStream(absolutePath);
} catch (FileNotFoundException e){
throw new IllegalStateException("Not able to find the file " + absolutePath);
}
deployment = KeycloakDeploymentBuilder.build(is);
cache.put(webContext, deployment);
}
return deployment;
return webContext;
}
}
@@ -0,0 +1,162 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.osgi;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OIDCHttpFacade;
import org.keycloak.adapters.spi.AuthenticationError;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.spi.LogoutError;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
public class HierarchicalPathBasedKeycloakConfigResolverTest {
@Test
public void genericAndSpecificConfigurations() throws Exception {
HierarchicalPathBasedKeycloakConfigResolver resolver = new HierarchicalPathBasedKeycloakConfigResolver();
populate(resolver, true);
assertThat(resolver.resolve(new MockRequest("http://localhost/a/b/c/d/e?a=b")).getRealm(), equalTo("a-b-c-d-e"));
assertThat(resolver.resolve(new MockRequest("http://localhost/a/b/c/d/x?a=b")).getRealm(), equalTo("a-b-c-d"));
assertThat(resolver.resolve(new MockRequest("http://localhost/a/b/c/x/x?a=b")).getRealm(), equalTo("a-b-c"));
assertThat(resolver.resolve(new MockRequest("http://localhost/a/b/x/x/x?a=b")).getRealm(), equalTo("a-b"));
assertThat(resolver.resolve(new MockRequest("http://localhost/a/x/x/x/x?a=b")).getRealm(), equalTo("a"));
assertThat(resolver.resolve(new MockRequest("http://localhost/x/x/x/x/x?a=b")).getRealm(), equalTo(""));
populate(resolver, false);
try {
resolver.resolve(new MockRequest("http://localhost/x/x/x/x/x?a=b"));
fail("Expected java.lang.IllegalStateException: Can't find Keycloak configuration ...");
} catch (IllegalStateException expected) {
}
}
@SuppressWarnings("unchecked")
private PathBasedKeycloakConfigResolver populate(PathBasedKeycloakConfigResolver resolver, boolean fallback)
throws Exception {
Field f = PathBasedKeycloakConfigResolver.class.getDeclaredField("cache");
f.setAccessible(true);
Map<String, KeycloakDeployment> cache = (Map<String, KeycloakDeployment>) f.get(resolver);
cache.clear();
cache.put("a-b-c-d-e", newKeycloakDeployment("a-b-c-d-e"));
cache.put("a-b-c-d", newKeycloakDeployment("a-b-c-d"));
cache.put("a-b-c", newKeycloakDeployment("a-b-c"));
cache.put("a-b", newKeycloakDeployment("a-b"));
cache.put("a", newKeycloakDeployment("a"));
if (fallback) {
cache.put("", newKeycloakDeployment(""));
}
return resolver;
}
private KeycloakDeployment newKeycloakDeployment(String realm) {
KeycloakDeployment deployment = new KeycloakDeployment();
deployment.setRealm(realm);
return deployment;
}
private class MockRequest implements OIDCHttpFacade.Request {
private String uri;
public MockRequest(String uri) {
this.uri = uri;
}
@Override
public String getMethod() {
return null;
}
@Override
public String getURI() {
return this.uri;
}
@Override
public String getRelativePath() {
return null;
}
@Override
public boolean isSecure() {
return false;
}
@Override
public String getFirstParam(String param) {
return null;
}
@Override
public String getQueryParamValue(String param) {
return null;
}
@Override
public HttpFacade.Cookie getCookie(String cookieName) {
return null;
}
@Override
public String getHeader(String name) {
return null;
}
@Override
public List<String> getHeaders(String name) {
return null;
}
@Override
public InputStream getInputStream() {
return null;
}
@Override
public InputStream getInputStream(boolean buffered) {
return null;
}
@Override
public String getRemoteAddr() {
return null;
}
@Override
public void setError(AuthenticationError error) {
}
@Override
public void setError(LogoutError error) {
}
}
}
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak OIDC Client Adapter Modules</name>
+40 -6
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -30,11 +30,21 @@
<name>Keycloak Servlet Filter Adapter Integration</name>
<description/>
<properties>
<keycloak.osgi.export>
org.keycloak.adapters.servlet.*
</keycloak.osgi.export>
<keycloak.osgi.import>
javax.servlet.*;version="[2.5,4)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -86,12 +96,36 @@
</dependencies>
<build>
<plugins>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
+6 -15
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -30,6 +30,11 @@
<name>Keycloak Servlet OAuth Client</name>
<description/>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
@@ -74,7 +79,6 @@
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -83,17 +87,4 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -105,12 +105,4 @@
<version>${spring-boot.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -25,27 +25,17 @@ import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.webapp.WebAppContext;
import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
import org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve;
import org.keycloak.adapters.undertow.KeycloakServletExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.undertow.UndertowDeploymentInfoCustomizer;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.ApplicationContext;
import java.util.ArrayList;
import java.util.HashSet;
@@ -65,6 +55,10 @@ public class KeycloakBaseSpringBootConfiguration {
KeycloakSpringBootConfigResolver.setAdapterConfig(keycloakProperties);
}
@Autowired
public void setApplicationContext(ApplicationContext context) {
KeycloakSpringBootConfigResolverWrapper.setApplicationContext(context);
}
static class KeycloakBaseUndertowDeploymentInfoCustomizer {
@@ -81,7 +75,7 @@ public class KeycloakBaseSpringBootConfiguration {
deploymentInfo.setLoginConfig(loginConfig);
deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolverWrapper.class.getName());
deploymentInfo.addSecurityConstraints(getSecurityConstraints());
deploymentInfo.addServletExtension(new KeycloakServletExtension());
@@ -123,7 +117,7 @@ public class KeycloakBaseSpringBootConfiguration {
public void customize(Server server) {
KeycloakJettyAuthenticator keycloakJettyAuthenticator = new KeycloakJettyAuthenticator();
keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolver());
keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolverWrapper());
/* see org.eclipse.jetty.webapp.StandardDescriptorProcessor#visitSecurityConstraint for an example
on how to map servlet spec to Constraints */
@@ -187,7 +181,7 @@ public class KeycloakBaseSpringBootConfiguration {
WebAppContext webAppContext = server.getBean(WebAppContext.class);
//if not found as registered bean let's try the handler
if(webAppContext==null){
webAppContext = (WebAppContext) server.getHandler();
webAppContext = getWebAppContext(server.getHandlers());
}
ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
@@ -196,6 +190,21 @@ public class KeycloakBaseSpringBootConfiguration {
webAppContext.setSecurityHandler(securityHandler);
}
private WebAppContext getWebAppContext(Handler... handlers) {
for (Handler handler : handlers) {
if (handler instanceof WebAppContext) {
return (WebAppContext) handler;
} else if (handler instanceof HandlerList) {
return getWebAppContext(((HandlerList) handler).getHandlers());
} else if (handler instanceof HandlerCollection) {
return getWebAppContext(((HandlerCollection) handler).getHandlers());
} else if (handler instanceof HandlerWrapper) {
return getWebAppContext(((HandlerWrapper) handler).getHandlers());
}
}
throw new RuntimeException("No WebAppContext found in Jetty server handlers");
}
}
static class KeycloakBaseTomcatContextCustomizer {
@@ -223,9 +232,12 @@ public class KeycloakBaseSpringBootConfiguration {
for (KeycloakSpringBootProperties.SecurityConstraint constraint : keycloakProperties.getSecurityConstraints()) {
SecurityConstraint tomcatConstraint = new SecurityConstraint();
for (String authRole : constraint.getAuthRoles()) {
tomcatConstraint.addAuthRole(authRole);
if(authRole.equals("*") || authRole.equals("**")) {
// For some reasons embed tomcat don't set the auth constraint on true when wildcard is used
tomcatConstraint.setAuthConstraint(true);
}
}
for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
@@ -256,7 +268,7 @@ public class KeycloakBaseSpringBootConfiguration {
context.addConstraint(tomcatConstraint);
}
context.addParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
context.addParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolverWrapper.class.getName());
}
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.springboot;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springsecurity.config.KeycloakSpringConfigResolverWrapper;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
/**
* <p>A specific implementation of {@link KeycloakSpringConfigResolverWrapper} that first tries to register any {@link KeycloakConfigResolver}
* instance provided by the application. if none is provided, {@link KeycloakSpringBootConfigResolver} is set.
*
* <p>This implementation is specially useful when using Spring Boot and Spring Security in the same application where the same {@link KeycloakConfigResolver}
* instance must be used across the different stacks.
*
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class KeycloakSpringBootConfigResolverWrapper extends KeycloakSpringConfigResolverWrapper {
private static ApplicationContext context;
public KeycloakSpringBootConfigResolverWrapper() {
super(new KeycloakSpringBootConfigResolver());
try {
setDelegate(context.getBean(KeycloakConfigResolver.class));
} catch (NoSuchBeanDefinitionException ignore) {
}
}
public static void setApplicationContext(ApplicationContext context) {
KeycloakSpringBootConfigResolverWrapper.context = context;
}
}
@@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.keycloak.adapters.springboot.KeycloakAutoConfiguration
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<artifactId>spring-boot-container-bundle</artifactId>
+4 -13
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -31,6 +31,8 @@
<description/>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<spring-boot.version>1.4.0.RELEASE</spring-boot.version>
<spring.version>4.1.6.RELEASE</spring.version>
<mockito.version>1.9.5</mockito.version>
@@ -125,16 +127,5 @@
<version>${spring-boot.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
+1 -11
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -67,13 +67,11 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.4</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -140,12 +138,4 @@
<version>${spring-boot.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
+1 -4
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -72,19 +72,16 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${apache-httpcomponents.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
@@ -0,0 +1,19 @@
package org.keycloak.adapters.springsecurity.authentication;
import javax.servlet.http.HttpServletRequest;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.RequestAuthenticator;
import org.keycloak.adapters.spi.HttpFacade;
/**
* Creates {@link RequestAuthenticator}s.
*/
public interface RequestAuthenticatorFactory {
/**
* Creates new {@link RequestAuthenticator} instances on a per-request basis.
*/
RequestAuthenticator createRequestAuthenticator(HttpFacade facade, HttpServletRequest request,
KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort);
}
@@ -0,0 +1,17 @@
package org.keycloak.adapters.springsecurity.authentication;
import javax.servlet.http.HttpServletRequest;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.RequestAuthenticator;
import org.keycloak.adapters.spi.HttpFacade;
public class SpringSecurityRequestAuthenticatorFactory implements RequestAuthenticatorFactory {
@Override
public RequestAuthenticator createRequestAuthenticator(HttpFacade facade,
HttpServletRequest request, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort) {
return new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, sslRedirectPort);
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.springsecurity.config;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.spi.HttpFacade;
/**
* Spring applications may use different security stacks in order to enforce access based on the configuration provided
* by a {@code KeycloakDeployment}. This implementation of {@code KeycloakConfigResolver} wraps and avoid calling multiple
* {@code KeycloakConfigResolver} instances but only those defined by applications or set as default by the configuration.
*
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class KeycloakSpringConfigResolverWrapper implements KeycloakConfigResolver {
private KeycloakConfigResolver delegate;
public KeycloakSpringConfigResolverWrapper(KeycloakConfigResolver delegate) {
this.delegate = delegate;
}
@Override
public KeycloakDeployment resolve(HttpFacade.Request facade) {
return delegate.resolve(facade);
}
protected void setDelegate(KeycloakConfigResolver delegate) {
this.delegate = delegate;
}
}
@@ -65,7 +65,7 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
protected AdapterDeploymentContext adapterDeploymentContext() throws Exception {
AdapterDeploymentContextFactoryBean factoryBean;
if (keycloakConfigResolver != null) {
factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigResolver);
factoryBean = new AdapterDeploymentContextFactoryBean(new KeycloakSpringConfigResolverWrapper(keycloakConfigResolver));
}
else {
factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigFileResource);
@@ -94,11 +94,6 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
return new KeycloakPreAuthActionsFilter(httpSessionManager());
}
@Bean
protected KeycloakAuthenticatedActionsFilter keycloakAuthenticatedActionsFilter() {
return new KeycloakAuthenticatedActionsFilter();
}
protected KeycloakCsrfRequestMatcher keycloakCsrfRequestMatcher() {
return new KeycloakCsrfRequestMatcher();
}
@@ -125,8 +120,8 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
.and()
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
.addFilterBefore(keycloakAuthenticatedActionsFilter(), BasicAuthenticationFilter.class)
.addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
.addFilterAfter(keycloakAuthenticatedActionsRequestFilter(), KeycloakSecurityContextRequestFilter.class)
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
.and()
.logout()
@@ -139,4 +134,9 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
protected KeycloakSecurityContextRequestFilter keycloakSecurityContextRequestFilter() {
return new KeycloakSecurityContextRequestFilter();
}
@Bean
protected KeycloakAuthenticatedActionsFilter keycloakAuthenticatedActionsRequestFilter() {
return new KeycloakAuthenticatedActionsFilter();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.springsecurity.filter;
import java.io.IOException;
@@ -26,65 +25,84 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterDeploymentContext;
import org.keycloak.adapters.AuthenticatedActionsHandler;
import org.keycloak.adapters.NodesRegistrationManagement;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OIDCHttpFacade;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
/**
* Exposes a Keycloak adapter {@link AuthenticatedActionsHandler} as a Spring Security filter.
*
* @author <a href="mailto:srossillo@smartling.com">Scott Rossillo</a>
* @version $Revision: 1 $
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class KeycloakAuthenticatedActionsFilter extends GenericFilterBean implements ApplicationContextAware {
private static final Logger log = LoggerFactory.getLogger(KeycloakAuthenticatedActionsFilter.class);
private static final String FILTER_APPLIED = KeycloakAuthenticatedActionsFilter.class.getPackage().getName() + ".authenticated-actions";
private final NodesRegistrationManagement management = new NodesRegistrationManagement();
private ApplicationContext applicationContext;
private AdapterDeploymentContext deploymentContext;
public KeycloakAuthenticatedActionsFilter() {
super();
}
@Override
protected void initFilterBean() throws ServletException {
deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class);
}
@Override
public void destroy() {
log.debug("Unregistering deployment");
management.stop();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpFacade facade = new SimpleHttpFacade((HttpServletRequest)request, (HttpServletResponse)response);
AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deploymentContext.resolveDeployment(facade), (OIDCHttpFacade)facade);
boolean handled = handler.handledRequest();
if (handled) {
log.debug("Authenticated filter handled request: {}", ((HttpServletRequest) request).getRequestURI());
} else {
chain.doFilter(request, response);
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
if (request.getAttribute(FILTER_APPLIED) != null) {
filterChain.doFilter(request, response);
return;
}
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
KeycloakSecurityContext keycloakSecurityContext = getKeycloakPrincipal();
if (keycloakSecurityContext instanceof RefreshableKeycloakSecurityContext) {
HttpFacade facade = new SimpleHttpFacade((HttpServletRequest) request, (HttpServletResponse) response);
KeycloakDeployment deployment = resolveDeployment(request, response);
AuthenticatedActionsHandler actions = new AuthenticatedActionsHandler(deployment, OIDCHttpFacade.class.cast(facade));
if (actions.handledRequest()) {
return;
}
}
filterChain.doFilter(request, response);
}
@Override
protected void initFilterBean() {
deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
private KeycloakSecurityContext getKeycloakPrincipal() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
Object principal = authentication.getPrincipal();
if (principal instanceof KeycloakPrincipal) {
return KeycloakPrincipal.class.cast(principal).getKeycloakSecurityContext();
}
}
return null;
}
private KeycloakDeployment resolveDeployment(ServletRequest servletRequest, ServletResponse servletResponse) {
return deploymentContext.resolveDeployment(new SimpleHttpFacade(HttpServletRequest.class.cast(servletRequest), HttpServletResponse.class.cast(servletResponse)));
}
private void clearAuthenticationContext() {
SecurityContextHolder.clearContext();
}
}
@@ -34,7 +34,8 @@ import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationFailureHandler;
import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticator;
import org.keycloak.adapters.springsecurity.authentication.RequestAuthenticatorFactory;
import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticatorFactory;
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
import org.keycloak.adapters.springsecurity.token.AdapterTokenStoreFactory;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
@@ -83,6 +84,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
private AdapterDeploymentContext adapterDeploymentContext;
private AdapterTokenStoreFactory adapterTokenStoreFactory = new SpringSecurityAdapterTokenStoreFactory();
private AuthenticationManager authenticationManager;
private RequestAuthenticatorFactory requestAuthenticatorFactory = new SpringSecurityRequestAuthenticatorFactory();
/**
* Creates a new Keycloak authentication processing filter with given {@link AuthenticationManager} and the
@@ -142,7 +144,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
AdapterTokenStore tokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, request);
RequestAuthenticator authenticator
= new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, -1);
= requestAuthenticatorFactory.createRequestAuthenticator(facade, request, deployment, tokenStore, -1);
AuthOutcome result = authenticator.authenticate();
log.debug("Auth outcome: {}", result);
@@ -249,4 +251,14 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
public final void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
throw new UnsupportedOperationException("This filter does not support explicitly setting a continue chain before success policy");
}
}
/**
* Sets the request authenticator factory to use when creating per-request authenticators.
*
* @param requestAuthenticatorFactory the <code>RequestAuthenticatorFactory</code> to use
*/
public void setRequestAuthenticatorFactory(RequestAuthenticatorFactory requestAuthenticatorFactory) {
Assert.notNull(requestAuthenticatorFactory, "RequestAuthenticatorFactory cannot be null");
this.requestAuthenticatorFactory = requestAuthenticatorFactory;
}
}
@@ -48,10 +48,11 @@ public class KeycloakPreAuthActionsFilter extends GenericFilterBean implements A
private static final Logger log = LoggerFactory.getLogger(KeycloakPreAuthActionsFilter.class);
private final NodesRegistrationManagement management = new NodesRegistrationManagement();
private NodesRegistrationManagement nodesRegistrationManagement = new NodesRegistrationManagement();
private ApplicationContext applicationContext;
private AdapterDeploymentContext deploymentContext;
private UserSessionManagement userSessionManagement;
private PreAuthActionsHandlerFactory preAuthActionsHandlerFactory = new PreAuthActionsHandlerFactory();
public KeycloakPreAuthActionsFilter() {
super();
@@ -69,7 +70,7 @@ public class KeycloakPreAuthActionsFilter extends GenericFilterBean implements A
@Override
public void destroy() {
log.debug("Unregistering deployment");
management.stop();
nodesRegistrationManagement.stop();
}
@Override
@@ -77,7 +78,8 @@ public class KeycloakPreAuthActionsFilter extends GenericFilterBean implements A
throws IOException, ServletException {
HttpFacade facade = new SimpleHttpFacade((HttpServletRequest)request, (HttpServletResponse)response);
PreAuthActionsHandler handler = new PreAuthActionsHandler(userSessionManagement, deploymentContext, facade);
nodesRegistrationManagement.tryRegister(deploymentContext.resolveDeployment(facade));
PreAuthActionsHandler handler = preAuthActionsHandlerFactory.createPreAuthActionsHandler(facade);
if (handler.handleRequest()) {
log.debug("Pre-auth filter handled request: {}", ((HttpServletRequest) request).getRequestURI());
} else {
@@ -93,4 +95,23 @@ public class KeycloakPreAuthActionsFilter extends GenericFilterBean implements A
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
void setNodesRegistrationManagement(NodesRegistrationManagement nodesRegistrationManagement) {
this.nodesRegistrationManagement = nodesRegistrationManagement;
}
void setPreAuthActionsHandlerFactory(PreAuthActionsHandlerFactory preAuthActionsHandlerFactory) {
this.preAuthActionsHandlerFactory = preAuthActionsHandlerFactory;
}
/**
* Creates {@link PreAuthActionsHandler}s.
*
* Package-private class to enable mocking.
*/
class PreAuthActionsHandlerFactory {
PreAuthActionsHandler createPreAuthActionsHandler(HttpFacade facade) {
return new PreAuthActionsHandler(userSessionManagement, deploymentContext, facade);
}
}
}
@@ -63,13 +63,15 @@ public class KeycloakSecurityContextRequestFilter extends GenericFilterBean impl
RefreshableKeycloakSecurityContext refreshableSecurityContext = (RefreshableKeycloakSecurityContext) keycloakSecurityContext;
KeycloakDeployment deployment = resolveDeployment(request, response);
if (deployment.isAlwaysRefreshToken()) {
if (!refreshableSecurityContext.isActive() || deployment.isAlwaysRefreshToken()) {
if (refreshableSecurityContext.refreshExpiredToken(false)) {
request.setAttribute(KeycloakSecurityContext.class.getName(), refreshableSecurityContext);
} else {
clearAuthenticationContext();
}
}
request.setAttribute(KeycloakSecurityContext.class.getName(), keycloakSecurityContext);
}
filterChain.doFilter(request, response);
@@ -0,0 +1,90 @@
package org.keycloak.adapters.springsecurity.filter;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.adapters.AdapterDeploymentContext;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.NodesRegistrationManagement;
import org.keycloak.adapters.PreAuthActionsHandler;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.spi.UserSessionManagement;
import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.PreAuthActionsHandlerFactory;
import org.mockito.Mock;
import org.springframework.context.ApplicationContext;
public class KeycloakPreAuthActionsFilterTest {
private KeycloakPreAuthActionsFilter filter;
@Mock
private NodesRegistrationManagement nodesRegistrationManagement;
@Mock
private ApplicationContext applicationContext;
@Mock
private AdapterDeploymentContext deploymentContext;
@Mock
private PreAuthActionsHandlerFactory preAuthActionsHandlerFactory;
@Mock
private UserSessionManagement userSessionManagement;
@Mock
private PreAuthActionsHandler preAuthActionsHandler;
@Mock
private KeycloakDeployment deployment;
@Mock
private HttpServletRequest request;
@Mock
private HttpServletResponse response;
@Mock
private FilterChain chain;
@Before
public void setUp() throws Exception {
initMocks(this);
filter = new KeycloakPreAuthActionsFilter(userSessionManagement);
filter.setNodesRegistrationManagement(nodesRegistrationManagement);
filter.setApplicationContext(applicationContext);
filter.setPreAuthActionsHandlerFactory(preAuthActionsHandlerFactory);
when(applicationContext.getBean(AdapterDeploymentContext.class)).thenReturn(deploymentContext);
when(deploymentContext.resolveDeployment(any(HttpFacade.class))).thenReturn(deployment);
when(preAuthActionsHandlerFactory.createPreAuthActionsHandler(any(HttpFacade.class))).thenReturn(preAuthActionsHandler);
filter.initFilterBean();
}
@Test
public void shouldIgnoreChainWhenPreAuthActionHandlerHandled() throws Exception {
when(preAuthActionsHandler.handleRequest()).thenReturn(true);
filter.doFilter(request, response, chain);
verifyZeroInteractions(chain);
verify(nodesRegistrationManagement).tryRegister(deployment);
}
@Test
public void shouldContinueChainWhenPreAuthActionHandlerDidNotHandle() throws Exception {
when(preAuthActionsHandler.handleRequest()).thenReturn(false);
filter.doFilter(request, response, chain);
verify(chain).doFilter(request, response);;
verify(nodesRegistrationManagement).tryRegister(deployment);
}
@After
public void tearDown() {
filter.destroy();
verify(nodesRegistrationManagement).stop();
}
}
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Tomcat Integration</name>
+66 -76
View File
@@ -14,36 +14,38 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-tomcat-core-adapter</artifactId>
<name>Keycloak Tomcat Core Integration</name>
<artifactId>keycloak-tomcat-core-adapter</artifactId>
<name>Keycloak Tomcat Core Integration</name>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<tomcat.version>6.0.41</tomcat.version>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
@@ -51,69 +53,57 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!-- Authorization -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
</dependency>
<!-- Authorization -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>${tomcat.version}</version>
<scope>compile</scope>
</dependency>
-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>${tomcat.version}</version>
<scope>compile</scope>
</dependency>
-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>${tomcat.version}</version>
<scope>compile</scope>
</dependency>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -93,7 +93,7 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
@Override
public void logout() {
CookieTokenStore.removeCookie(facade);
CookieTokenStore.removeCookie(deployment, facade);
}
@Override
@@ -132,7 +132,7 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
log.fine("Cleanup and expire cookie for user " + principal.getName() + " after failed refresh");
request.setUserPrincipal(null);
request.setAuthType(null);
CookieTokenStore.removeCookie(facade);
CookieTokenStore.removeCookie(deployment, facade);
return null;
}
}
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -2
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -38,7 +38,6 @@
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
+45 -55
View File
@@ -14,36 +14,38 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-tomcat8-adapter</artifactId>
<name>Keycloak Tomcat 8 Integration</name>
<artifactId>keycloak-tomcat8-adapter</artifactId>
<name>Keycloak Tomcat 8 Integration</name>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<tomcat.version>8.0.14</tomcat.version>
</properties>
<description />
<description />
<dependencies>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
</dependency>
@@ -78,43 +80,31 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
+5 -11
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -31,10 +31,14 @@
<description/>
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<keycloak.osgi.export>
org.keycloak.adapters.undertow.*
</keycloak.osgi.export>
<keycloak.osgi.import>
io.undertow.*;version="[1.4,3)",
*;resolution:=optional
</keycloak.osgi.import>
</properties>
@@ -43,7 +47,6 @@
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -106,15 +109,6 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
@@ -74,7 +74,7 @@ public class UndertowCookieTokenStore implements AdapterTokenStore {
return true;
} else {
log.debug("Account was not active, removing cookie and returning false");
CookieTokenStore.removeCookie(facade);
CookieTokenStore.removeCookie(deployment, facade);
return false;
}
}
@@ -90,7 +90,7 @@ public class UndertowCookieTokenStore implements AdapterTokenStore {
KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal = CookieTokenStore.getPrincipalFromCookie(deployment, facade, this);
if (principal == null) return;
CookieTokenStore.removeCookie(facade);
CookieTokenStore.removeCookie(deployment, facade);
}
@Override
+2 -8
View File
@@ -22,7 +22,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -31,11 +31,6 @@
<name>Keycloak Wildfly Elytron OIDC Adapter</name>
<description/>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.wildfly.common</groupId>
@@ -55,7 +50,6 @@
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -101,4 +95,4 @@
<scope>provided</scope>
</dependency>
</dependencies>
</project>
</project>
@@ -18,12 +18,9 @@
package org.keycloak.adapters.elytron;
import java.security.Principal;
import org.jboss.logging.Logger;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.CookieTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OidcKeycloakAccount;
@@ -98,7 +95,7 @@ public class ElytronCookieTokenStore implements ElytronTokeStore {
return true;
} else {
log.debug("Account was not active, removing cookie and returning false");
CookieTokenStore.removeCookie(httpFacade);
CookieTokenStore.removeCookie(deployment, httpFacade);
return false;
}
}
@@ -145,7 +142,7 @@ public class ElytronCookieTokenStore implements ElytronTokeStore {
return;
}
CookieTokenStore.removeCookie(this.httpFacade);
CookieTokenStore.removeCookie(this.httpFacade.getDeployment(), this.httpFacade);
if (glo) {
KeycloakSecurityContext ksc = (KeycloakSecurityContext) principal.getKeycloakSecurityContext();
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak WildFly Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -96,6 +96,12 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
.setValidator(new IntRangeValidator(-1, true))
.setAllowExpression(true)
.build();
protected static final SimpleAttributeDefinition PUBLIC_KEY_CACHE_TTL =
new SimpleAttributeDefinitionBuilder("public-key-cache-ttl", ModelType.INT, true)
.setXmlName("public-key-cache-ttl")
.setAllowExpression(true)
.setValidator(new IntRangeValidator(-1, true))
.build();
protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
static {
@@ -108,6 +114,7 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
DEPLOYMENT_ONLY_ATTRIBUTES.add(TOKEN_MINIMUM_TIME_TO_LIVE);
DEPLOYMENT_ONLY_ATTRIBUTES.add(MIN_TIME_BETWEEN_JWKS_REQUESTS);
DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_KEY_CACHE_TTL);
}
protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
@@ -187,6 +187,20 @@ public class SharedAttributeDefinitons {
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition PROXY_URL =
new SimpleAttributeDefinitionBuilder("proxy-url", ModelType.STRING, true)
.setXmlName("proxy-url")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition VERIFY_TOKEN_AUDIENCE =
new SimpleAttributeDefinitionBuilder("verify-token-audience", ModelType.BOOLEAN, true)
.setXmlName("verify-token-audience")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final List<SimpleAttributeDefinition> ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
static {
ATTRIBUTES.add(REALM_PUBLIC_KEY);
@@ -214,6 +228,8 @@ public class SharedAttributeDefinitons {
ATTRIBUTES.add(PRINCIPAL_ATTRIBUTE);
ATTRIBUTES.add(AUTODETECT_BEARER_ONLY);
ATTRIBUTES.add(IGNORE_OAUTH_QUERY_PARAMETER);
ATTRIBUTES.add(PROXY_URL);
ATTRIBUTES.add(VERIFY_TOKEN_AUDIENCE);
}
/**
@@ -49,6 +49,8 @@ keycloak.realm.token-store=cookie or session storage for auth session data
keycloak.realm.principal-attribute=token attribute to use to set Principal name
keycloak.realm.autodetect-bearer-only=autodetect bearer-only requests
keycloak.realm.ignore-oauth-query-parameter=disable query parameter parsing for access_token
keycloak.realm.proxy-url=The URL for the HTTP proxy if one is used.
keycloak.realm.verify-token-audience=If true, then during bearer-only authentication, the adapter will verify if token contains this client name (resource) as an audience
keycloak.secure-deployment=A deployment secured by Keycloak
keycloak.secure-deployment.add=Add a deployment to be secured by Keycloak
@@ -86,9 +88,11 @@ keycloak.secure-deployment.principal-attribute=token attribute to use to set Pri
keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login. Change this to true if you want to turn this off
keycloak.secure-deployment.token-minimum-time-to-live=The adapter will refresh the token if the current token is expired OR will expire in 'token-minimum-time-to-live' seconds or less
keycloak.secure-deployment.min-time-between-jwks-requests=If adapter recognize token signed by unknown public key, it will try to download new public key from keycloak server. However it won't try to download if already tried it in less than 'min-time-between-jwks-requests' seconds
keycloak.secure-deployment.public-key-cache-ttl=Maximum time the downloaded public keys are considered valid. When this time reach, the adapter is forced to download public keys from keycloak server
keycloak.secure-deployment.autodetect-bearer-only=autodetect bearer-only requests
keycloak.secure-deployment.ignore-oauth-query-parameter=disable query parameter parsing for access_token
keycloak.secure-deployment.proxy-url=The URL for the HTTP proxy if one is used.
keycloak.secure-deployment.verify-token-audience=If true, then during bearer-only authentication, the adapter will verify if token contains this client name (resource) as an audience
keycloak.secure-deployment.credential=Credential value
keycloak.credential=Credential
@@ -68,6 +68,8 @@
<xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="autodetect-bearer-only" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="ignore-oauth-query-parameter" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
@@ -111,8 +113,11 @@
<xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="token-minimum-time-to-live" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="min-time-between-jwks-requests" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="public-key-cache-ttl" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="autodetect-bearer-only" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="ignore-oauth-query-parameter" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
@@ -23,11 +23,14 @@
<turn-off-change-session-id-on-login>false</turn-off-change-session-id-on-login>
<token-minimum-time-to-live>10</token-minimum-time-to-live>
<min-time-between-jwks-requests>20</min-time-between-jwks-requests>
<public-key-cache-ttl>3600</public-key-cache-ttl>
<realm-public-key>
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
</realm-public-key>
<auth-server-url>http://localhost:8080/auth</auth-server-url>
<ssl-required>EXTERNAL</ssl-required>
<proxy-url>http://localhost:9000</proxy-url>
<verify-token-audience>true</verify-token-audience>
<credential name="secret">0aa31d98-e0aa-404c-b6e0-e771dba1e798</credential>
</secure-deployment>
<secure-deployment name="http-endpoint">
+3 -16
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -34,7 +34,6 @@
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -84,7 +83,7 @@
<dependency>
<groupId>org.picketbox</groupId>
<artifactId>picketbox</artifactId>
<version>4.0.20.Final</version>
<version>${picketbox.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -109,17 +108,5 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
</project>
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>4.1.0.Final-SNAPSHOT</version>
<version>4.7.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -95,6 +95,18 @@ abstract class AbstractAdapterConfigurationDefinition extends SimpleResourceDefi
.setValidator(new IntRangeValidator(-1, true))
.setAllowExpression(true)
.build();
protected static final SimpleAttributeDefinition PUBLIC_KEY_CACHE_TTL =
new SimpleAttributeDefinitionBuilder("public-key-cache-ttl", ModelType.INT, true)
.setXmlName("public-key-cache-ttl")
.setAllowExpression(true)
.setValidator(new IntRangeValidator(-1, true))
.build();
protected static final SimpleAttributeDefinition ADAPTER_STATE_COOKIE_PATH =
new SimpleAttributeDefinitionBuilder("adapter-state-cookie-path", ModelType.STRING, true)
.setXmlName("adapter-state-cookie-path")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
@@ -108,6 +120,8 @@ abstract class AbstractAdapterConfigurationDefinition extends SimpleResourceDefi
DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
DEPLOYMENT_ONLY_ATTRIBUTES.add(TOKEN_MINIMUM_TIME_TO_LIVE);
DEPLOYMENT_ONLY_ATTRIBUTES.add(MIN_TIME_BETWEEN_JWKS_REQUESTS);
DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_KEY_CACHE_TTL);
DEPLOYMENT_ONLY_ATTRIBUTES.add(ADAPTER_STATE_COOKIE_PATH);
}
static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList();
Loaded 100 of 2406 files, more files were not shown because too many files have changed in this diff. Show more