Compare commits

..
337 Commits
Author SHA1 Message Date
keycloak-bot d3e66fbbf5 Set version to 2.2.0.Test1 2016-08-26 07:27:09 +00:00
Marek Posolda d138b19adb Merge pull request #3142 from vmuzikar/KEYCLOAK-3429
KEYCLOAK-3429 Fix behaviour of redirect_uri parameter with query components
2016-08-24 09:53:29 +02:00
Marek Posolda 3be47dee37 Merge pull request #3162 from mposolda/master
KEYCLOAK-3460 Support for ClientUpdatedEvent
2016-08-23 16:35:14 +02:00
mposolda 494d9973a6 KEYCLOAK-3460 Support for ClientUpdatedEvent 2016-08-23 14:57:31 +02:00
Stian Thorgersen e28a3750cd Merge pull request #3149 from vmuzikar/KEYCLOAK-3437
KEYCLOAK-3437 Add User Federation Console UI test
2016-08-23 12:57:02 +02:00
Stian Thorgersen 014c8e068f Merge pull request #3156 from vmuzikar/KEYCLOAK-3448
KEYCLOAK-3448 Stabilize Internationalization UI Test
2016-08-23 12:55:53 +02:00
Stian Thorgersen 3890867383 Merge pull request #3133 from fkiss/master-email-ibmjdk
KEYCLOAK-3351 TrustStoreEmailTest fix for ibmjdk
2016-08-23 12:54:12 +02:00
Stian Thorgersen d499b8a489 Merge pull request #3159 from stianst/master
KEYCLOAK-3447 Manual upgrade of database schema
2016-08-23 12:38:28 +02:00
Stian Thorgersen c522a20ab9 KEYCLOAK-3447 Manual upgrade of database schema 2016-08-22 10:22:08 +02:00
Vaclav Muzikar 365a1b66c8 KEYCLOAK-3448 Stabilize Internationalization UI Test 2016-08-19 11:40:01 +02:00
Pedro Igor fa1fb3a3a9 Merge pull request #3152 from pedroigor/KEYCLOAK-3377
[KEYCLOAK-3377] - Add pagination to authorization UI
2016-08-18 19:43:34 -03:00
Bill Burke 6592014707 Update users.js 2016-08-18 13:13:08 -04:00
Pedro Igor 4cd0a8e894 [KEYCLOAK-3377] - Add pagination to authorization UI 2016-08-18 13:29:54 -03:00
Stian Thorgersen 7d444c8b13 Merge pull request #3147 from stianst/master
Tweak Travis
2016-08-17 08:08:13 +02:00
Vaclav Muzikar be83e2fb6b KEYCLOAK-3437 Add User Federation Console UI test 2016-08-16 15:47:02 +02:00
Stian Thorgersen ab2368be34 Tweak Travis 2016-08-16 07:49:17 +02:00
Pedro Igor ba076ad159 Merge pull request #3144 from pedroigor/KEYCLOAK-3144
[KEYCLOAK-3144] - Add authorization settings when exporting/importing a realm
2016-08-15 11:49:49 -03:00
Pedro Igor a8d2b810cf [KEYCLOAK-3144] - Add authorization settings when exporting/importing a realm. 2016-08-15 10:35:28 -03:00
Pedro Igor fd983690e2 Merge pull request #3140 from pedroigor/KEYCLOAK-3390
[KEYCLOAK-3390] - Updating authorization objects doesn't invalidate cache in cluster
2016-08-12 12:45:20 -03:00
Marek Posolda 006a0f856e Merge pull request #3143 from mposolda/oidc-dynamic2
KEYCLOAK-3424 Support for save JWKS in OIDC ClientRegistration endpoint
2016-08-12 17:33:07 +02:00
Pedro Igor bfe10e34e7 [KEYCLOAK-3390] - Updating authorization objects doesn't invalidate cache in cluster 2016-08-12 11:15:13 -03:00
mposolda 2cba13db9c KEYCLOAK-3424 Possibility to import JWK key through admin console 2016-08-12 15:51:14 +02:00
mposolda 3eb9134e02 KEYCLOAK-3424 Support for save JWKS in OIDC ClientRegistration endpoint 2016-08-12 15:51:14 +02:00
Vaclav Muzikar b7f2e0b5ff KEYCLOAK-3429 Fix behaviour of redirect_uri parameter with query components 2016-08-12 14:02:17 +02:00
Pedro Igor 27187c11f1 Merge pull request #3138 from pedroigor/KEYCLOAK-3428
[KEYCLOAK-3428] - Removing scope policies in case the resource does not match
2016-08-11 14:59:20 -03:00
Pedro Igor 0030df060b [KEYCLOAK-3428] - Removing scope policies in case the resource does not match 2016-08-11 14:58:14 -03:00
Marek Posolda f6f587e472 Merge pull request #3137 from thomasdarimont/issue/KEYCLOAK-3412-remove-unused-adminEventBuilder-error-method
KEYCLOAK-3412 - Remove erroneous AdminEventBuilder.error method
2016-08-11 17:41:04 +02:00
Marek Posolda 841c6b619a Merge pull request #3136 from mposolda/oidc-dynamic2
OIDC dynamic client registrations from conformance testsuite
2016-08-11 17:16:11 +02:00
Thomas Darimont e0d70a35d6 KEYCLOAK-3412 - Remove erroneous AdminEventBuilder.error method
Wasn't used within the Keycloak codebase and wouldn't have worked either
since the OperationType lookup would always fail since there are no
"_ERROR" operation types.

Signed-off-by: Thomas Darimont <thomas.darimont@gmail.com>
2016-08-11 16:10:49 +02:00
mposolda 0520d465c1 KEYCLOAK-3414 Support for client registration from trusted hosts 2016-08-11 15:55:32 +02:00
mposolda a8fb988e31 KEYCLOAK-3406 OIDC dynamic client registrations specs fixes 2016-08-11 15:54:51 +02:00
Marek Posolda c34d175572 Merge pull request #3135 from mposolda/master
Fix ExportImportTest
2016-08-11 15:53:16 +02:00
mposolda 9c7442c75b Fix ExportImportTest 2016-08-11 15:51:56 +02:00
fkiss de888fc8a1 KEYCLOAK-3351 TrustStoreEmailTest fix for ibmjdk 2016-08-11 10:52:29 +02:00
Marek Posolda 2df7d6252e Merge pull request #3128 from mposolda/master
Set version to 2.2.0-SNAPSHOT
2016-08-10 09:02:13 +02:00
mposolda d52e043322 Set version to 2.2.0-SNAPSHOT 2016-08-10 08:57:18 +02:00
Marek Posolda 6c8d55d534 Merge pull request #3125 from thomasdarimont/issue/KEYCLOAK-3391-hide-service-account-roles-if-service-accounts-disabled
KEYCLOAK-3391 Better control over service account roles tab visibility
2016-08-10 08:16:27 +02:00
Marek Posolda 26bc07b2c4 Merge pull request #3126 from pedroigor/KEYCLOAK-3398
[KEYCLOAK-3398] - Review input fields on AuthZ UI to fetch data on demand
2016-08-10 06:50:51 +02:00
Bill Burke 7f6fc170dc Merge pull request #3119 from fkiss/master-exportimport
KEYCLOAK-3211 - ExportImportTest fix for Wildfly
2016-08-09 20:59:04 -04:00
Bill Burke 741bbf471f Merge pull request #3123 from patriot1burke/master
components import/export
2016-08-09 20:58:20 -04:00
Pedro Igor 70eb27ec83 [KEYCLOAK-3398] - Review input fields on AuthZ UI to fetch data on demand 2016-08-09 21:56:29 -03:00
Thomas Darimont 96b729886f KEYCLOAK-3391 Better control of service account roles tab visibility
Previously the service account roles remain visible when changing
the client type from confidential to public or bearer only.

We now only show the service account roles tab iif:
- service accounts are enabled
- client access type is set to confidential
2016-08-10 00:44:14 +02:00
Bill Burke 530870f05e realm components import/export 2016-08-09 15:06:29 -04:00
Bill Burke 1633f062d5 Merge remote-tracking branch 'upstream/master' 2016-08-09 12:25:13 -04:00
Bill Burke ff703f935f component export/import 2016-08-09 12:25:04 -04:00
fkiss 4974079794 KEYCLOAK-3211 - ExportImportTest fix for Wildfly 2016-08-09 15:20:40 +02:00
Bill Burke d94515cdae Merge pull request #3117 from patriot1burke/master
deployer, jta lookup, merge user fed/storage
2016-08-08 17:46:35 -04:00
Bill Burke f838c697d1 Merge remote-tracking branch 'upstream/master' 2016-08-08 16:04:16 -04:00
Bill Burke d14de43ac7 merge User Federation/Storage menu 2016-08-08 16:02:06 -04:00
Marek Posolda e198e7e0b9 Merge pull request #3116 from mposolda/master
KEYCLOAK-3400 OIDC request with missing response_type should respond …
2016-08-08 21:50:08 +02:00
Bill Burke 83306963e8 jta transaction abstraction 2016-08-08 12:32:36 -04:00
mposolda 65e2f127c9 KEYCLOAK-3400 OIDC request with missing response_type should respond with error 2016-08-08 16:11:50 +02:00
Marek Posolda 64c2077c0b Merge pull request #3115 from mposolda/master
KEYCLOAK-2169 KEYCLOAK-3286 Support for at_hash and c_hash
2016-08-08 12:36:33 +02:00
mposolda 9be6777685 KEYCLOAK-2169 KEYCLOAK-3286 Support for at_hash and c_hash 2016-08-08 10:57:44 +02:00
Bill Burke f14f303dfe Merge remote-tracking branch 'upstream/master' 2016-08-07 11:50:44 -04:00
Bill Burke 33d7d89ad9 provider hot deployment 2016-08-07 11:41:52 -04:00
Marek Posolda 65c49c39f4 Merge pull request #3114 from mposolda/master
KEYCLOAK-3321 OIDC requests without 'nonce' claim should be rejected …
2016-08-05 16:45:56 +02:00
Marek Posolda 6c0f685c39 Merge pull request #2948 from thomasdarimont/issue/KEYCLOAK-3142-Add-ResourceType-to-AdminEvents
KEYCLOAK-3142 - Capture ResourceType that triggers an AdminEvent
2016-08-05 15:07:56 +02:00
mposolda e0a59baaf2 KEYCLOAK-3321 OIDC requests without 'nonce' claim should be rejected unless using the code flow. Started responseType tests 2016-08-05 15:05:26 +02:00
Marek Posolda 6a797a61a9 Merge pull request #3113 from vmuzikar/KEYCLOAK-3367
KEYCLOAK-3367 Improve stability of Adapters Tests
2016-08-05 09:44:52 +02:00
Thomas Darimont e49afb2d83 KEYCLOAK-3142 - Revised according to codereview
Liquibase Moved schema evolution configuration from jpa-changelog-2.1.0
to jpa-changelog-2.2.0.
Corrected wrong ResourceType references in tests.
Adapted AdminEvents copy-routines to be aware of resourceType attribute.
Added ResourceType enum to exposed ENUMS of ServerInfoAdminResource.

Signed-off-by: Thomas Darimont <thomas.darimont@gmail.com>
2016-08-05 00:01:03 +02:00
Vaclav Muzikar 0d225f44de KEYCLOAK-3367 Improve stability of Adapters Tests 2016-08-04 14:43:49 +02:00
Thomas Darimont 586f6eeece KEYCLOAK-3142 - Capture ResourceType that triggers an AdminEvent
Introduced new ResourceType enum for AdminEvents which lists
the current supported ResourceTypes for which AdminEvents
can be fired.

Previously it was difficult for custom EventListeners to figure
out which ResourceType triggered an AdminEvent in order
to handle it appropriately, effectively forcing users to parse
the representation.
Having dedicated resource types as a marker on an AdminEvent helps
to ease custom EventListener code.

We now also allow filtering of admin events by ResourceType in the
admin-console.

Signed-off-by: Thomas Darimont <thomas.darimont@gmail.com>
2016-08-04 11:30:02 +02:00
Bill Burke f91907c8f9 Merge pull request #3107 from thomasdarimont/issue/KEYCLOAK-3392-honor-web-context-for-odic-endpoint-link
KEYCLOAK-3392 Use authUrl prefix for OIDC Configuration link
2016-08-03 21:34:00 -04:00
Bill Burke 9e0667bc11 Merge pull request #3080 from trajakovic/issue/editAccountHtmlTtile
Fixing typo in account resource(s) bundle
2016-08-03 21:31:44 -04:00
Bill Burke a3ffb32532 Merge pull request #3060 from fkiss/master-ldaps
KEYCLOAK-2281 added ldap tests over ssl
2016-08-03 21:31:12 -04:00
Bill Burke 1e7cf9fb3f Merge pull request #3088 from thomasdarimont/issue/KEYCLOAK-3380-allow-ignore-pattern-in-filter
KEYCLOAK-3380 Allow to configure paths to skip in KeycloakOIDCFilter
2016-08-03 21:30:20 -04:00
Bill Burke f75c0d3e61 Merge pull request #3111 from patriot1burke/master
user storage provider jpa example
2016-08-03 21:27:30 -04:00
Bill Burke 534ee2e50c Merge remote-tracking branch 'upstream/master' 2016-08-03 19:16:45 -04:00
Bill Burke 70722d0d3d user storage provider jpa example 2016-08-03 19:16:11 -04:00
Marek Posolda 0292acd5e2 Merge pull request #3110 from mposolda/master
Master: Oracle & EAP7 overlay
2016-08-03 14:24:50 +02:00
mposolda bf3541414c KEYCLOAK-3393 Fix Keycloak on EAP7 overlay 2016-08-03 13:01:44 +02:00
mposolda 9242e972c0 Fix Oracle DB 2016-08-03 13:01:30 +02:00
Thomas Darimont 57a96fa6aa KEYCLOAK-3392 Use authUrl prefix for OIDC Configuration link
We now use the {{authUrl}} prefix for the OIDC configuration link
in the admin-console to honor different web-context paths.

Previously when a different web-context than /auth was configured
the generated link pointed to the wrong location.

Signed-off-by: Thomas Darimont <thomas.darimont@gmail.com>
2016-08-02 15:52:22 +02:00
Bill Burke 7f08717dfb Merge pull request #3105 from patriot1burke/master
component model
2016-08-02 09:28:55 -04:00
Bill Burke 9365a40426 Merge pull request #3104 from zschwarz/exclude-test
KEYCLOAK-3389 Added general exclude for tests
2016-08-02 07:19:42 -04:00
Bill Burke ae58d64741 Merge pull request #3092 from vmuzikar/KEYCLOAK-3381
KEYCLOAK-3381 Fix and stabilize some Console UI tests
2016-08-02 07:19:28 -04:00
Bill Burke 4a8b4bcdec Merge pull request #3087 from zschwarz/password-policy
KEYCLOAK-3379 Password policy tests refactoring
2016-08-02 07:15:58 -04:00
Bill Burke e3aec098a2 Merge pull request #3064 from cainj13/oneSamlAttributeStatement
SamlProtocol should only drop attributes into a single attributeStatement
2016-08-02 07:14:08 -04:00
Bill Burke 3b9b673e5e turn off menu item 2016-08-02 06:57:48 -04:00
Bill Burke 17e75950fe more fixes 2016-08-02 06:56:22 -04:00
Bill Burke 1c75b03e59 props 2016-08-02 06:50:13 -04:00
Marek Posolda 27814dab65 Merge pull request #3102 from mposolda/master
Fixing mongo
2016-08-02 12:25:41 +02:00
mposolda b3a55df1e7 Fixing mongo 2016-08-02 10:58:44 +02:00
Marek Posolda 7ec3813a07 Merge pull request #3103 from mposolda/travis-fix
Travis workaround - another attempt
2016-08-02 09:21:04 +02:00
mposolda 62b96143a1 Travis workaround - another attempt 2016-08-02 09:20:33 +02:00
Marek Posolda ec6b81e42d Merge pull request #3101 from mposolda/master
New component model & fixes
2016-08-02 08:10:11 +02:00
Bill Burke 3a5d4a3723 fix 2016-08-02 05:50:23 +02:00
Bill Burke 1d695237b7 fix 2016-08-02 05:49:50 +02:00
Bill Burke 09693eb108 component model 2016-08-02 05:48:57 +02:00
mposolda 3b3368eead KEYCLOAK-3237 Add scope=openid to KeycloakInstalled 2016-08-02 05:45:55 +02:00
mposolda a5cbe113fd Migration fix 2016-08-02 05:45:20 +02:00
mposolda 9688880837 Fix testsuite with mongo 2016-08-02 05:44:40 +02:00
Marek Posolda 98be930027 Merge pull request #3100 from mposolda/master
Fix travis
2016-08-02 05:42:29 +02:00
mposolda 83b4495e69 Fix travis 2016-08-02 05:40:03 +02:00
Pedro Igor bd73b0aee6 Merge pull request #3097 from pedroigor/KEYCLOAK-3385
[KEYCLOAK-3385] - Improvements to evaluation tool UI and result
2016-08-01 20:43:33 -03:00
Pedro Igor ae1a7542d8 [KEYCLOAK-3385] - Improvements to evaluation tool UI and result 2016-08-01 18:01:24 -03:00
Bill Burke 7d1bdf6e81 Update .travis.yml 2016-08-01 16:39:06 -04:00
Bill Burke d64e7394a7 fix 2016-08-01 14:55:06 -04:00
Bill Burke 059011e82f Update .travis.yml 2016-08-01 14:28:34 -04:00
Marek Posolda eaf28f72c1 Merge pull request #3095 from mposolda/saml-ignore-master
Ignore KcSamlBrokerTest and KcSamlSignedBrokerTest again
2016-08-01 19:04:11 +02:00
mposolda aa177dd9f9 Ignore KcSamlBrokerTest and KcSamlSignedBrokerTest again 2016-08-01 19:03:07 +02:00
Bill Burke a8a77add39 fix 2016-08-01 12:07:02 -04:00
Bill Burke 5facec73e4 Merge remote-tracking branch 'upstream/master' 2016-08-01 11:19:09 -04:00
Bill Burke 91a267a0d8 component model 2016-08-01 11:18:58 -04:00
Vaclav Muzikar 0147fbe489 KEYCLOAK-3381 Fix and stabilize some Console UI tests 2016-08-01 15:10:18 +02:00
Marek Posolda a9ccabdce5 Merge pull request #3089 from mposolda/master
Fix DB2 and Oracle
2016-08-01 14:32:12 +02:00
zschwarz e04ad9d7b6 Added general exclude for tests 2016-08-01 13:17:24 +02:00
mposolda c5d40a76ff Fix DB2 and Oracle 2016-08-01 12:31:16 +02:00
Thomas Darimont 79c7203fe8 KEYCLOAK-3380 Allow to configure paths to skip in KeycloakOIDCFilter
We now allow configuration of path patterns which should not
be handled by the `KeycloakOIDCFilter` than can be specified via
the new init-parameter `keycloak.config.skipPattern` of
the `KeycloakOIDCFilter`.
Patterns are matched against the requestURI without the context-path.
A request for `/myapp/index.html` would be matched with `/index.html`
against the skip pattern.
This allows for for more flexible path handling when using the
`KeycloakOIDCFilter` in combination with existing applications.

Signed-off-by: Thomas Darimont <thomas.darimont@gmail.com>
2016-08-01 11:43:49 +02:00
Marek Posolda 0d99b797b6 Merge pull request #3068 from mstruk/KEYCLOAK-2981-m
KEYCLOAK-2981 Upload-certificate admin endpoint does not nullify private keys
2016-08-01 11:20:55 +02:00
Marek Posolda 59f228be2b Merge pull request #3076 from Smartling/KEYCLOAK-3097
KEYCLOAK-3097: Fix JBoss Logging scope
2016-08-01 09:30:02 +02:00
Marek Posolda 159b752fb0 Merge pull request #3085 from pedroigor/master
[KEYCLOAK-3376] - Show authorization data when evaluating authorization requests
2016-08-01 09:09:55 +02:00
Marek Posolda b0c7746eeb Merge pull request #3084 from mhajas/KEYCLOAK-3165
KEYCLOAK-3165 Migrate SAML Filter tests to integration arquillian testsuite
2016-08-01 09:07:19 +02:00
Marek Posolda bbeac6d741 Merge pull request #3086 from cargosoft/KEYCLOAK-3369
KEYCLOAK-3369 Fire RealmPostCreateEvent
2016-08-01 08:56:09 +02:00
Marek Posolda a8eb3ca65a Merge pull request #3065 from wyvie/samltest
[KEYCLOAK-3035] Fixed broker tests, should not randomly fail anymore
2016-08-01 08:39:22 +02:00
Dmitry Telegin fea277a7f5 KEYCLOAK-3369: Fire RealmPostCreateEvent 2016-08-01 01:00:50 +03:00
wyvie cd94778dec [KEYCLOAK-3035] Fixed broker tests, should not randomly fail anymore 2016-07-31 18:57:15 +02:00
Pedro Igor bd5b434894 [KEYCLOAK-3376] - Show authorization data when evaluating authorization requests 2016-07-29 22:09:17 -03:00
Pedro Igor 26f0f6509a Merge pull request #3082 from pedroigor/master
[KEYCLOAK-3372] - Code cleanup and more testing
2016-07-29 19:28:01 -03:00
Pedro Igor 7983ed064f [KEYCLOAK-3372] - More tests and code cleanup 2016-07-29 15:25:36 -03:00
Pedro Igor 607b305c2f [KEYCLOAK-3372] - Adding tests for servlet authorization 2016-07-29 12:42:53 -03:00
mhajas 824890323d Migrate SAML Filter tests to integration arquillian tests 2016-07-29 11:06:09 +02:00
zschwarz 5011960cac Password policy tests refactoring 2016-07-29 10:24:13 +02:00
Pedro Igor 3c8ed8e3d8 [KEYCLOAK-3372] - Code cleanup 2016-07-29 05:18:38 -03:00
Pedro Igor e6ce2e138d Merge pull request #3081 from pedroigor/master
[KEYCLOAK-3338] More testing and improvements when importing role poicies
2016-07-28 15:10:30 -03:00
Pedro Igor 8cfa50f134 [KEYCLOAK-3338] More testing and improvements when importing role policies 2016-07-28 12:31:46 -03:00
Tomislav Rajaković 2b3859f462 Fixing typo in account resource bundle: editAccountHtmlTtile -> editAccountHtmlTitle 2016-07-28 16:34:52 +02:00
Bill Burke 5d9fe09599 Merge pull request #3070 from mstruk/KEYCLOAK-2571
KEYCLOAK-2571 RESET_PASSWORD_ERROR and UPDATE_PASSWORD_ERROR events not fired
2016-07-28 07:23:32 -04:00
Bill Burke 2219cd363e Merge pull request #3079 from patriot1burke/master
KEYCLOAK-3268
2016-07-28 07:22:45 -04:00
Pedro Igor b08800fbd8 Merge pull request #3072 from pedroigor/KEYCLOAK-3338
[KEYCLOAK-3338] - Adding client roles to role policy and UX improvements
2016-07-27 18:14:25 -03:00
Pedro Igor 7e1b97888a [KEYCLOAK-3338] - Adding client roles to role policy and UX improvements 2016-07-27 15:15:14 -03:00
Scott Rossillo 322597b420 KEYCLOAK-3097: Fix JBoss Logging scope
JBoss Logging Framework required by Keycloak Core.
2016-07-27 12:35:21 -04:00
Bill Burke bd499e1c55 fix pom 2016-07-27 10:37:16 -04:00
Bill Burke 46b4bb0909 KEYCLOAK-3268 2016-07-27 09:28:48 -04:00
Marko Strukelj 59e0570cdf KEYCLOAK-2571 RESET_PASSWORD_ERROR and UPDATE_PASSWORD_ERROR events not fired 2016-07-26 21:32:57 +02:00
Bill Burke c925033944 Merge remote-tracking branch 'upstream/master' 2016-07-26 11:31:22 -04:00
Marko Strukelj 94f583e935 KEYCLOAK-2981 Upload-certificate admin endpoint does not nullify private keys 2016-07-25 11:13:21 +02:00
Bill Burke 69f051fb0a test user fed registration spi 2016-07-23 08:55:06 -04:00
Bill Burke 3973aed57d Merge pull request #2989 from thomasdarimont/issue/KEYCLOAK-3234-allow-restricting-mapper-for-userinfo
KEYCLOAK-3234 Allow restricting claim mapper for userinfo endpoint
2016-07-22 17:54:00 -04:00
Bill Burke 73d3db6d00 Merge pull request #3063 from patriot1burke/master
user fed spi query fixes and tests.
2016-07-22 17:51:20 -04:00
Josh Cain 535a0763fc put imports back, new IDE snuck a * in there. 2016-07-22 14:57:07 -05:00
Josh Cain 283581f920 SamlProtocol should only drop attributes into a single attributeStatement element 2016-07-22 14:49:48 -05:00
Marek Posolda 488dee71d2 Merge pull request #3062 from mposolda/master
KEYCLOAK-3319 More OIDC tests. Minor refactoring
2016-07-22 20:49:14 +02:00
Bill Burke b6811b96b9 fix test 2016-07-22 14:42:17 -04:00
Bill Burke db852f7e11 preRemove 2016-07-22 14:24:37 -04:00
mposolda 01830fd7f3 KEYCLOAK-3319 More OIDC tests. Minor refactoring 2016-07-22 18:16:58 +02:00
Bill Burke 00d439b6f0 log level oops 2016-07-22 12:09:22 -04:00
Bill Burke 06fca9c897 Merge remote-tracking branch 'upstream/master' 2016-07-22 11:42:14 -04:00
Bill Burke 72d134748c user fed spi querying tests 2016-07-22 11:42:07 -04:00
fkiss e2ad7608c8 KEYCLOAK-2281 added ldap tests over ssl 2016-07-22 16:29:58 +02:00
Marek Posolda a73dd537f3 Merge pull request #3059 from mposolda/master
KEYCLOAK-3354 request and request_uri not supported
2016-07-22 15:12:25 +02:00
mposolda 9169bcd88d KEYCLOAK-3354 request and request_uri not supported 2016-07-22 13:44:45 +02:00
Marek Posolda 94af2e1789 Merge pull request #3058 from mposolda/master
KEYCLOAK-3318 Adapter support for prompt and max_age. Refactoring to …
2016-07-21 21:58:29 +02:00
mposolda 56e011dce4 KEYCLOAK-3318 Adapter support for prompt and max_age. Refactoring to not hardcode OIDC specifics to CookieAuthenticator 2016-07-21 18:19:53 +02:00
Marek Posolda 079026a7be Merge pull request #3055 from mposolda/master
KEYCLOAK-3344 Can't remove realm with mongo model
2016-07-21 14:18:49 +02:00
Pedro Igor 7c6cf8f3b7 Merge pull request #3054 from pedroigor/KEYCLOAK-3313
[KEYCLOAK-3313] - UI improvements and messages
2016-07-21 08:32:02 -03:00
mposolda 981ff90c81 KEYCLOAK-3344 Can't remove realm with mongo model 2016-07-21 12:47:25 +02:00
Pedro Igor 484d5d6e08 [KEYCLOAK-3313] - UI improvements and messages 2016-07-20 22:11:24 -03:00
Bill Burke 0315bd0b87 Merge remote-tracking branch 'upstream/master' 2016-07-20 17:26:15 -04:00
Bill Burke 2a05f00d0c user fed tests 2016-07-20 17:26:00 -04:00
Marek Posolda 05a804b972 Merge pull request #3052 from mposolda/master
KEYCLOAK-3318 Support for prompt=login. More tests for prompt parameter
2016-07-20 22:51:30 +02:00
mposolda f4ddfe4a52 KEYCLOAK-3318 Support for prompt=login. More tests for prompt parameter 2016-07-20 21:27:38 +02:00
Bill Burke 76c4fbb241 Merge pull request #3051 from patriot1burke/master
user fed spi fixes and simple test
2016-07-20 12:51:42 -04:00
Bill Burke 3b0fd71155 Merge pull request #3048 from pedroigor/KEYCLOAK-3320
[KEYCLOAK-3320] - Enable authorization services to WF8 adapter
2016-07-20 11:29:23 -04:00
Bill Burke 6f92bac782 Merge pull request #3000 from tonswieb/master
KEYCLOAK-3265 Support writing a NameIDType AttributeValue
2016-07-20 11:23:18 -04:00
Bill Burke 8b535c5da6 log level 2016-07-20 11:16:20 -04:00
Bill Burke e719722e32 Merge remote-tracking branch 'upstream/master' 2016-07-20 11:01:01 -04:00
Bill Burke c709598fdd user fed spi simple test 2016-07-20 10:59:45 -04:00
Stian Thorgersen 3ef0527a91 Merge pull request #3046 from pdrozd/KEYCLOAK-3336
KEYCLOAK-3336 Arquillian testuite: Added possibility to install serve…
2016-07-20 14:58:29 +02:00
Marek Posolda eb12a307f7 Merge pull request #3050 from mposolda/master
KEYCLOAK-1733 added verifySSL checks for 'basic' and 'query' authenti…
2016-07-20 14:01:35 +02:00
Pedro Igor f36a68308d [KEYCLOAK-3320] - Enable authorization services to WF8 adapter 2016-07-20 08:16:37 -03:00
mposolda 7571dc07f9 KEYCLOAK-1733 added verifySSL checks for 'basic' and 'query' authentication 2016-07-20 11:04:31 +02:00
Marek Posolda e03bf6eef6 Merge pull request #2990 from trex667/feat/keycloak-1733
[KEYCLOAK-1733]: introduce token as query paramter
2016-07-20 10:46:11 +02:00
Pavel Drozd 0e470d75e9 KEYCLOAK-3336 Arquillian testuite: Added possibility to install server patch 2016-07-19 14:22:49 +02:00
Stian Thorgersen 187f4a49ad Merge pull request #3044 from thomasdarimont/issue/KEYCLOAK-3301-support-undertow-in-spring-boot-adapter
KEYCLOAK-3301 Add support for Undertow in Spring Boot Adapter
2016-07-19 09:29:52 +02:00
Stian Thorgersen 0a5e061ca6 Merge pull request #3045 from mhajas/KEYCLOAK-3326
KEYCLOAK-3326 Fix invalidRequesterMessage in tests
2016-07-19 09:29:15 +02:00
Stian Thorgersen 1b517a461e Merge pull request #3041 from stianst/KEYCLOAK-3302
KEYCLOAK-3302 Allow logout with expired refresh token
2016-07-19 08:03:52 +02:00
mhajas a913b8a158 Fix invalidRequesterMessage in tests 2016-07-18 14:21:28 +02:00
Thomas Darimont f574173ed3 KEYCLOAK-3301 Add support for Undertow in Spring Boot Adapter
We now support using Undertow in combination with the Spring Boot Adapter.
2016-07-18 10:07:07 +02:00
Marek Posolda a6bdf81e6d Merge pull request #3040 from mposolda/master
KEYCLOAK-3220 Added test for missing response_type
2016-07-15 22:19:52 +02:00
Stian Thorgersen a42e4af78d Merge pull request #3018 from thomasdarimont/issue/KEYCLOAK-3300-support-jetty-in-spring-boot-adapter
KEYCLOAK-3300 Add support for jetty in spring-boot-adapter
2016-07-15 13:29:16 +02:00
Stian Thorgersen b1ae0a9000 Merge pull request #3003 from iconoeugen/fix/update_server_spi_module_deps_for_script_based
KEYCLOAK-3285: Update server-spi module to include deps required by script based flow executor
2016-07-15 13:27:28 +02:00
Stian Thorgersen 07d7141d98 Merge pull request #3042 from stianst/master
Ignore unstable tests
2016-07-15 12:59:33 +02:00
Stian Thorgersen 0632bc8939 Ignore unstable tests 2016-07-15 12:59:15 +02:00
Stian Thorgersen e708c53730 KEYCLOAK-3302 Allow logout with expired refresh token 2016-07-15 12:56:31 +02:00
mposolda 243105f952 KEYCLOAK-3175 Document run of OIDC Conformance test 2016-07-15 12:51:35 +02:00
Stian Thorgersen 1ce17c459d Merge pull request #3039 from stianst/KEYCLOAK-3192
KEYCLOAK-3192 Ignore disabled required action
2016-07-15 10:38:49 +02:00
Stian Thorgersen daa4d23ac0 Merge pull request #3038 from stianst/KEYCLOAK-3170
KEYCLOAK-3170 Users with only view-users and impersonate can't impers…
2016-07-15 10:38:32 +02:00
Stian Thorgersen 30d651bcee Merge pull request #3036 from stianst/master
Added umlats test to registration test
2016-07-15 10:38:23 +02:00
mposolda fda0a79e27 KEYCLOAK-3237 Add scopes_supported to OIDC WellKnown endpoint 2016-07-15 09:47:09 +02:00
mposolda 021c2ec701 KEYCLOAK-3220 Added test for missing response_type 2016-07-15 09:15:09 +02:00
Stian Thorgersen fbf00ba1cd Added umlats test to registration test 2016-07-15 09:05:41 +02:00
Marek Posolda a2ead8743f Merge pull request #3035 from mposolda/master
OIDC fixes
2016-07-15 09:03:31 +02:00
Stian Thorgersen 5a0b86f814 Merge pull request #3037 from stianst/KEYCLOAK-3266
KEYCLOAK-3266 password policy NotUsername breaks new user registration
2016-07-15 09:03:02 +02:00
Stian Thorgersen 970c89dd6a KEYCLOAK-3192 Ignore disabled required action 2016-07-15 09:01:44 +02:00
Stian Thorgersen f9bfb5d3e5 KEYCLOAK-3170 Users with only view-users and impersonate can't impersonate in the UI 2016-07-15 07:52:21 +02:00
Stian Thorgersen f384c2340e KEYCLOAK-3266 password policy NotUsername breaks new user registration 2016-07-15 07:34:13 +02:00
Stian Thorgersen 2f14fb7fb7 Merge pull request #3033 from rpieciorak/patch-1
Remove link to missing ReleaseProcess.md
2016-07-15 06:04:31 +02:00
Stian Thorgersen fe367d207a Merge pull request #3022 from vmuzikar/KEYCLOAK-3212
KEYCLOAK-3212 Improve Console UI tests stability in FF, Chrome and IE
2016-07-15 06:03:32 +02:00
mposolda 13a21e5fda KEYCLOAK-3220 Improve error handling on adapters 2016-07-14 23:56:46 +02:00
mposolda dcc4ea3aea KEYCLOAK-3237 Change OIDC adapters to use scope=openid as required per specs 2016-07-14 23:56:46 +02:00
Pedro Igor 7bc34c0ba4 Merge pull request #3034 from pedroigor/KEYCLOAK-3137
[KEYCLOAK-3137] - Review i18n for AuthZ Services
2016-07-14 15:22:41 -03:00
Pedro Igor aacf2e9390 [KEYCLOAK-3137] - Review i18n for AuthZ Services 2016-07-14 13:54:37 -03:00
Rafał Pięciorak 966a580895 Remove link to missing ReleaseProcess.md 2016-07-14 17:06:03 +02:00
Marek Posolda bffbc9e198 Merge pull request #3032 from mposolda/KEYCLOAK-3223
KEYCLOAK-3223 Basic support for acr claim
2016-07-14 16:26:36 +02:00
mposolda ee3ac3fdaf KEYCLOAK-3223 Basic support for acr claim 2016-07-14 12:36:12 +02:00
Stian Thorgersen 9ddec7d1eb Merge pull request #3019 from ssilvert/KEYCLOAK-3273-ear
KEYCLOAK-3273: Prefer module name for secure-deployment in Keycloak
2016-07-14 12:06:44 +02:00
Stian Thorgersen 4f1d83b9dc Merge pull request #3030 from stianst/KEYCLOAK-2824-2
KEYCLOAK-2824 Password Policy SPI
2016-07-14 10:12:25 +02:00
Marek Posolda eeabc0092b Merge pull request #3031 from mposolda/master
KEYCLOAK-3220 redirect to client with error if possible
2016-07-14 08:30:18 +02:00
Stian Thorgersen ea44b5888b KEYCLOAK-2824 Password Policy SPI 2016-07-14 07:20:30 +02:00
mposolda abde62f369 KEYCLOAK-3220 redirect to client with error if possible 2016-07-13 20:57:43 +02:00
Marek Posolda 16184d1e9d Merge pull request #3029 from mposolda/master
KEYCLOAK-3281 OIDC 'state' parameter is url-encoded twice when respon…
2016-07-13 19:16:35 +02:00
mposolda 38f89b93ff KEYCLOAK-3281 OIDC 'state' parameter is url-encoded twice when responseMode=form_post 2016-07-13 18:07:57 +02:00
Marek Posolda 912bc8464e Merge pull request #3028 from mposolda/KEYCLOAK-3219
KEYCLOAK-3219 Added claims info to OIDCWellKnownProvider. More tests
2016-07-13 12:28:29 +02:00
mposolda d5199501c7 KEYCLOAK-3219 Added claims info to OIDCWellKnownProvider. More tests 2016-07-13 10:17:45 +02:00
Stian Thorgersen f9235cb07d Merge pull request #3020 from realityforge/FilterSessionStore_getDateHeader
KEYCLOAK-3308: Return -1 from getDateHeader() when request is restored.
2016-07-13 08:38:53 +02:00
Stian Thorgersen d7649c2547 Merge pull request #3024 from stianst/KEYCLOAK-3267
KEYCLOAK-3267 Fix identity broker login with brute force enabled
2016-07-13 07:37:52 +02:00
Thomas Darimont be5468a7cf KEYCLOAK-3300 Add support for jetty in spring-boot-adapter
This adds support for using Jetty together with the Keycloak
spring-boot-adapter. Sadly the KeycloakSpringBootProperties.SecurityCollection
definition is mostly inspired by Tomcats SecurityConstraint/SecurityCollection
which doesn't provide a good fit for jettys structures.
In cases where jetty only allows one setting, we use the first value.

We only initialize KeycloakJettyServerCustomizer if jetty is used, same
applies for tomcat.
Revised configuration and extracted serverCustomizer code into
dedicated classes.
Prepared infrastructure for Undertow support.
2016-07-12 23:19:30 +02:00
Pedro Igor eba56e4784 Merge pull request #3027 from pedroigor/KEYCLOAK-3305
[KEYCLOAK-3305] - Cache is not properly handling failures when importing configuration
2016-07-12 17:57:47 -03:00
Marek Posolda 26efb2cbee Merge pull request #3026 from mposolda/master
KEYCLOAK-3306 Added reproducer test for OutdatedTopologyException
2016-07-12 21:47:01 +02:00
Pedro Igor 02896768f5 [KEYCLOAK-3305] - Cache is not properly handling failures when importing configuration 2016-07-12 13:57:49 -03:00
Stan Silvert 1d4e76117c KEYCLOAK-3273: Prefer module name for secure-deployment name. 2016-07-12 12:42:24 -04:00
mposolda a912ba3148 KEYCLOAK-3306 Added reproducer test for OutdatedTopologyException 2016-07-12 18:12:20 +02:00
Stian Thorgersen 5b0980172d KEYCLOAK-3267 Fix identity broker login with brute force enabled 2016-07-12 15:21:00 +02:00
Stian Thorgersen ff8dce77f3 Merge pull request #3021 from stianst/master
KEYCLOAK-3143 Wrong field name in login theme message properties
2016-07-12 13:57:40 +02:00
Vaclav Muzikar 7dbdb023a0 KEYCLOAK-3212 Improve Console UI tests stability in FF, Chrome and IE 2016-07-12 11:39:27 +02:00
Stian Thorgersen 2fa200889a KEYCLOAK-3143 Wrong field name in login theme message properties 2016-07-12 10:49:13 +02:00
Stian Thorgersen f97d0846ed Merge pull request #3010 from wadahiro/KEYCLOAK-3278
KEYCLOAK-3278 Add support for any encoding property file in theme
2016-07-12 10:34:34 +02:00
Stian Thorgersen 19e5ddeba5 Merge pull request #3015 from martin-kanis/master
KEYCLOAK-3096 Remove leading/trailing spaces from username/email
2016-07-12 10:03:55 +02:00
Stian Thorgersen df090fa5e1 Merge pull request #3012 from wadahiro/KEYCLOAK-3289
KEYCLOAK-3289 Fixed 'User Enabled' toggled incorrectly
2016-07-12 10:01:23 +02:00
Peter Donald c283f9803c Return -1 from getDateHeader() when request is restored.
Other certain container will attempt to access date (such as when
checking If-Modified-Since header)  and fail when accessing restored
request. The javax.servlet.http.HttpServletRequest#getDateHeader()
javadocs indicate that -1 should be returned when date is not available
2016-07-12 16:28:45 +10:00
Stian Thorgersen 3a370e2726 Merge pull request #3006 from vmuzikar/KEYCLOAK-3280-master
KEYCLOAK-3280 Alerts in Admin Console are sometimes shown only for a split second
2016-07-12 07:30:37 +02:00
Stan Silvert 73cbf857c1 KEYCLOAK-3273: Prefer module name for secure-deployment in Keycloak
adapter subsystem
2016-07-11 20:58:31 -04:00
Marek Posolda 64ad222a28 Merge pull request #3017 from mposolda/rhit
KEYCLOAK-3296 same user logging twice at the same time causes lock is…
2016-07-11 21:42:31 +02:00
mposolda 6e94931023 KEYCLOAK-3296 same user logging twice at the same time causes lock issue - HQL deletion patch 2016-07-11 19:40:24 +02:00
Marek Posolda ba3b6fd564 Merge pull request #3016 from mposolda/master
KEYCLOAK-3295 Kerberos authenticator changed during userFederationPro…
2016-07-11 17:15:48 +02:00
mposolda 039bb103c2 KEYCLOAK-3295 Kerberos authenticator changed during userFederationProvider update just if it was DISABLED 2016-07-11 15:52:49 +02:00
Stian Thorgersen e946c1c512 Merge pull request #3011 from stianst/KEYCLOAK-3202
Add versions for Jetty 9.3 adapter dists
2016-07-11 08:02:35 +02:00
Martin Kanis c67d834d39 KEYCLOAK-3096 Remove leading/trailing spaces from login 2016-07-09 18:35:51 +02:00
Marek Posolda 8bdfd57e9b Merge pull request #3014 from mposolda/KEYCLOAK-3222
OIDC client auth fixes & tests
2016-07-08 18:16:43 +02:00
mposolda 629390dd4a KEYCLOAK-2986 Require either expiration or issuedAt for client authentication with signed JWT 2016-07-08 16:16:38 +02:00
mposolda 3bfd999590 KEYCLOAK-3222 extend WellKnown to return supported types of client authentications. More tests 2016-07-08 15:39:13 +02:00
Pedro Igor 80a67149af Merge pull request #3002 from pedroigor/KEYCLOAK-3249
[KEYCLOAK-3249] - AuthorizationContext.hasScopePermission() gives NPE
2016-07-08 09:16:51 -03:00
Marek Posolda 7962f68991 Merge pull request #3013 from mposolda/KEYCLOAK-3221
OIDC fixes
2016-07-08 14:08:06 +02:00
mposolda c10a005997 KEYCLOAK-3290 UserInfoEndpoint error responses don't have correct statuses 2016-07-08 12:15:07 +02:00
mposolda 4dd28c0adf KEYCLOAK-3221 Tokens should be invalidated if an attempt to reuse code is made 2016-07-08 11:04:08 +02:00
Stian Thorgersen 4bdd67da79 Add versions for Jetty 9.3 adapter dists 2016-07-08 08:21:03 +02:00
Hiroyuki Wada 8e24c73ac8 KEYCLOAK-3289 Fixed 'User Enabled' toggled incorrectly when 'Federation Link' label is clicked 2016-07-08 15:09:58 +09:00
Bill Burke bd2887aa77 Merge pull request #2982 from ahus1/jetty_9_3
KEYCLOAK-2684: jetty 9.3 implementation (oidc/saml)
2016-07-07 14:59:29 -04:00
Bill Burke bdc57d57c1 Merge pull request #3008 from patriot1burke/master
new User Fed SPI initial iteration
2016-07-07 14:56:38 -04:00
Marek Posolda 38cc183be5 Merge pull request #3009 from mposolda/master
KEYCLOAK-3218 Support for max_age OIDC authRequest parameter and supp…
2016-07-07 20:01:50 +02:00
Hiroyuki Wada 930b0d9ad7 KEYCLOAK-3278 Add support for any encoding property file in theme 2016-07-08 02:58:48 +09:00
Bill Burke bf2ca4008e log level info 2016-07-07 12:06:57 -04:00
mposolda a7c9e71490 KEYCLOAK-3218 Support for max_age OIDC authRequest parameter and support for auth_time in IDToken 2016-07-07 17:04:32 +02:00
Bill Burke 0040d3fc3b Merge remote-tracking branch 'upstream/master' 2016-07-07 10:35:45 -04:00
Bill Burke 7e5a5f79cf fixes for new user fed spi 2016-07-07 10:35:35 -04:00
Marek Posolda 7a161cc8bb Merge pull request #3005 from mposolda/KEYCLOAK-3217
KEYCLOAK-3217 UserInfo endpoint wasn't accessible by POST request sec…
2016-07-07 13:49:43 +02:00
Marek Posolda c5e8a010dc Merge pull request #3004 from mposolda/KEYCLOAK-3147
KEYCLOAK-3147 Don't allow authRequest without redirect_uri parameter
2016-07-07 13:49:34 +02:00
Vaclav Muzikar 5638e9e1c5 KEYCLOAK-3280 Alerts in Admin Console are sometimes shown only for a split second 2016-07-07 13:44:28 +02:00
mposolda 56e09bf189 KEYCLOAK-3147 Don't allow authRequest without redirect_uri parameter 2016-07-07 12:46:36 +02:00
mposolda 7aafbcd5d9 KEYCLOAK-3217 UserInfo endpoint wasn't accessible by POST request secured with Bearer header 2016-07-07 12:28:25 +02:00
Stian Thorgersen 78fbf45b80 Merge pull request #2991 from ssilvert/RHSSO-296
KEYCLOAK-3244: Required Action "Configure Totp" should be "Configure OTP"
2016-07-07 11:43:50 +02:00
Horatiu Eugen Vlad bd124d5f9b Update server-spi module deps to include dependencies required by script based flow executor. 2016-07-06 18:00:46 +02:00
Pedro Igor 5ef65e837c [KEYCLOAK-3249] - AuthorizationContext.hasScopePermission() gives NPE 2016-07-06 09:39:56 -03:00
Stian Thorgersen 2591dd862b Merge pull request #2976 from vramik/KEYCLOAK-3151
KEYCLOAK-3151 removed adapter libs mode from testsuite
2016-07-06 14:21:07 +02:00
awpwb 159b371973 [KEYCLOAK-1733]: introduce token as query paramter
add functional tests for access token as query paramter
2016-07-06 14:12:23 +02:00
Stian Thorgersen 948f37b01a Merge pull request #2997 from pedroigor/KEYCLOAK-3246
[KEYCLOAK-3246] - Authz client missing from tomcat 8 OpenID adapter
2016-07-06 09:24:19 +02:00
Stian Thorgersen 1f41b3195f Merge pull request #3001 from stianst/KEYCLOAK-3202
KEYCLOAK-3202 Creating users causes memory leak
2016-07-06 09:22:40 +02:00
Stan Silvert 4628946a55 Automatically migrate required action name. 2016-07-05 15:07:54 -04:00
Stan Silvert a231c1b31b RHSSO-296: Required Action "Configure Totp" should be "Configure OTP" 2016-07-05 15:07:52 -04:00
Stian Thorgersen 3fc215d041 KEYCLOAK-3202 Creating users causes memory leak 2016-07-05 19:54:55 +02:00
Ton Swieb fed7339558 KEYCLOAK-3265 Support writing a NameIDType AttributeValue 2016-07-05 14:54:38 +02:00
Stian Thorgersen 7e0238d1c7 Merge pull request #2998 from stianst/KEYCLOAK-3262
KEYCLOAK-3262 Add support to save multiple state in keycloak.js
2016-07-05 09:48:28 +02:00
Stian Thorgersen 2dd0d7189e Merge pull request #2999 from stianst/KEYCLOAK-3189
KEYCLOAK-3189 KEYCLOAK-3190 Add kid and typ to JWT header
2016-07-05 09:33:21 +02:00
Stian Thorgersen f52504ac41 KEYCLOAK-3262 Add support to save multiple state in keycloak.js 2016-07-05 08:45:12 +02:00
Stian Thorgersen 7cfee80e58 KEYCLOAK-3189 KEYCLOAK-3190 Add kid and typ to JWT header 2016-07-05 08:26:26 +02:00
Stian Thorgersen 435cdb6180 Merge pull request #2994 from wadahiro/KEYCLOAK-3259
KEYCLOAK-3259 Specify UTF-8 encoding for freemarker template files
2016-07-04 19:25:03 +02:00
Stian Thorgersen fe856d3fa7 Merge pull request #2992 from ssilvert/RHSSO-274
KEYCLOAK-3243: "Undefined" as auth flow execution
2016-07-04 19:24:30 +02:00
Stian Thorgersen 98923d0ea4 Merge pull request #2971 from mhajas/fixRelative
KEYCLOAK-3195 Fix example adapter tests on relative scenario
2016-07-04 19:22:06 +02:00
Stian Thorgersen dd6434a487 Merge pull request #2995 from stianst/KEYCLOAK-2617
KEYCLOAK-2617 Ignore postmessages if not initiated by keycloak.js
2016-07-04 19:19:34 +02:00
Stian Thorgersen 842b811a41 Merge pull request #2987 from ssilvert/RHSSO-319
KEYCLOAK-3242: Some hints in admin console contain backslash in front of
2016-07-04 19:17:29 +02:00
Stian Thorgersen 07ab632351 Merge pull request #2986 from ssilvert/RHSSO-253
KEYCLOAK-3240: No tooltip shown for Client Mapper Type
2016-07-04 19:16:57 +02:00
Julien Giovaresco 9bcfda64fa Fix typo in email and login french translations 2016-07-04 19:14:36 +02:00
Stian Thorgersen 453859d14f Merge pull request #2993 from stianst/KEYCLOAK-2660
KEYCLOAK-2660 Test updating user without including username with brut…
2016-07-04 19:11:56 +02:00
Stian Thorgersen 122cb1f490 Merge pull request #2925 from chameleon82/issue/KEYCLOAK-3102-russian-localization
KEYCLOAK-3102 Add russian localization
2016-07-04 19:03:04 +02:00
Pedro Igor 6bb59b7f63 [KEYCLOAK-3246] - Authz client missing from tomcat 8 OpenID adapter 2016-07-04 13:27:14 -03:00
Pedro Igor 1ec88cf5b0 Merge pull request #2996 from pedroigor/KEYCLOAK-3248
[KEYCLOAK-3248] - Permissions don't unlink from resources and scopes
2016-07-04 13:16:44 -03:00
Pedro Igor 74139ec787 [KEYCLOAK-3248] - Permissions don't unlink from resources and scopes 2016-07-04 09:33:46 -03:00
Stian Thorgersen f3a780cc2d KEYCLOAK-2617 Ignore postmessages if not initiated by keycloak.js 2016-07-04 13:07:17 +02:00
Hiroyuki Wada 00cb0a798a KEYCLOAK-3259 Specify UTF-8 encoding for freemarker template files 2016-07-04 19:46:00 +09:00
Stian Thorgersen c9bbfc3b0b KEYCLOAK-2660 Test updating user without including username with brute force enabled 2016-07-04 12:37:26 +02:00
Alex cb085cc598 KEYCLOAK-3102 update Russian grammar in admin console 2016-07-02 10:04:57 +06:00
Alex a8b39edd73 KEYCLOAK-3102 Fix russian grammar in admin messages 2016-07-01 23:17:36 +06:00
Stan Silvert 8b8ebfc7e1 Fix failing test. 2016-07-01 12:24:13 -04:00
Stan Silvert d90a708ceb RHSSO-274: "Undefined" as auth flow execution 2016-07-01 10:25:14 -04:00
Stian Thorgersen 450b57c76a Merge pull request #2984 from stianst/master
KEYCLOAK-3172 Add view authorization role to existing realms
2016-07-01 12:41:09 +02:00
Stian Thorgersen fa312fb3db Merge pull request #2979 from cainj13/localeNpeFix
make locale retrieval null-safe
2016-07-01 12:33:36 +02:00
Alexander Schwartz 9384aa1398 KEYCLOAK-2684: jetty 9.3 implementation 2016-07-01 12:26:59 +02:00
Thomas Darimont ce7e7ef1d7 KEYCLOAK-3234 Allow restricting claim mapper for userinfo endpoint
Client mappers can now be configured to be limited to the
userinfo endpoint. This allows to keep access-tokens lean
while providing extended user information on demand via the
userinfo endpoint.
2016-07-01 11:35:19 +02:00
Bill Burke a19469aba5 Merge remote-tracking branch 'upstream/master' 2016-06-30 17:18:17 -04:00
Bill Burke b224917fc5 bump version 2016-06-30 17:17:53 -04:00
Bill Burke 3f1eecc4be Merge remote-tracking branch 'upstream/master' 2016-06-30 16:47:55 -04:00
Bill Burke 3ba3be877e fixes 2016-06-30 16:47:49 -04:00
Stan Silvert daefbcf994 RHSSO-319: Some hints in admin console contain backslash in front of
collon
2016-06-30 13:32:21 -04:00
Stan Silvert 5d9669e5a6 RHSSO-253: No tooltip shown for Client Mapper Type 2016-06-30 13:10:47 -04:00
Pedro Igor 1e7745b5c3 Merge pull request #2978 from pedroigor/authz-tests
[Authorization] - Integration tests
2016-06-30 13:32:28 -03:00
Pedro Igor 46d02f15fe [KEYCLOAK-2999] - Authorization arquillian tests 2016-06-30 10:26:05 -03:00
Pedro Igor 01f3dddd91 Adding a column to list policies associated with a permission. 2016-06-30 10:26:05 -03:00
Pedro Igor 2db41ef052 [KEYCLOAK-2999] - Changes to authz examples for integration test 2016-06-30 10:26:05 -03:00
Pedro Igor afa9471c7c [KEYCLOAK-3128] - Admin Client Authorization Endpoints 2016-06-30 10:26:05 -03:00
Stian Thorgersen 08f28de903 Removed release process doc as it's now in a private document 2016-06-30 09:46:46 +02:00
Stian Thorgersen 1fe8da67dc KEYCLOAK-3172 Add view authorization role to existing realms 2016-06-30 08:52:18 +02:00
Stian Thorgersen 591a794247 Merge pull request #2983 from stianst/master
Update messages_fr.properties
2016-06-30 07:34:30 +02:00
Alexandre a9e8f315a4 Update messages_fr.properties
Change the word "adminitrateur" to "administrateur"

The "s" was missing in "admini-S-trateur"

That all !
2016-06-30 07:34:17 +02:00
Stian Thorgersen c738f9fbd3 Merge pull request #2981 from pedroigor/KEYCLOAK-3172
[KEYCLOAK-3172] - Migrating older versions with authorization services.
2016-06-30 07:31:39 +02:00
Stian Thorgersen 588f6ba253 Merge pull request #2965 from mhajas/fixSSLTrustore
KEYCLOAK-3174 Fix duplicate plugin for adding truststore
2016-06-30 07:29:09 +02:00
Bill Burke a9f6948d74 Merge remote-tracking branch 'upstream/master' 2016-06-29 15:37:32 -04:00
Bill Burke f51098c50b user fed refactor 2016-06-29 15:37:22 -04:00
Pedro Igor 8b0bf503c3 [KEYCLOAK-3172] - Migrating older versions with authorization services. 2016-06-29 12:07:49 -03:00
Josh Cain ec402f759b make locale retrieval null-safe 2016-06-28 13:25:48 -05:00
Marek Posolda bc82f18acb Merge pull request #2974 from mposolda/master
KEYCLOAK-3194 Fix fuse adapter. Remove karaf related steps from README
2016-06-27 22:17:31 +02:00
Stian Thorgersen a001d53d2a Merge pull request #2972 from iperdomo/master
[KEYCLOAK-3185] Fix navigation resource > permission
2016-06-27 16:20:25 +02:00
mposolda 1a4d03e283 KEYCLOAK-3194 Fix fuse adapter. Remove karaf related steps from README 2016-06-27 15:43:23 +02:00
Iván Perdomo 8a8bf47043 [KEYCLOAK-3185] Fix navigation resource > permission 2016-06-27 14:21:19 +02:00
mhajas 836ab2820a Fix adapter tests on relative scenario 2016-06-27 14:18:32 +02:00
Alex 01d0821142 KEYCLOAK-3102 Fix grammar 2016-06-25 13:30:22 +06:00
Vlasta Ramik 47fab2d034 removed adapter libs mode from testsuite 2016-06-24 13:32:03 +02:00
Stian Thorgersen fc295ac2ac Merge pull request #2964 from stianst/master
Remove testsuite/stress
2016-06-24 13:04:52 +02:00
mhajas 69919902b4 Fix duplicate plugin for adding truststore 2016-06-24 12:50:39 +02:00
Stian Thorgersen a6af72cbbc Removed perf package from testsuite/integration 2016-06-24 10:59:05 +02:00
Stian Thorgersen 4aa102fcab Remove testsuite/stress 2016-06-24 10:59:05 +02:00
Stian Thorgersen 0dc8bb7c3b Merge pull request #2963 from ssilvert/migrate-importexport
KEYCLOAK-3031 Migrate exportimport package to arquillian testsuite
2016-06-24 10:44:46 +02:00
Stan Silvert 5e450d5cd4 Minor cleanup. 2016-06-23 11:09:57 -04:00
Stan Silvert 38722e8273 KEYCLOAK-3031 Migrate exportimport package to arquillian testsuite 2016-06-23 11:09:55 -04:00
Alex 61be5cc90e KEYCLOAK-3102 Fix Russian translation more cleaner 2016-06-21 01:16:05 +06:00
Некрасов Александр Сергеевич 1422d2962e KEYCLOAK-3102 Add russian localization 2016-06-10 15:54:19 +06:00
1291 changed files with 43366 additions and 7909 deletions

No files matched your search

+8 -1
View File
@@ -1,5 +1,12 @@
language: java
cache:
directories:
- $HOME/.m2
before_cache:
- rm -rf $HOME/.m2/repository/org/keycloak
env:
global:
- MAVEN_SKIP_RC=true
@@ -12,7 +19,7 @@ before_script:
- export MAVEN_SKIP_RC=true
install:
- mvn install -Pdistribution -DskipTests=true -B -V -q
- travis_wait 30 mvn install -Pdistribution -DskipTests=true -B -V -q
script:
- mvn test -B
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -34,6 +34,7 @@ import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.IDToken;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.common.util.UriUtils;
import org.keycloak.util.TokenUtil;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicLong;
@@ -159,6 +160,12 @@ public class OAuthRequestAuthenticator {
String scope = getQueryParamValue(OAuth2Constants.SCOPE);
url = UriUtils.stripQueryParam(url, OAuth2Constants.SCOPE);
String prompt = getQueryParamValue(OAuth2Constants.PROMPT);
url = UriUtils.stripQueryParam(url, OAuth2Constants.PROMPT);
String maxAge = getQueryParamValue(OAuth2Constants.MAX_AGE);
url = UriUtils.stripQueryParam(url, OAuth2Constants.MAX_AGE);
KeycloakUriBuilder redirectUriBuilder = deployment.getAuthUrl().clone()
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
@@ -171,9 +178,15 @@ public class OAuthRequestAuthenticator {
if (idpHint != null && idpHint.length() > 0) {
redirectUriBuilder.queryParam(AdapterConstants.KC_IDP_HINT,idpHint);
}
if (scope != null && scope.length() > 0) {
redirectUriBuilder.queryParam(OAuth2Constants.SCOPE, scope);
if (prompt != null && prompt.length() > 0) {
redirectUriBuilder.queryParam(OAuth2Constants.PROMPT, prompt);
}
if (maxAge != null && maxAge.length() > 0) {
redirectUriBuilder.queryParam(OAuth2Constants.MAX_AGE, maxAge);
}
scope = TokenUtil.attachOIDCScope(scope);
redirectUriBuilder.queryParam(OAuth2Constants.SCOPE, scope);
return redirectUriBuilder.build().toString();
}
@@ -35,7 +35,8 @@ public class OIDCAuthenticationError implements AuthenticationError {
CODE_TO_TOKEN_FAILURE,
INVALID_TOKEN,
STALE_TOKEN,
NO_AUTHORIZATION_HEADER
NO_AUTHORIZATION_HEADER,
NO_QUERY_PARAMETER_ACCESS_TOKEN
}
private Reason reason;
@@ -0,0 +1,54 @@
/*
* 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;
import org.jboss.logging.Logger;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
/**
* @author <a href="mailto:froehlich.ch@gmail.com">Christian Froehlich</a>
* @version $Revision: 1 $
*/
public class QueryParamterTokenRequestAuthenticator extends BearerTokenRequestAuthenticator {
public static final String ACCESS_TOKEN = "access_token";
protected Logger log = Logger.getLogger(QueryParamterTokenRequestAuthenticator.class);
public QueryParamterTokenRequestAuthenticator(KeycloakDeployment deployment) {
super(deployment);
}
public AuthOutcome authenticate(HttpFacade exchange) {
tokenString = null;
tokenString = getAccessTokenFromQueryParamter(exchange);
if (tokenString == null || tokenString.trim().isEmpty()) {
challenge = challengeResponse(exchange, OIDCAuthenticationError.Reason.NO_QUERY_PARAMETER_ACCESS_TOKEN, null, null);
return AuthOutcome.NOT_ATTEMPTED;
}
return (authenticateToken(exchange, tokenString));
}
String getAccessTokenFromQueryParamter(HttpFacade exchange) {
try {
if (exchange != null && exchange.getRequest() != null) {
return exchange.getRequest().getQueryParamValue(ACCESS_TOKEN);
}
} catch (Exception ignore) {
}
return null;
}
}
@@ -61,7 +61,7 @@ public abstract class RequestAuthenticator {
if (log.isTraceEnabled()) {
log.trace("try bearer");
}
AuthOutcome outcome = bearer.authenticate(facade);
if (outcome == AuthOutcome.FAILED) {
challenge = bearer.getChallenge();
@@ -74,18 +74,36 @@ public abstract class RequestAuthenticator {
return AuthOutcome.AUTHENTICATED;
}
QueryParamterTokenRequestAuthenticator queryParamAuth = createQueryParamterTokenRequestAuthenticator();
if (log.isTraceEnabled()) {
log.trace("try query paramter auth");
}
outcome = queryParamAuth.authenticate(facade);
if (outcome == AuthOutcome.FAILED) {
challenge = queryParamAuth.getChallenge();
log.debug("QueryParamAuth auth FAILED");
return AuthOutcome.FAILED;
} else if (outcome == AuthOutcome.AUTHENTICATED) {
if (verifySSL()) return AuthOutcome.FAILED;
log.debug("QueryParamAuth AUTHENTICATED");
completeAuthentication(queryParamAuth, "KEYCLOAK");
return AuthOutcome.AUTHENTICATED;
}
if (deployment.isEnableBasicAuth()) {
BasicAuthRequestAuthenticator basicAuth = createBasicAuthAuthenticator();
if (log.isTraceEnabled()) {
log.trace("try basic auth");
}
outcome = basicAuth.authenticate(facade);
if (outcome == AuthOutcome.FAILED) {
challenge = basicAuth.getChallenge();
log.debug("BasicAuth FAILED");
return AuthOutcome.FAILED;
} else if (outcome == AuthOutcome.AUTHENTICATED) {
if (verifySSL()) return AuthOutcome.FAILED;
log.debug("BasicAuth AUTHENTICATED");
completeAuthentication(basicAuth, "BASIC");
return AuthOutcome.AUTHENTICATED;
@@ -150,6 +168,10 @@ public abstract class RequestAuthenticator {
return new BasicAuthRequestAuthenticator(deployment);
}
protected QueryParamterTokenRequestAuthenticator createQueryParamterTokenRequestAuthenticator() {
return new QueryParamterTokenRequestAuthenticator(deployment);
}
protected void completeAuthentication(OAuthRequestAuthenticator oauth) {
RefreshableKeycloakSecurityContext session = new RefreshableKeycloakSecurityContext(deployment, tokenStore, oauth.getTokenString(), oauth.getToken(), oauth.getIdTokenString(), oauth.getIdToken(), oauth.getRefreshToken());
final KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal = new KeycloakPrincipal<RefreshableKeycloakSecurityContext>(AdapterUtils.getPrincipalName(deployment, oauth.getToken()), session);
@@ -158,10 +180,12 @@ public abstract class RequestAuthenticator {
}
protected abstract void completeOAuthAuthentication(KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal);
protected abstract void completeBearerAuthentication(KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal, String method);
/**
* After code is received, we change the session id if possible to guard against https://www.owasp.org/index.php/Session_Fixation
*
* @param create
* @return
*/
@@ -54,6 +54,10 @@ public class JWTClientCredentialsProvider implements ClientCredentialsProvider {
this.tokenTimeout = tokenTimeout;
}
protected int getTokenTimeout() {
return tokenTimeout;
}
@Override
public void init(KeycloakDeployment deployment, Object config) {
if (config == null || !(config instanceof Map)) {
@@ -29,7 +29,7 @@ import org.keycloak.representations.AccessToken;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
import org.keycloak.representations.authorization.Permission;
import org.keycloak.representations.idm.authorization.Permission;
import java.net.URI;
import java.util.Collections;
@@ -126,11 +126,13 @@ public abstract class AbstractPolicyEnforcer {
List<Permission> permissions = authorization.getPermissions();
for (Permission permission : permissions) {
Set<String> allowedScopes = permission.getScopes();
if (permission.getResourceSetId() != null) {
if (isResourcePermission(actualPathConfig, permission)) {
if (((allowedScopes == null || allowedScopes.isEmpty()) && requiredScopes.isEmpty()) || allowedScopes.containsAll(requiredScopes)) {
if (actualPathConfig.isInstance() && !matchResourcePermission(actualPathConfig, permission)) {
continue;
}
if (hasResourceScopePermission(requiredScopes, permission, actualPathConfig)) {
LOGGER.debugf("Authorization GRANTED for path [%s]. Permissions [%s].", actualPathConfig, permissions);
if (request.getMethod().equalsIgnoreCase("DELETE") && actualPathConfig.isInstance()) {
this.paths.remove(actualPathConfig);
@@ -139,8 +141,7 @@ public abstract class AbstractPolicyEnforcer {
}
}
} else {
if ((allowedScopes.isEmpty() && requiredScopes.isEmpty()) || allowedScopes.containsAll(requiredScopes)) {
LOGGER.debugf("Authorization GRANTED for path [%s]. Permissions [%s].", actualPathConfig, permissions);
if (hasResourceScopePermission(requiredScopes, permission, actualPathConfig)) {
return true;
}
}
@@ -151,6 +152,11 @@ public abstract class AbstractPolicyEnforcer {
return false;
}
private boolean hasResourceScopePermission(Set<String> requiredScopes, Permission permission, PathConfig actualPathConfig) {
Set<String> allowedScopes = permission.getScopes();
return (allowedScopes.containsAll(requiredScopes) || allowedScopes.isEmpty());
}
protected AuthzClient getAuthzClient() {
return this.authzClient;
}
@@ -210,7 +216,6 @@ public abstract class AbstractPolicyEnforcer {
config.setPath(targetResource.getUri());
config.setScopes(originalConfig.getScopes());
config.setMethods(originalConfig.getMethods());
config.setInstance(true);
config.setParentConfig(originalConfig);
this.paths.add(config);
@@ -244,13 +249,17 @@ public abstract class AbstractPolicyEnforcer {
private boolean isResourcePermission(PathConfig actualPathConfig, Permission permission) {
// first we try a match using resource id
boolean resourceMatch = permission.getResourceSetId().equals(actualPathConfig.getId());
boolean resourceMatch = matchResourcePermission(actualPathConfig, permission);
// as a fallback, check if the current path is an instance and if so, check if parent's id matches the permission
if (!resourceMatch && actualPathConfig.isInstance()) {
resourceMatch = permission.getResourceSetId().equals(actualPathConfig.getParentConfig().getId());
resourceMatch = matchResourcePermission(actualPathConfig.getParentConfig(), permission);
}
return resourceMatch;
}
private boolean matchResourcePermission(PathConfig actualPathConfig, Permission permission) {
return permission.getResourceSetId().equals(actualPathConfig.getId());
}
}
@@ -26,12 +26,17 @@ import org.keycloak.authorization.client.AuthorizationDeniedException;
import org.keycloak.authorization.client.AuthzClient;
import org.keycloak.authorization.client.representation.AuthorizationRequest;
import org.keycloak.authorization.client.representation.AuthorizationResponse;
import org.keycloak.authorization.client.representation.EntitlementRequest;
import org.keycloak.authorization.client.representation.EntitlementResponse;
import org.keycloak.authorization.client.representation.PermissionRequest;
import org.keycloak.authorization.client.representation.PermissionResponse;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
import org.keycloak.representations.idm.authorization.Permission;
import org.keycloak.util.JsonSerialization;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
/**
@@ -50,9 +55,8 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
int retry = 2;
AccessToken original = accessToken;
while (retry >= 0) {
while (retry > 0) {
if (super.isAuthorized(pathConfig, requiredScopes, accessToken, httpFacade)) {
original.setAuthorization(accessToken.getAuthorization());
return true;
}
@@ -62,6 +66,21 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
return false;
}
AccessToken.Authorization authorization = original.getAuthorization();
if (authorization == null) {
authorization = new AccessToken.Authorization();
authorization.setPermissions(new ArrayList<Permission>());
}
AccessToken.Authorization newAuthorization = accessToken.getAuthorization();
if (newAuthorization != null) {
authorization.getPermissions().addAll(newAuthorization.getPermissions());
}
original.setAuthorization(authorization);
retry--;
}
@@ -107,8 +126,21 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
return null;
} else {
LOGGER.debug("Obtaining entitlements for authenticated user.");
EntitlementResponse authzResponse = authzClient.entitlement(accessToken).getAll(authzClient.getConfiguration().getClientId());
return RSATokenVerifier.verifyToken(authzResponse.getRpt(), deployment.getRealmKey(), deployment.getRealmInfoUrl());
AccessToken token = httpFacade.getSecurityContext().getToken();
if (token.getAuthorization() == null) {
EntitlementResponse authzResponse = authzClient.entitlement(accessToken).getAll(authzClient.getConfiguration().getClientId());
return RSATokenVerifier.verifyToken(authzResponse.getRpt(), deployment.getRealmKey(), deployment.getRealmInfoUrl());
} else {
EntitlementRequest request = new EntitlementRequest();
PermissionRequest permissionRequest = new PermissionRequest();
permissionRequest.setResourceSetId(pathConfig.getId());
permissionRequest.setResourceSetName(pathConfig.getName());
permissionRequest.setScopes(new HashSet<>(pathConfig.getScopes()));
request.addPermission(permissionRequest);
EntitlementResponse authzResponse = authzClient.entitlement(accessToken).get(authzClient.getConfiguration().getClientId(), request);
return RSATokenVerifier.verifyToken(authzResponse.getRpt(), deployment.getRealmKey(), deployment.getRealmInfoUrl());
}
}
} catch (AuthorizationDeniedException e) {
return null;
@@ -30,7 +30,7 @@ import org.keycloak.authorization.client.resource.ProtectedResource;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
import org.keycloak.representations.authorization.Permission;
import org.keycloak.representations.idm.authorization.Permission;
import java.util.ArrayList;
import java.util.HashSet;
@@ -45,7 +45,6 @@ public class PolicyEnforcer {
private static Logger LOGGER = Logger.getLogger(PolicyEnforcer.class);
private final KeycloakDeployment deployment;
private final PathMatcher pathMatcher;
private final AuthzClient authzClient;
private final PolicyEnforcerConfig enforcerConfig;
private final List<PathConfig> paths;
@@ -54,7 +53,6 @@ public class PolicyEnforcer {
this.deployment = deployment;
this.enforcerConfig = adapterConfig.getPolicyEnforcerConfig();
this.authzClient = AuthzClient.create(new Configuration(adapterConfig.getAuthServerUrl(), adapterConfig.getRealm(), adapterConfig.getResource(), adapterConfig.getCredentials(), deployment.getClient()));
this.pathMatcher = new PathMatcher();
this.paths = configurePaths(this.authzClient.protection().resource(), this.enforcerConfig);
if (LOGGER.isDebugEnabled()) {
@@ -43,6 +43,7 @@ import org.keycloak.common.VerificationException;
import org.keycloak.adapters.authentication.ClientCredentialsProviderUtils;
import org.keycloak.constants.ServiceUrlConstants;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
import org.keycloak.util.JsonSerialization;
import org.keycloak.common.util.KeycloakUriBuilder;
@@ -102,9 +103,9 @@ public class DirectAccessGrantsLoginModule extends AbstractKeycloakLoginModule {
StringBuilder errorBuilder = new StringBuilder("Login failed. Invalid status: " + status);
if (entity != null) {
InputStream is = entity.getContent();
Map<String, String> errors = (Map<String, String>) JsonSerialization.readValue(is, Map.class);
errorBuilder.append(", OAuth2 error. Error: " + errors.get(OAuth2Constants.ERROR))
.append(", Error description: " + errors.get(OAuth2Constants.ERROR_DESCRIPTION));
OAuth2ErrorRepresentation errorRep = JsonSerialization.readValue(is, OAuth2ErrorRepresentation.class);
errorBuilder.append(", OAuth2 error. Error: " + errorRep.getError())
.append(", Error description: " + errorRep.getErrorDescription());
}
String error = errorBuilder.toString();
log.warn(error);
@@ -161,9 +162,9 @@ public class DirectAccessGrantsLoginModule extends AbstractKeycloakLoginModule {
if (entity != null) {
InputStream is = entity.getContent();
if (status == 400) {
Map<String, String> errors = (Map<String, String>) JsonSerialization.readValue(is, Map.class);
errorBuilder.append(", OAuth2 error. Error: " + errors.get(OAuth2Constants.ERROR))
.append(", Error description: " + errors.get(OAuth2Constants.ERROR_DESCRIPTION));
OAuth2ErrorRepresentation errorRep = JsonSerialization.readValue(is, OAuth2ErrorRepresentation.class);
errorBuilder.append(", OAuth2 error. Error: " + errorRep.getError())
.append(", Error description: " + errorRep.getErrorDescription());
} else {
if (is != null) is.close();
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-integration-pom</artifactId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -49,7 +49,6 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
// if it's not a web-app there's nothing to secure
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
@@ -67,24 +66,24 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
// otherwise
LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
boolean hasSubsystemConfig = service.isSecureDeployment(deploymentName);
boolean hasSubsystemConfig = service.isSecureDeployment(deploymentUnit);
boolean webRequiresKC = loginConfig != null && "KEYCLOAK".equalsIgnoreCase(loginConfig.getAuthMethod());
if (hasSubsystemConfig || webRequiresKC) {
log.debug("Setting up KEYCLOAK auth method for WAR: " + deploymentName);
log.debug("Setting up KEYCLOAK auth method for WAR: " + deploymentUnit.getName());
// if secure-deployment configuration exists for web app, we force KEYCLOAK auth method on it
if (hasSubsystemConfig) {
addJSONData(service.getJSON(deploymentName), warMetaData);
addJSONData(service.getJSON(deploymentUnit), warMetaData);
if (loginConfig != null) {
loginConfig.setAuthMethod("KEYCLOAK");
loginConfig.setRealmName(service.getRealmName(deploymentName));
loginConfig.setRealmName(service.getRealmName(deploymentUnit));
} else {
log.warn("Failed to set up KEYCLOAK auth method for WAR: " + deploymentName + " (loginConfig == null)");
log.warn("Failed to set up KEYCLOAK auth method for WAR: " + deploymentUnit.getName() + " (loginConfig == null)");
}
}
addValve(webMetaData);
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentName);
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
}
}
@@ -25,6 +25,9 @@ import java.util.HashMap;
import java.util.Map;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.web.deployment.WarMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
/**
* This service keeps track of the entire Keycloak management model so as to provide
@@ -154,13 +157,15 @@ public final class KeycloakAdapterConfigService {
return null;
}
public String getRealmName(String deploymentName) {
public String getRealmName(DeploymentUnit deploymentUnit) {
String deploymentName = preferredDeploymentName(deploymentUnit);
ModelNode deployment = this.secureDeployments.get(deploymentName);
return deployment.get(RealmDefinition.TAG_NAME).asString();
}
public String getJSON(String deploymentName) {
public String getJSON(DeploymentUnit deploymentUnit) {
String deploymentName = preferredDeploymentName(deploymentUnit);
ModelNode deployment = this.secureDeployments.get(deploymentName);
String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
ModelNode realm = this.realms.get(realmName);
@@ -184,9 +189,29 @@ public final class KeycloakAdapterConfigService {
}
}
public boolean isSecureDeployment(String deploymentName) {
public boolean isSecureDeployment(DeploymentUnit deploymentUnit) {
//log.info("********* CHECK KEYCLOAK DEPLOYMENT: deployments.size()" + deployments.size());
String deploymentName = preferredDeploymentName(deploymentUnit);
return this.secureDeployments.containsKey(deploymentName);
}
// KEYCLOAK-3273: prefer module name if available
private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return deploymentName;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return deploymentName;
}
String moduleName = webMetaData.getModuleName();
if (moduleName != null) return moduleName + ".war";
return deploymentName;
}
}
@@ -46,8 +46,7 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
if (!KeycloakAdapterConfigService.getInstance().isSecureDeployment(deploymentName)) {
if (!KeycloakAdapterConfigService.getInstance().isSecureDeployment(deploymentUnit)) {
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return;
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -119,6 +119,7 @@ public class KeycloakInstalled {
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
.queryParam(OAuth2Constants.STATE, state)
.queryParam(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
.build().toString();
Desktop.getDesktop().browse(new URI(authUrl));
@@ -175,6 +176,7 @@ public class KeycloakInstalled {
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
.queryParam(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
.build().toString();
printer.println("Open the following URL in a browser. After login copy/paste the code back and press <enter>");
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -20,6 +20,7 @@ package org.keycloak.jaxrs;
import org.keycloak.AbstractOAuthClient;
import org.keycloak.OAuth2Constants;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.util.TokenUtil;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.InternalServerErrorException;
@@ -85,14 +86,13 @@ public class JaxrsOAuthClient extends AbstractOAuthClient {
}
public Response redirect(UriInfo uriInfo, String redirectUri) {
String state = getStateCode();
String scopeParam = TokenUtil.attachOIDCScope(scope);
UriBuilder uriBuilder = UriBuilder.fromUri(authUrl)
.queryParam(OAuth2Constants.CLIENT_ID, clientId)
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
.queryParam(OAuth2Constants.STATE, state);
if (scope != null) {
uriBuilder.queryParam(OAuth2Constants.SCOPE, scope);
}
.queryParam(OAuth2Constants.STATE, state)
.queryParam(OAuth2Constants.SCOPE, scopeParam);
URI url = uriBuilder.build();
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -340,13 +340,13 @@ public abstract class AbstractKeycloakJettyAuthenticator extends LoginAuthentica
Authentication authentication = request.getAuthentication();
if (!(authentication instanceof KeycloakAuthentication)) {
UserIdentity userIdentity = createIdentity(principal);
authentication = createAuthentication(userIdentity);
authentication = createAuthentication(userIdentity, request);
request.setAuthentication(authentication);
}
return authentication;
}
protected abstract Authentication createAuthentication(UserIdentity userIdentity);
protected abstract Authentication createAuthentication(UserIdentity userIdentity, Request request);
public static abstract class KeycloakAuthentication extends UserAuthentication {
public KeycloakAuthentication(String method, UserIdentity userIdentity) {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -50,7 +50,7 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
}
@Override
protected Authentication createAuthentication(UserIdentity userIdentity) {
protected Authentication createAuthentication(UserIdentity userIdentity, Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -52,7 +52,7 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
}
@Override
protected Authentication createAuthentication(UserIdentity userIdentity) {
protected Authentication createAuthentication(UserIdentity userIdentity, Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -47,7 +47,7 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
}
@Override
protected Authentication createAuthentication(UserIdentity userIdentity) {
protected Authentication createAuthentication(UserIdentity userIdentity, Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
+156
View File
@@ -0,0 +1,156 @@
<?xml version="1.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.
-->
<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>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<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>
org.keycloak.adapters.jetty.*
</keycloak.osgi.export>
<keycloak.osgi.import>
org.eclipse.jetty.*;resolution:=optional,
javax.servlet.*;version="[3.0,4)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<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-adapter-core</artifactId>
</dependency>
<dependency>
<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>
<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.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>${jetty9.version}</version>
<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>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<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>
</build>
</project>
@@ -0,0 +1,47 @@
/*
* 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.jetty;
import org.eclipse.jetty.server.Request;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.JettyRequestAuthenticator;
import org.keycloak.adapters.spi.HttpFacade;
import javax.servlet.http.HttpSession;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class Jetty93RequestAuthenticator extends JettyRequestAuthenticator {
public Jetty93RequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort, Request request) {
super(facade, deployment, tokenStore, sslRedirectPort, request);
}
@Override
protected String changeHttpSessionId(boolean create) {
Request request = this.request;
HttpSession session = request.getSession(false);
if (session == null) {
return request.getSession(true).getId();
}
if (!deployment.isTurnOffChangeSessionIdOnLogin()) return request.changeSessionId();
else return session.getId();
}
}
@@ -0,0 +1,112 @@
/*
* 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.jetty;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.MultiMap;
import org.keycloak.adapters.spi.AdapterSessionStore;
import org.keycloak.adapters.jetty.spi.JettyHttpFacade;
import org.keycloak.common.util.MultivaluedHashMap;
import javax.servlet.http.HttpSession;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class JettyAdapterSessionStore implements AdapterSessionStore {
public static final String CACHED_FORM_PARAMETERS = "__CACHED_FORM_PARAMETERS";
protected Request myRequest;
public JettyAdapterSessionStore(Request request) {
this.myRequest = request; // for IDE/compilation purposes
}
protected MultiMap<String> extractFormParameters(Request base_request) {
MultiMap<String> formParameters = new MultiMap<String>();
base_request.extractFormParameters(formParameters);
return formParameters;
}
protected void restoreFormParameters(MultiMap<String> j_post, Request base_request) {
base_request.setContentParameters(j_post);
}
public boolean restoreRequest() {
HttpSession session = myRequest.getSession(false);
if (session == null) return false;
synchronized (session) {
String j_uri = (String) session.getAttribute(FormAuthenticator.__J_URI);
if (j_uri != null) {
// check if the request is for the same url as the original and restore
// params if it was a post
StringBuffer buf = myRequest.getRequestURL();
if (myRequest.getQueryString() != null)
buf.append("?").append(myRequest.getQueryString());
if (j_uri.equals(buf.toString())) {
String method = (String)session.getAttribute(JettyHttpFacade.__J_METHOD);
myRequest.setMethod(method);
MultivaluedHashMap<String, String> j_post = (MultivaluedHashMap<String, String>) session.getAttribute(CACHED_FORM_PARAMETERS);
if (j_post != null) {
myRequest.setContentType("application/x-www-form-urlencoded");
MultiMap<String> map = new MultiMap<String>();
for (String key : j_post.keySet()) {
for (String val : j_post.getList(key)) {
map.add(key, val);
}
}
restoreFormParameters(map, myRequest);
}
session.removeAttribute(FormAuthenticator.__J_URI);
session.removeAttribute(JettyHttpFacade.__J_METHOD);
session.removeAttribute(FormAuthenticator.__J_POST);
}
return true;
}
}
return false;
}
public void saveRequest() {
// remember the current URI
HttpSession session = myRequest.getSession();
synchronized (session) {
// But only if it is not set already, or we save every uri that leads to a login form redirect
if (session.getAttribute(FormAuthenticator.__J_URI) == null) {
StringBuffer buf = myRequest.getRequestURL();
if (myRequest.getQueryString() != null)
buf.append("?").append(myRequest.getQueryString());
session.setAttribute(FormAuthenticator.__J_URI, buf.toString());
session.setAttribute(JettyHttpFacade.__J_METHOD, myRequest.getMethod());
if ("application/x-www-form-urlencoded".equals(myRequest.getContentType()) && "POST".equalsIgnoreCase(myRequest.getMethod())) {
MultiMap<String> formParameters = extractFormParameters(myRequest);
MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
for (String key : formParameters.keySet()) {
for (Object value : formParameters.getValues(key)) {
map.add(key, (String) value);
}
}
session.setAttribute(CACHED_FORM_PARAMETERS, map);
}
}
}
}
}
@@ -0,0 +1,69 @@
/*
* 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.jetty;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.AbstractKeycloakJettyAuthenticator;
import org.keycloak.adapters.jetty.core.JettyRequestAuthenticator;
import org.keycloak.adapters.jetty.core.JettySessionTokenStore;
import org.keycloak.adapters.jetty.spi.JettyHttpFacade;
import javax.servlet.ServletRequest;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticator {
public KeycloakJettyAuthenticator() {
super();
}
@Override
protected Request resolveRequest(ServletRequest req) {
return Request.getBaseRequest(req);
}
@Override
protected Authentication createAuthentication(UserIdentity userIdentity, final Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
logoutCurrent(request);
}
};
}
@Override
public AdapterTokenStore createSessionTokenStore(Request request, KeycloakDeployment resolvedDeployment) {
return new JettySessionTokenStore(request, resolvedDeployment, new JettyAdapterSessionStore(request));
}
@Override
protected JettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade,
KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
return new Jetty93RequestAuthenticator(facade, deployment, tokenStore, -1, request);
}
}
+3 -2
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Jetty Integration</name>
@@ -33,7 +33,8 @@
<modules>
<module>jetty-core</module>
<module>jetty8.1</module>
<module>jetty9.2</module>
<module>jetty9.1</module>
<module>jetty9.2</module>
<module>jetty9.3</module>
</modules>
</project>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -49,7 +49,7 @@
*/
this.authorize = function (wwwAuthenticateHeader) {
this.then = function (onGrant, onDeny, onError) {
if (wwwAuthenticateHeader.startsWith('UMA')) {
if (wwwAuthenticateHeader.indexOf('UMA') != -1) {
var params = wwwAuthenticateHeader.split(',');
for (i = 0; i < params.length; i++) {
@@ -96,7 +96,7 @@
));
}
}
} else if (wwwAuthenticateHeader.startsWith('KC_ETT')) {
} else if (wwwAuthenticateHeader.indexOf('KC_ETT') != -1) {
var params = wwwAuthenticateHeader.substring('KC_ETT'.length).trim().split(',');
var clientId = null;
+120 -64
View File
@@ -25,7 +25,7 @@
var kc = this;
var adapter;
var refreshQueue = [];
var storage;
var callbackStorage;
var loginIframe = {
enable: true,
@@ -36,10 +36,10 @@
kc.init = function (initOptions) {
kc.authenticated = false;
storage = new PersistentStorage();
callbackStorage = createCallbackStorage();
if (initOptions && initOptions.adapter === 'cordova') {
adapter = loadAdapter('cordova');
adapter = loadAdapter('cordova');
} else if (initOptions && initOptions.adapter === 'default') {
adapter = loadAdapter();
} else {
@@ -103,8 +103,8 @@
initPromise.promise.success(function() {
kc.onReady && kc.onReady(kc.authenticated);
promise.setSuccess(kc.authenticated);
}).error(function() {
promise.setError();
}).error(function(errorData) {
promise.setError(errorData);
});
var configPromise = loadConfig(config);
@@ -201,13 +201,15 @@
redirectUri += (redirectUri.indexOf('?') == -1 ? '?' : '&') + 'prompt=' + options.prompt;
}
storage.setItem('oauthState', JSON.stringify({ state: state, nonce: nonce, redirectUri: encodeURIComponent(redirectUri) }));
callbackStorage.add({ state: state, nonce: nonce, redirectUri: encodeURIComponent(redirectUri) });
var action = 'auth';
if (options && options.action == 'register') {
action = 'registrations';
}
var scope = (options && options.scope) ? "openid " + options.scope : "openid";
var url = getRealmUrl()
+ '/protocol/openid-connect/' + action
+ '?client_id=' + encodeURIComponent(kc.clientId)
@@ -215,12 +217,17 @@
+ '&state=' + encodeURIComponent(state)
+ '&nonce=' + encodeURIComponent(nonce)
+ '&response_mode=' + encodeURIComponent(kc.responseMode)
+ '&response_type=' + encodeURIComponent(kc.responseType);
+ '&response_type=' + encodeURIComponent(kc.responseType)
+ '&scope=' + encodeURIComponent(scope);
if (options && options.prompt) {
url += '&prompt=' + encodeURIComponent(options.prompt);
}
if (options && options.maxAge) {
url += '&max_age=' + encodeURIComponent(options.maxAge);
}
if (options && options.loginHint) {
url += '&login_hint=' + encodeURIComponent(options.loginHint);
}
@@ -229,10 +236,6 @@
url += '&kc_idp_hint=' + encodeURIComponent(options.idpHint);
}
if (options && options.scope) {
url += '&scope=' + encodeURIComponent(options.scope);
}
if (options && options.locale) {
url += '&ui_locales=' + encodeURIComponent(options.locale);
}
@@ -463,8 +466,9 @@
if (error) {
if (prompt != 'none') {
kc.onAuthError && kc.onAuthError();
promise && promise.setError();
var errorData = { error: error, error_description: oauth.error_description };
kc.onAuthError && kc.onAuthError(errorData);
promise && promise.setError(errorData);
} else {
promise && promise.setSuccess();
}
@@ -697,15 +701,11 @@
function parseCallback(url) {
var oauth = new CallbackParser(url, kc.responseMode).parseUri();
var oauthState = callbackStorage.get(oauth.state);
var oauthState = storage.getItem('oauthState');
var sessionState = oauthState && JSON.parse(oauthState);
if (sessionState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token) && oauth.state && oauth.state == sessionState.state) {
storage.removeItem('oauthState');
oauth.redirectUri = sessionState.redirectUri;
oauth.storedNonce = sessionState.nonce;
if (oauthState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token)) {
oauth.redirectUri = oauthState.redirectUri;
oauth.storedNonce = oauthState.nonce;
if (oauth.fragment) {
oauth.newUrl += '#' + oauth.fragment;
@@ -792,8 +792,22 @@
if (event.origin !== loginIframe.iframeOrigin) {
return;
}
var data = JSON.parse(event.data);
try {
var data = JSON.parse(event.data);
} catch (err) {
return;
}
if (!data.callbackId) {
return;
}
var promise = loginIframe.callbackMap[data.callbackId];
if (!promise) {
return;
}
delete loginIframe.callbackMap[data.callbackId];
if ((!kc.sessionId || kc.sessionId == data.session) && data.loggedIn) {
@@ -982,60 +996,93 @@
throw 'invalid adapter type: ' + type;
}
var PersistentStorage = function() {
if (!(this instanceof PersistentStorage)) {
return new PersistentStorage();
var LocalStorage = function() {
if (!(this instanceof LocalStorage)) {
return new LocalStorage();
}
var ps = this;
var useCookieStorage = function () {
if (typeof localStorage === "undefined") {
return true;
localStorage.setItem('kc-test', 'test');
localStorage.removeItem('kc-test');
var cs = this;
function clearExpired() {
var time = new Date().getTime();
for (var i = 1; i <= localStorage.length; i++) {
var key = localStorage.key(i);
if (key && key.indexOf('kc-callback-') == 0) {
var value = localStorage.getItem(key);
if (value) {
try {
var expires = JSON.parse(value).expires;
if (!expires || expires < time) {
localStorage.removeItem(key);
}
} catch (err) {
localStorage.removeItem(key);
}
}
}
}
try {
var key = '@@keycloak-session-storage/test';
localStorage.setItem(key, 'test');
}
cs.get = function(state) {
if (!state) {
return;
}
var key = 'kc-callback-' + state;
var value = localStorage.getItem(key);
if (value) {
localStorage.removeItem(key);
return false;
} catch (err) {
// Probably in Safari "private mode" where localStorage
// quota is 0, or quota exceeded. Switching to cookie
// storage.
return true;
value = JSON.parse(value);
}
}
ps.setItem = function(key, value) {
if (useCookieStorage()) {
setCookie(key, value, cookieExpiration(5));
} else {
localStorage.setItem(key, value);
}
}
clearExpired();
return value;
};
ps.getItem = function(key) {
if (useCookieStorage()) {
return getCookie(key);
}
return localStorage.getItem(key);
}
cs.add = function(state) {
clearExpired();
ps.removeItem = function(key) {
if (typeof localStorage !== "undefined") {
try {
// Always try to delete from localStorage.
localStorage.removeItem(key);
} catch (err) { }
var key = 'kc-callback-' + state.state;
state.expires = new Date().getTime() + (60 * 60 * 1000);
localStorage.setItem(key, JSON.stringify(state));
};
};
var CookieStorage = function() {
if (!(this instanceof CookieStorage)) {
return new CookieStorage();
}
var cs = this;
cs.get = function(state) {
if (!state) {
return;
}
// Always remove the cookie.
var value = getCookie('kc-callback-' + state);
setCookie('kc-callback-' + state, '', cookieExpiration(-100));
if (value) {
return JSON.parse(value);
}
};
cs.add = function(state) {
setCookie('kc-callback-' + state.state, JSON.stringify(state), cookieExpiration(60));
};
cs.removeItem = function(key) {
setCookie(key, '', cookieExpiration(-100));
}
};
var cookieExpiration = function (minutes) {
var exp = new Date();
exp.setTime(exp.getTime() + (minutes*60*1000));
return exp;
}
};
var getCookie = function (key) {
var name = key + '=';
@@ -1050,13 +1097,22 @@
}
}
return '';
}
};
var setCookie = function (key, value, expirationDate) {
var cookie = key + '=' + value + '; '
+ 'expires=' + expirationDate.toUTCString() + '; ';
document.cookie = cookie;
}
};
function createCallbackStorage() {
try {
return new LocalStorage();
} catch (err) {
}
return new CookieStorage();
}
var CallbackParser = function(uriToParse, responseMode) {
@@ -1103,7 +1159,7 @@
}
var handleQueryParam = function(paramName, paramValue, oauth) {
var supportedOAuthParams = [ 'code', 'error', 'state' ];
var supportedOAuthParams = [ 'code', 'state', 'error', 'error_description' ];
for (var i = 0 ; i< supportedOAuthParams.length ; i++) {
if (paramName === supportedOAuthParams[i]) {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak OIDC Client Adapter Modules</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -47,6 +47,7 @@ import java.io.InputStream;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -56,10 +57,18 @@ public class KeycloakOIDCFilter implements Filter {
protected AdapterDeploymentContext deploymentContext;
protected SessionIdMapper idMapper = new InMemorySessionIdMapper();
protected NodesRegistrationManagement nodesRegistrationManagement;
protected Pattern skipPattern;
private final static Logger log = Logger.getLogger(""+KeycloakOIDCFilter.class);
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
String skipPatternDefinition = filterConfig.getInitParameter("keycloak.config.skipPattern");
if (skipPatternDefinition != null) {
skipPattern = Pattern.compile(skipPatternDefinition, Pattern.DOTALL);
}
String configResolverClass = filterConfig.getInitParameter("keycloak.config.resolver");
if (configResolverClass != null) {
try {
@@ -85,13 +94,7 @@ public class KeycloakOIDCFilter implements Filter {
if (pathParam != null) path = pathParam;
is = filterConfig.getServletContext().getResourceAsStream(path);
}
KeycloakDeployment kd;
if (is == null) {
log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
kd = new KeycloakDeployment();
} else {
kd = KeycloakDeploymentBuilder.build(is);
}
KeycloakDeployment kd = createKeycloakDeploymentFrom(is);
deploymentContext = new AdapterDeploymentContext(kd);
log.fine("Keycloak is using a per-deployment configuration.");
}
@@ -99,13 +102,30 @@ public class KeycloakOIDCFilter implements Filter {
nodesRegistrationManagement = new NodesRegistrationManagement();
}
private KeycloakDeployment createKeycloakDeploymentFrom(InputStream is) {
if (is == null) {
log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
return new KeycloakDeployment();
}
return KeycloakDeploymentBuilder.build(is);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
log.fine("Keycloak OIDC Filter");
//System.err.println("Keycloak OIDC Filter: " + ((HttpServletRequest)req).getRequestURL().toString());
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (shouldSkip(request)) {
chain.doFilter(req, res);
return;
}
OIDCServletHttpFacade facade = new OIDCServletHttpFacade(request, response);
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
if (deployment == null || !deployment.isConfigured()) {
@@ -171,6 +191,26 @@ public class KeycloakOIDCFilter implements Filter {
}
/**
* Decides whether this {@link Filter} should skip the given {@link HttpServletRequest} based on the configured {@link KeycloakOIDCFilter#skipPattern}.
* Patterns are matched against the {@link HttpServletRequest#getRequestURI() requestURI} of a request without the context-path.
* A request for {@code /myapp/index.html} would be tested with {@code /index.html} against the skip pattern.
* Skipped requests will not be processed further by {@link KeycloakOIDCFilter} and immediately delegated to the {@link FilterChain}.
*
* @param request the request to check
* @return {@code true} if the request should not be handled,
* {@code false} otherwise.
*/
private boolean shouldSkip(HttpServletRequest request) {
if (skipPattern == null) {
return false;
}
String requestPath = request.getRequestURI().substring(request.getContextPath().length());
return skipPattern.matcher(requestPath).matches();
}
@Override
public void destroy() {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -30,6 +30,7 @@ import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.IDToken;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.util.TokenUtil;
import javax.security.cert.X509Certificate;
import javax.servlet.http.Cookie;
@@ -91,15 +92,15 @@ public class ServletOAuthClient extends KeycloakDeploymentDelegateOAuthClient {
String state = getStateCode();
KeycloakDeployment resolvedDeployment = resolveDeployment(getDeployment(), request);
String authUrl = resolvedDeployment.getAuthUrl().clone().build().toString();
String scopeParam = TokenUtil.attachOIDCScope(scope);
KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(authUrl)
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
.queryParam(OAuth2Constants.CLIENT_ID, getClientId())
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
.queryParam(OAuth2Constants.STATE, state);
if (scope != null) {
uriBuilder.queryParam(OAuth2Constants.SCOPE, scope);
}
.queryParam(OAuth2Constants.STATE, state)
.queryParam(OAuth2Constants.SCOPE, scopeParam);
URI url = uriBuilder.build();
String stateCookiePath = this.stateCookiePath;
+40 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -67,6 +67,45 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@@ -17,24 +17,38 @@
package org.keycloak.adapters.springboot;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.WebResourceCollection;
import org.apache.catalina.Context;
import org.apache.tomcat.util.descriptor.web.LoginConfig;
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.Server;
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.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 java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
@@ -61,80 +75,212 @@ public class KeycloakSpringBootConfiguration {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
if (configurableEmbeddedServletContainer instanceof TomcatEmbeddedServletContainerFactory) {
TomcatEmbeddedServletContainerFactory container = (TomcatEmbeddedServletContainerFactory) configurableEmbeddedServletContainer;
container.addContextValves(new KeycloakAuthenticatorValve());
container.addContextCustomizers(tomcatKeycloakContextCustomizer());
container.addContextCustomizers(getTomcatKeycloakContextCustomizer());
} else if (configurableEmbeddedServletContainer instanceof UndertowEmbeddedServletContainerFactory) {
throw new IllegalArgumentException("Undertow Keycloak integration is not yet implemented");
UndertowEmbeddedServletContainerFactory container = (UndertowEmbeddedServletContainerFactory) configurableEmbeddedServletContainer;
container.addDeploymentInfoCustomizers(undertowKeycloakContextCustomizer());
} else if (configurableEmbeddedServletContainer instanceof JettyEmbeddedServletContainerFactory) {
throw new IllegalArgumentException("Jetty Keycloak integration is not yet implemented");
JettyEmbeddedServletContainerFactory container = (JettyEmbeddedServletContainerFactory) configurableEmbeddedServletContainer;
container.addServerCustomizers(jettyKeycloakServerCustomizer());
}
}
};
}
@Bean
public TomcatContextCustomizer getTomcatKeycloakContextCustomizer() {
return new TomcatContextCustomizer() {
@Override
public void customize(Context context) {
LoginConfig loginConfig = new LoginConfig();
loginConfig.setAuthMethod("KEYCLOAK");
context.setLoginConfig(loginConfig);
Set<String> authRoles = new HashSet<String>();
for (KeycloakSpringBootProperties.SecurityConstraint constraint : keycloakProperties.getSecurityConstraints()) {
for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
for (String authRole : collection.getAuthRoles()) {
if (!authRoles.contains(authRole)) {
context.addSecurityRole(authRole);
authRoles.add(authRole);
}
}
}
}
for (KeycloakSpringBootProperties.SecurityConstraint constraint : keycloakProperties.getSecurityConstraints()) {
SecurityConstraint tomcatConstraint = new SecurityConstraint();
for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
SecurityCollection tomcatSecCollection = new SecurityCollection();
if (collection.getName() != null) {
tomcatSecCollection.setName(collection.getName());
}
if (collection.getDescription() != null) {
tomcatSecCollection.setDescription(collection.getDescription());
}
for (String authRole : collection.getAuthRoles()) {
tomcatConstraint.addAuthRole(authRole);
}
for (String pattern : collection.getPatterns()) {
tomcatSecCollection.addPattern(pattern);
}
for (String method : collection.getMethods()) {
tomcatSecCollection.addMethod(method);
}
for (String method : collection.getOmittedMethods()) {
tomcatSecCollection.addOmittedMethod(method);
}
tomcatConstraint.addCollection(tomcatSecCollection);
}
context.addConstraint(tomcatConstraint);
}
context.addParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
}
};
@ConditionalOnClass(name = {"org.eclipse.jetty.webapp.WebAppContext"})
public JettyServerCustomizer jettyKeycloakServerCustomizer() {
return new KeycloakJettyServerCustomizer(keycloakProperties);
}
@Bean
@ConditionalOnClass(name = {"org.apache.catalina.startup.Tomcat"})
public TomcatContextCustomizer tomcatKeycloakContextCustomizer() {
return new KeycloakTomcatContextCustomizer(keycloakProperties);
}
@Bean
@ConditionalOnClass(name = {"io.undertow.Undertow"})
public UndertowDeploymentInfoCustomizer undertowKeycloakContextCustomizer() {
return new KeycloakUndertowDeploymentInfoCustomizer(keycloakProperties);
}
static class KeycloakUndertowDeploymentInfoCustomizer implements UndertowDeploymentInfoCustomizer {
private final KeycloakSpringBootProperties keycloakProperties;
public KeycloakUndertowDeploymentInfoCustomizer(KeycloakSpringBootProperties keycloakProperties) {
this.keycloakProperties = keycloakProperties;
}
@Override
public void customize(DeploymentInfo deploymentInfo) {
io.undertow.servlet.api.LoginConfig loginConfig = new io.undertow.servlet.api.LoginConfig(keycloakProperties.getRealm());
loginConfig.addFirstAuthMethod("KEYCLOAK");
deploymentInfo.setLoginConfig(loginConfig);
deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
deploymentInfo.addSecurityConstraints(getSecurityConstraints());
deploymentInfo.addServletExtension(new KeycloakServletExtension());
}
private List<io.undertow.servlet.api.SecurityConstraint> getSecurityConstraints() {
List<io.undertow.servlet.api.SecurityConstraint> undertowSecurityConstraints = new ArrayList<io.undertow.servlet.api.SecurityConstraint>();
for (KeycloakSpringBootProperties.SecurityConstraint constraintDefinition : keycloakProperties.getSecurityConstraints()) {
for (KeycloakSpringBootProperties.SecurityCollection collectionDefinition : constraintDefinition.getSecurityCollections()) {
io.undertow.servlet.api.SecurityConstraint undertowSecurityConstraint = new io.undertow.servlet.api.SecurityConstraint();
undertowSecurityConstraint.addRolesAllowed(collectionDefinition.getAuthRoles());
WebResourceCollection webResourceCollection = new WebResourceCollection();
webResourceCollection.addHttpMethods(collectionDefinition.getMethods());
webResourceCollection.addHttpMethodOmissions(collectionDefinition.getOmittedMethods());
webResourceCollection.addUrlPatterns(collectionDefinition.getPatterns());
undertowSecurityConstraint.addWebResourceCollections(webResourceCollection);
undertowSecurityConstraints.add(undertowSecurityConstraint);
}
}
return undertowSecurityConstraints;
}
}
static class KeycloakJettyServerCustomizer implements JettyServerCustomizer {
private final KeycloakSpringBootProperties keycloakProperties;
public KeycloakJettyServerCustomizer(KeycloakSpringBootProperties keycloakProperties) {
this.keycloakProperties = keycloakProperties;
}
@Override
public void customize(Server server) {
KeycloakJettyAuthenticator keycloakJettyAuthenticator = new KeycloakJettyAuthenticator();
keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolver());
List<ConstraintMapping> jettyConstraintMappings = new ArrayList<ConstraintMapping>();
for (KeycloakSpringBootProperties.SecurityConstraint constraintDefinition : keycloakProperties.getSecurityConstraints()) {
for (KeycloakSpringBootProperties.SecurityCollection securityCollectionDefinition : constraintDefinition
.getSecurityCollections()) {
Constraint jettyConstraint = new Constraint();
jettyConstraint.setName(securityCollectionDefinition.getName());
jettyConstraint.setAuthenticate(true);
if (securityCollectionDefinition.getName() != null) {
jettyConstraint.setName(securityCollectionDefinition.getName());
}
jettyConstraint.setRoles(securityCollectionDefinition.getAuthRoles().toArray(new String[0]));
ConstraintMapping jettyConstraintMapping = new ConstraintMapping();
if (securityCollectionDefinition.getPatterns().size() > 0) {
//First pattern wins
jettyConstraintMapping.setPathSpec(securityCollectionDefinition.getPatterns().get(0));
jettyConstraintMapping.setConstraint(jettyConstraint);
}
if (securityCollectionDefinition.getMethods().size() > 0) {
//First method wins
jettyConstraintMapping.setMethod(securityCollectionDefinition.getMethods().get(0));
}
jettyConstraintMapping.setMethodOmissions(
securityCollectionDefinition.getOmittedMethods().toArray(new String[0]));
jettyConstraintMappings.add(jettyConstraintMapping);
}
}
WebAppContext webAppContext = server.getBean(WebAppContext.class);
ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
securityHandler.setConstraintMappings(jettyConstraintMappings);
securityHandler.setAuthenticator(keycloakJettyAuthenticator);
webAppContext.setHandler(securityHandler);
}
}
static class KeycloakTomcatContextCustomizer implements TomcatContextCustomizer {
private final KeycloakSpringBootProperties keycloakProperties;
public KeycloakTomcatContextCustomizer(KeycloakSpringBootProperties keycloakProperties) {
this.keycloakProperties = keycloakProperties;
}
@Override
public void customize(Context context) {
LoginConfig loginConfig = new LoginConfig();
loginConfig.setAuthMethod("KEYCLOAK");
context.setLoginConfig(loginConfig);
Set<String> authRoles = new HashSet<String>();
for (KeycloakSpringBootProperties.SecurityConstraint constraint : keycloakProperties.getSecurityConstraints()) {
for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
for (String authRole : collection.getAuthRoles()) {
if (!authRoles.contains(authRole)) {
context.addSecurityRole(authRole);
authRoles.add(authRole);
}
}
}
}
for (KeycloakSpringBootProperties.SecurityConstraint constraint : keycloakProperties.getSecurityConstraints()) {
SecurityConstraint tomcatConstraint = new SecurityConstraint();
for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
SecurityCollection tomcatSecCollection = new SecurityCollection();
if (collection.getName() != null) {
tomcatSecCollection.setName(collection.getName());
}
if (collection.getDescription() != null) {
tomcatSecCollection.setDescription(collection.getDescription());
}
for (String authRole : collection.getAuthRoles()) {
tomcatConstraint.addAuthRole(authRole);
}
for (String pattern : collection.getPatterns()) {
tomcatSecCollection.addPattern(pattern);
}
for (String method : collection.getMethods()) {
tomcatSecCollection.addMethod(method);
}
for (String method : collection.getOmittedMethods()) {
tomcatSecCollection.addOmittedMethod(method);
}
tomcatConstraint.addCollection(tomcatSecCollection);
}
context.addConstraint(tomcatConstraint);
}
context.addParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
}
}
}
+8 -7
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -71,6 +71,13 @@
<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>
@@ -121,12 +128,6 @@
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Tomcat Integration</name>
+8 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -77,6 +77,13 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!-- Authorization -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.apache.tomcat</groupId>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</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>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -46,8 +46,7 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
// not sure if we need this yet, keeping here just in case
protected void addSecurityDomain(DeploymentUnit deploymentUnit, KeycloakAdapterConfigService service) {
String deploymentName = deploymentUnit.getName();
if (!service.isSecureDeployment(deploymentName)) {
if (!service.isSecureDeployment(deploymentUnit)) {
return;
}
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
@@ -67,10 +66,9 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
if (service.isSecureDeployment(deploymentName)) {
addKeycloakAuthData(phaseContext, deploymentName, service);
if (service.isSecureDeployment(deploymentUnit)) {
addKeycloakAuthData(phaseContext, service);
}
// FYI, Undertow Extension will find deployments that have auth-method set to KEYCLOAK
@@ -79,14 +77,14 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
// addSecurityDomain(deploymentUnit, service);
}
private void addKeycloakAuthData(DeploymentPhaseContext phaseContext, String deploymentName, KeycloakAdapterConfigService service) throws DeploymentUnitProcessingException {
private void addKeycloakAuthData(DeploymentPhaseContext phaseContext, KeycloakAdapterConfigService service) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
throw new DeploymentUnitProcessingException("WarMetaData not found for " + deploymentName + ". Make sure you have specified a WAR as your secure-deployment in the Keycloak subsystem.");
throw new DeploymentUnitProcessingException("WarMetaData not found for " + deploymentUnit.getName() + ". Make sure you have specified a WAR as your secure-deployment in the Keycloak subsystem.");
}
addJSONData(service.getJSON(deploymentName), warMetaData);
addJSONData(service.getJSON(deploymentUnit), warMetaData);
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
webMetaData = new JBossWebMetaData();
@@ -99,8 +97,8 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
webMetaData.setLoginConfig(loginConfig);
}
loginConfig.setAuthMethod("KEYCLOAK");
loginConfig.setRealmName(service.getRealmName(deploymentName));
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentName);
loginConfig.setRealmName(service.getRealmName(deploymentUnit));
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
}
private void addJSONData(String json, WarMetaData warMetaData) {
@@ -24,6 +24,9 @@ import java.util.HashMap;
import java.util.Map;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.web.common.WarMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
/**
* This service keeps track of the entire Keycloak management model so as to provide
@@ -153,13 +156,15 @@ public final class KeycloakAdapterConfigService {
return null;
}
public String getRealmName(String deploymentName) {
public String getRealmName(DeploymentUnit deploymentUnit) {
String deploymentName = preferredDeploymentName(deploymentUnit);
ModelNode deployment = this.secureDeployments.get(deploymentName);
return deployment.get(RealmDefinition.TAG_NAME).asString();
}
public String getJSON(String deploymentName) {
public String getJSON(DeploymentUnit deploymentUnit) {
String deploymentName = preferredDeploymentName(deploymentUnit);
ModelNode deployment = this.secureDeployments.get(deploymentName);
String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
ModelNode realm = this.realms.get(realmName);
@@ -183,9 +188,29 @@ public final class KeycloakAdapterConfigService {
}
}
public boolean isSecureDeployment(String deploymentName) {
public boolean isSecureDeployment(DeploymentUnit deploymentUnit) {
//log.info("********* CHECK KEYCLOAK DEPLOYMENT: deployments.size()" + deployments.size());
String deploymentName = preferredDeploymentName(deploymentUnit);
return this.secureDeployments.containsKey(deploymentName);
}
// KEYCLOAK-3273: prefer module name if available
private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return deploymentName;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return deploymentName;
}
String moduleName = webMetaData.getModuleName();
if (moduleName != null) return moduleName + ".war";
return deploymentName;
}
}
@@ -46,8 +46,7 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
if (!KeycloakAdapterConfigService.getInstance().isSecureDeployment(deploymentName)) {
if (!KeycloakAdapterConfigService.getInstance().isSecureDeployment(deploymentUnit)) {
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return;
@@ -78,8 +78,6 @@ public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
addCredential(addr, service, "secret", "secret1");
addCredential(addr, service, "jwt.client-keystore-file", "/tmp/foo.jks");
addCredential(addr, service, "jwt.token-timeout", "10");
System.out.println("Deployment: " + service.getJSON("foo"));
}
private void addCredential(PathAddress parent, KeycloakAdapterConfigService service, String key, String value) {
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -46,8 +46,7 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
// not sure if we need this yet, keeping here just in case
protected void addSecurityDomain(DeploymentUnit deploymentUnit, KeycloakAdapterConfigService service) {
String deploymentName = deploymentUnit.getName();
if (!service.isSecureDeployment(deploymentName)) {
if (!service.isSecureDeployment(deploymentUnit)) {
return;
}
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
@@ -67,10 +66,9 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
if (service.isSecureDeployment(deploymentName)) {
addKeycloakAuthData(phaseContext, deploymentName, service);
if (service.isSecureDeployment(deploymentUnit)) {
addKeycloakAuthData(phaseContext, service);
}
// FYI, Undertow Extension will find deployments that have auth-method set to KEYCLOAK
@@ -79,14 +77,14 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
// addSecurityDomain(deploymentUnit, service);
}
private void addKeycloakAuthData(DeploymentPhaseContext phaseContext, String deploymentName, KeycloakAdapterConfigService service) throws DeploymentUnitProcessingException {
private void addKeycloakAuthData(DeploymentPhaseContext phaseContext, KeycloakAdapterConfigService service) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
throw new DeploymentUnitProcessingException("WarMetaData not found for " + deploymentName + ". Make sure you have specified a WAR as your secure-deployment in the Keycloak subsystem.");
throw new DeploymentUnitProcessingException("WarMetaData not found for " + deploymentUnit.getName() + ". Make sure you have specified a WAR as your secure-deployment in the Keycloak subsystem.");
}
addJSONData(service.getJSON(deploymentName), warMetaData);
addJSONData(service.getJSON(deploymentUnit), warMetaData);
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
webMetaData = new JBossWebMetaData();
@@ -99,8 +97,8 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
webMetaData.setLoginConfig(loginConfig);
}
loginConfig.setAuthMethod("KEYCLOAK");
loginConfig.setRealmName(service.getRealmName(deploymentName));
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentName);
loginConfig.setRealmName(service.getRealmName(deploymentUnit));
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
}
private void addJSONData(String json, WarMetaData warMetaData) {
@@ -24,6 +24,9 @@ import java.util.HashMap;
import java.util.Map;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.web.common.WarMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
/**
* This service keeps track of the entire Keycloak management model so as to provide
@@ -153,13 +156,15 @@ public final class KeycloakAdapterConfigService {
return null;
}
public String getRealmName(String deploymentName) {
public String getRealmName(DeploymentUnit deploymentUnit) {
String deploymentName = preferredDeploymentName(deploymentUnit);
ModelNode deployment = this.secureDeployments.get(deploymentName);
return deployment.get(RealmDefinition.TAG_NAME).asString();
}
public String getJSON(String deploymentName) {
public String getJSON(DeploymentUnit deploymentUnit) {
String deploymentName = preferredDeploymentName(deploymentUnit);
ModelNode deployment = this.secureDeployments.get(deploymentName);
String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
ModelNode realm = this.realms.get(realmName);
@@ -183,9 +188,29 @@ public final class KeycloakAdapterConfigService {
}
}
public boolean isSecureDeployment(String deploymentName) {
public boolean isSecureDeployment(DeploymentUnit deploymentUnit) {
//log.info("********* CHECK KEYCLOAK DEPLOYMENT: deployments.size()" + deployments.size());
String deploymentName = preferredDeploymentName(deploymentUnit);
return this.secureDeployments.containsKey(deploymentName);
}
// KEYCLOAK-3273: prefer module name if available
private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return deploymentName;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return deploymentName;
}
String moduleName = webMetaData.getModuleName();
if (moduleName != null) return moduleName + ".war";
return deploymentName;
}
}
@@ -45,9 +45,7 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
if (!KeycloakAdapterConfigService.getInstance().isSecureDeployment(deploymentName)) {
if (!KeycloakAdapterConfigService.getInstance().isSecureDeployment(deploymentUnit)) {
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return;
@@ -67,7 +65,7 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
addCommonModules(moduleSpecification, moduleLoader);
addPlatformSpecificModules(moduleSpecification, moduleLoader);
}
private void addCommonModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader) {
// ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false));
@@ -78,8 +78,6 @@ public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
addCredential(addr, service, "secret", "secret1");
addCredential(addr, service, "jwt.client-keystore-file", "/tmp/foo.jks");
addCredential(addr, service, "jwt.token-timeout", "10");
System.out.println("Deployment: " + service.getJSON("foo"));
}
private void addCredential(PathAddress parent, KeycloakAdapterConfigService service, String key, String value) {
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Keycloak Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML EAP Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -16,8 +16,11 @@
*/
package org.keycloak.subsystem.saml.as7;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.web.deployment.WarMetaData;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
@@ -46,7 +49,8 @@ public class Configuration {
return keymodel.get(key);
}
public ModelNode getSecureDeployment(String name) {
public ModelNode getSecureDeployment(DeploymentUnit deploymentUnit) {
String name = preferredDeploymentName(deploymentUnit);
ModelNode secureDeployment = config.get("subsystem").get("keycloak-saml").get(Constants.Model.SECURE_DEPLOYMENT);
if (secureDeployment.hasDefined(name)) {
return secureDeployment.get(name);
@@ -54,7 +58,26 @@ public class Configuration {
return null;
}
public boolean isSecureDeployment(String name) {
return getSecureDeployment(name) != null;
public boolean isSecureDeployment(DeploymentUnit deploymentUnit) {
return getSecureDeployment(deploymentUnit) != null;
}
// KEYCLOAK-3273: prefer module name if available
private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return deploymentName;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return deploymentName;
}
String moduleName = webMetaData.getModuleName();
if (moduleName != null) return moduleName + ".war";
return deploymentName;
}
}
@@ -51,7 +51,6 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
@@ -69,30 +68,30 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
try {
boolean webRequiresKC = loginConfig != null && "KEYCLOAK-SAML".equalsIgnoreCase(loginConfig.getAuthMethod());
boolean hasSubsystemConfig = Configuration.INSTANCE.isSecureDeployment(deploymentName);
boolean hasSubsystemConfig = Configuration.INSTANCE.isSecureDeployment(deploymentUnit);
if (hasSubsystemConfig || webRequiresKC) {
log.debug("Setting up KEYCLOAK-SAML auth method for WAR: " + deploymentName);
log.debug("Setting up KEYCLOAK-SAML auth method for WAR: " + deploymentUnit.getName());
// if secure-deployment configuration exists for web app, we force KEYCLOAK-SAML auth method on it
if (hasSubsystemConfig) {
addXMLData(getXML(deploymentName), warMetaData);
addXMLData(getXML(deploymentUnit), warMetaData);
if (loginConfig != null) {
loginConfig.setAuthMethod("KEYCLOAK-SAML");
//loginConfig.setRealmName(service.getRealmName(deploymentName));
} else {
log.warn("Failed to set up KEYCLOAK-SAML auth method for WAR: " + deploymentName + " (loginConfig == null)");
log.warn("Failed to set up KEYCLOAK-SAML auth method for WAR: " + deploymentUnit.getName() + " (loginConfig == null)");
}
}
addValve(webMetaData);
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentName);
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
}
} catch (Exception e) {
throw new DeploymentUnitProcessingException("Failed to configure KeycloakSamlExtension from subsystem model", e);
}
}
private String getXML(String deploymentName) throws XMLStreamException {
ModelNode node = Configuration.INSTANCE.getSecureDeployment(deploymentName);
private String getXML(DeploymentUnit deploymentUnit) throws XMLStreamException {
ModelNode node = Configuration.INSTANCE.getSecureDeployment(deploymentUnit);
if (node != null) {
KeycloakSubsystemParser writer = new KeycloakSubsystemParser();
ByteArrayOutputStream output = new ByteArrayOutputStream();
@@ -46,8 +46,7 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
if (Configuration.INSTANCE.getSecureDeployment(deploymentName) == null) {
if (Configuration.INSTANCE.getSecureDeployment(deploymentUnit) == null) {
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return;
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -370,13 +370,13 @@ public abstract class AbstractSamlAuthenticator extends LoginAuthenticator {
Authentication authentication = request.getAuthentication();
if (!(authentication instanceof KeycloakAuthentication)) {
UserIdentity userIdentity = createIdentity(samlSession);
authentication = createAuthentication(userIdentity);
authentication = createAuthentication(userIdentity, request);
request.setAuthentication(authentication);
}
return authentication;
}
public abstract Authentication createAuthentication(UserIdentity userIdentity);
public abstract Authentication createAuthentication(UserIdentity userIdentity, Request request);
public static abstract class KeycloakAuthentication extends UserAuthentication {
public KeycloakAuthentication(String method, UserIdentity userIdentity) {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -17,6 +17,7 @@
package org.keycloak.adapters.saml.jetty;
import org.bouncycastle.cert.ocsp.Req;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.Request;
@@ -48,7 +49,7 @@ public class KeycloakSamlAuthenticator extends AbstractSamlAuthenticator {
}
@Override
public Authentication createAuthentication(UserIdentity userIdentity) {
public Authentication createAuthentication(UserIdentity userIdentity, Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -17,6 +17,7 @@
package org.keycloak.adapters.saml.jetty;
import org.bouncycastle.cert.ocsp.Req;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
@@ -50,7 +51,7 @@ public class KeycloakSamlAuthenticator extends AbstractSamlAuthenticator {
}
@Override
public Authentication createAuthentication(UserIdentity userIdentity) {
public Authentication createAuthentication(UserIdentity userIdentity, Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -45,7 +45,7 @@ public class KeycloakSamlAuthenticator extends AbstractSamlAuthenticator {
}
@Override
public Authentication createAuthentication(UserIdentity userIdentity) {
public Authentication createAuthentication(UserIdentity userIdentity, Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
+162
View File
@@ -0,0 +1,162 @@
<?xml version="1.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.
-->
<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>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-saml-jetty93-adapter</artifactId>
<name>Keycloak Jetty 9.3.x SAML Integration</name>
<properties>
<jetty9.version>9.3.9.v20160517</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.*
</keycloak.osgi.export>
<keycloak.osgi.import>
org.eclipse.jetty.*;resolution:=optional,
javax.servlet.*;version="[3.0,4)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<description />
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-jetty-adapter-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>${jetty9.version}</version>
<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>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<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>
</build>
</project>
@@ -0,0 +1,44 @@
/*
* 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.saml.jetty;
import org.eclipse.jetty.server.Request;
import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.spi.AdapterSessionStore;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.spi.SessionIdMapper;
import javax.servlet.http.HttpSession;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class Jetty9SamlSessionStore extends JettySamlSessionStore {
public Jetty9SamlSessionStore(Request request, AdapterSessionStore sessionStore, HttpFacade facade, SessionIdMapper idMapper, JettyUserSessionManagement sessionManagement, SamlDeployment deployment) {
super(request, sessionStore, facade, idMapper, sessionManagement, deployment);
}
@Override
protected String changeSessionId(HttpSession session) {
Request request = this.request;
if (!deployment.turnOffChangeSessionIdOnLogin()) return request.changeSessionId();
else return session.getId();
}
}
@@ -0,0 +1,112 @@
/*
* 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.saml.jetty;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.MultiMap;
import org.keycloak.adapters.spi.AdapterSessionStore;
import org.keycloak.adapters.jetty.spi.JettyHttpFacade;
import org.keycloak.common.util.MultivaluedHashMap;
import javax.servlet.http.HttpSession;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class JettyAdapterSessionStore implements AdapterSessionStore {
public static final String CACHED_FORM_PARAMETERS = "__CACHED_FORM_PARAMETERS";
protected Request myRequest;
public JettyAdapterSessionStore(Request request) {
this.myRequest = request; // for IDE/compilation purposes
}
protected MultiMap<String> extractFormParameters(Request base_request) {
MultiMap<String> formParameters = new MultiMap<String>();
base_request.extractFormParameters(formParameters);
return formParameters;
}
protected void restoreFormParameters(MultiMap<String> j_post, Request base_request) {
base_request.setContentParameters(j_post);
}
public boolean restoreRequest() {
HttpSession session = myRequest.getSession(false);
if (session == null) return false;
synchronized (session) {
String j_uri = (String) session.getAttribute(FormAuthenticator.__J_URI);
if (j_uri != null) {
// check if the request is for the same url as the original and restore
// params if it was a post
StringBuffer buf = myRequest.getRequestURL();
if (myRequest.getQueryString() != null)
buf.append("?").append(myRequest.getQueryString());
if (j_uri.equals(buf.toString())) {
String method = (String)session.getAttribute(JettyHttpFacade.__J_METHOD);
myRequest.setMethod(method);
MultivaluedHashMap<String, String> j_post = (MultivaluedHashMap<String, String>) session.getAttribute(CACHED_FORM_PARAMETERS);
if (j_post != null) {
myRequest.setContentType("application/x-www-form-urlencoded");
MultiMap<String> map = new MultiMap<String>();
for (String key : j_post.keySet()) {
for (String val : j_post.getList(key)) {
map.add(key, val);
}
}
restoreFormParameters(map, myRequest);
}
session.removeAttribute(FormAuthenticator.__J_URI);
session.removeAttribute(JettyHttpFacade.__J_METHOD);
session.removeAttribute(FormAuthenticator.__J_POST);
}
return true;
}
}
return false;
}
public void saveRequest() {
// remember the current URI
HttpSession session = myRequest.getSession();
synchronized (session) {
// But only if it is not set already, or we save every uri that leads to a login form redirect
if (session.getAttribute(FormAuthenticator.__J_URI) == null) {
StringBuffer buf = myRequest.getRequestURL();
if (myRequest.getQueryString() != null)
buf.append("?").append(myRequest.getQueryString());
session.setAttribute(FormAuthenticator.__J_URI, buf.toString());
session.setAttribute(JettyHttpFacade.__J_METHOD, myRequest.getMethod());
if ("application/x-www-form-urlencoded".equals(myRequest.getContentType()) && "POST".equalsIgnoreCase(myRequest.getMethod())) {
MultiMap<String> formParameters = extractFormParameters(myRequest);
MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
for (String key : formParameters.keySet()) {
for (Object value : formParameters.getValues(key)) {
map.add(key, (String) value);
}
}
session.setAttribute(CACHED_FORM_PARAMETERS, map);
}
}
}
}
}
@@ -0,0 +1,68 @@
/*
* 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.saml.jetty;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
import org.keycloak.adapters.spi.AdapterSessionStore;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.spi.HttpFacade;
import javax.servlet.ServletRequest;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class KeycloakSamlAuthenticator extends AbstractSamlAuthenticator {
public KeycloakSamlAuthenticator() {
super();
}
@Override
protected Request resolveRequest(ServletRequest req) {
return Request.getBaseRequest(req);
}
@Override
public Authentication createAuthentication(UserIdentity userIdentity, final Request request) {
return new KeycloakAuthentication(getAuthMethod(), userIdentity) {
@Override
public void logout() {
logoutCurrent(request);
}
};
}
@Override
public AdapterSessionStore createSessionTokenStore(Request request, SamlDeployment resolvedDeployment) {
return new JettyAdapterSessionStore(request);
}
@Override
protected JettySamlSessionStore createJettySamlSessionStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
JettySamlSessionStore store;
store = new Jetty9SamlSessionStore(request, createSessionTokenStore(request, resolvedDeployment), facade, idMapper, new JettyUserSessionManagement(request.getSessionManager()), resolvedDeployment);
return store;
}
}
+2 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Jetty Integration</name>
@@ -35,5 +35,6 @@
<module>jetty8.1</module>
<module>jetty9.1</module>
<module>jetty9.2</module>
<module>jetty9.3</module>
</modules>
</project>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Client Adapter Modules</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Tomcat Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Wildfly Integration</name>
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>2.0.0.CR1</version>
<version>2.2.0.Test1</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -16,8 +16,11 @@
*/
package org.keycloak.subsystem.adapter.saml.extension;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.web.common.WarMetaData;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
@@ -46,11 +49,31 @@ public class Configuration {
return keymodel.get(key);
}
public ModelNode getSecureDeployment(String name) {
public ModelNode getSecureDeployment(DeploymentUnit deploymentUnit) {
String name = preferredDeploymentName(deploymentUnit);
ModelNode secureDeployment = config.get("subsystem").get("keycloak-saml").get(Constants.Model.SECURE_DEPLOYMENT);
if (secureDeployment.hasDefined(name)) {
return secureDeployment.get(name);
}
return null;
}
// KEYCLOAK-3273: prefer module name if available
private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return deploymentName;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return deploymentName;
}
String moduleName = webMetaData.getModuleName();
if (moduleName != null) return moduleName + ".war";
return deploymentName;
}
}
@@ -49,21 +49,20 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
String deploymentName = deploymentUnit.getName();
if (Configuration.INSTANCE.getSecureDeployment(deploymentName) != null) {
addKeycloakSamlAuthData(phaseContext, deploymentName);
if (Configuration.INSTANCE.getSecureDeployment(deploymentUnit) != null) {
addKeycloakSamlAuthData(phaseContext);
}
}
private void addKeycloakSamlAuthData(DeploymentPhaseContext phaseContext, String deploymentName) throws DeploymentUnitProcessingException {
private void addKeycloakSamlAuthData(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
throw new DeploymentUnitProcessingException("WarMetaData not found for " + deploymentName + ". Make sure you have specified a WAR as your secure-deployment in the Keycloak subsystem.");
throw new DeploymentUnitProcessingException("WarMetaData not found for " + deploymentUnit.getName() + ". Make sure you have specified a WAR as your secure-deployment in the Keycloak subsystem.");
}
try {
addXMLData(getXML(deploymentName), warMetaData);
addXMLData(getXML(deploymentUnit), warMetaData);
} catch (Exception e) {
throw new DeploymentUnitProcessingException("Failed to configure KeycloakSamlExtension from subsystem model", e);
}
@@ -80,11 +79,11 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
}
loginConfig.setAuthMethod("KEYCLOAK-SAML");
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentName);
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
}
private String getXML(String deploymentName) throws XMLStreamException {
ModelNode node = Configuration.INSTANCE.getSecureDeployment(deploymentName);
private String getXML(DeploymentUnit deploymentUnit) throws XMLStreamException {
ModelNode node = Configuration.INSTANCE.getSecureDeployment(deploymentUnit);
if (node != null) {
KeycloakSubsystemParser writer = new KeycloakSubsystemParser();
ByteArrayOutputStream output = new ByteArrayOutputStream();
Loaded 100 of 1291 files, more files were not shown because too many files have changed in this diff. Show more