Compare commits
583
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b0693671c | ||
|
|
aea45e46da | ||
|
|
243ce2fc65 | ||
|
|
1200955643 | ||
|
|
1ad464c681 | ||
|
|
88a37067ad | ||
|
|
c6dab26769 | ||
|
|
9bceec9ef5 | ||
|
|
d1e491d57d | ||
|
|
7cfa1cc368 | ||
|
|
b79ee3c7f3 | ||
|
|
6085b21c36 | ||
|
|
b24d2e064a | ||
|
|
4fcb22c540 | ||
|
|
07689c9537 | ||
|
|
e329c7801d | ||
|
|
2de2df3a41 | ||
|
|
194a63cc71 | ||
|
|
6392405413 | ||
|
|
a18a4477e0 | ||
|
|
94ffeda62a | ||
|
|
264e81efb2 | ||
|
|
cea52a6db9 | ||
|
|
b8c7fcf587 | ||
|
|
04228791f3 | ||
|
|
04c4110f76 | ||
|
|
13e92cdb35 | ||
|
|
bd271b2367 | ||
|
|
9fea9f6fe0 | ||
|
|
8717cd0090 | ||
|
|
e487db349c | ||
|
|
29c0fe564c | ||
|
|
b2d1a1a17f | ||
|
|
4868918f94 | ||
|
|
15d0a116ac | ||
|
|
b5212d58ec | ||
|
|
cf1c577840 | ||
|
|
57127f39d0 | ||
|
|
052534de82 | ||
|
|
99e1eac094 | ||
|
|
7410bdb31c | ||
|
|
cc9c8d8ca1 | ||
|
|
f55d18189c | ||
|
|
6097a0c9e1 | ||
|
|
39f8311484 | ||
|
|
fe8e437e74 | ||
|
|
1373708dea | ||
|
|
34605ee3c6 | ||
|
|
3444fb62f1 | ||
|
|
cc788cf44e | ||
|
|
13e4f607ad | ||
|
|
5da491c270 | ||
|
|
99fcc51019 | ||
|
|
350b9550c3 | ||
|
|
f289b281a0 | ||
|
|
9cd860d698 | ||
|
|
536b88790e | ||
|
|
73d3e8afd9 | ||
|
|
aef6bb9789 | ||
|
|
b4f56e92f3 | ||
|
|
8daa2c3703 | ||
|
|
c7f2a0ffdd | ||
|
|
c19360c6f2 | ||
|
|
71da6ab4e9 | ||
|
|
9f33685785 | ||
|
|
df4f1e7129 | ||
|
|
212182ee34 | ||
|
|
86988833e9 | ||
|
|
5a0504b5d9 | ||
|
|
e364680792 | ||
|
|
ef46070410 | ||
|
|
843b4b470b | ||
|
|
dcf6da2a51 | ||
|
|
3d29816ea3 | ||
|
|
2eeb2f52c5 | ||
|
|
32827be8b1 | ||
|
|
23c1f513e7 | ||
|
|
ae40bfb96e | ||
|
|
547f5ecfa6 | ||
|
|
1913f801b9 | ||
|
|
5842f7c837 | ||
|
|
1ef2eb6110 | ||
|
|
178625d3f2 | ||
|
|
9fb46a7b1c | ||
|
|
bea8de8a1a | ||
|
|
d68f6bbc42 | ||
|
|
7de999a7f9 | ||
|
|
ffb688b393 | ||
|
|
6aee6b0c46 | ||
|
|
aa78c9eaf5 | ||
|
|
02eda8943c | ||
|
|
2f7143e72f | ||
|
|
9ad14d991c | ||
|
|
59a6c9f13f | ||
|
|
ae838c12db | ||
|
|
ac9268bd48 | ||
|
|
0b58bebc90 | ||
|
|
93157e49d5 | ||
|
|
3d9f11168e | ||
|
|
c4cce147e2 | ||
|
|
3a2927e12e | ||
|
|
901ff9c3d5 | ||
|
|
8de3b26126 | ||
|
|
1e51ade620 | ||
|
|
89e6f93fa4 | ||
|
|
41630d6962 | ||
|
|
efcd0346fc | ||
|
|
f13deab812 | ||
|
|
f28b3c1269 | ||
|
|
5e1ec459e5 | ||
|
|
9a6f202c46 | ||
|
|
e11957ecf3 | ||
|
|
23c8809598 | ||
|
|
7098daaf72 | ||
|
|
811d532b48 | ||
|
|
7ceef826ac | ||
|
|
fe294dcb58 | ||
|
|
8441bda3da | ||
|
|
227900f288 | ||
|
|
345e0da76d | ||
|
|
139e12fa5f | ||
|
|
4df70c517d | ||
|
|
cbd6f7e1d0 | ||
|
|
426e55664f | ||
|
|
ab0a669662 | ||
|
|
5c03b20bd1 | ||
|
|
7eeebff874 | ||
|
|
a0a7372160 | ||
|
|
9e697d033f | ||
|
|
2ec3eaf68a | ||
|
|
e047872c25 | ||
|
|
f1173f8022 | ||
|
|
420286c103 | ||
|
|
1495f4881e | ||
|
|
452611242c | ||
|
|
d075172fd2 | ||
|
|
c32620b718 | ||
|
|
37b8d1ad10 | ||
|
|
be4f2aff63 | ||
|
|
14669dfbc5 | ||
|
|
5cec0d4bef | ||
|
|
dd74b57d13 | ||
|
|
a09bc6520f | ||
|
|
8a02ef1859 | ||
|
|
9ccd05ff54 | ||
|
|
42a8a0eb15 | ||
|
|
fb374ad99d | ||
|
|
a4f46d3310 | ||
|
|
5bc134ea7b | ||
|
|
28c289cfb8 | ||
|
|
0b5b27ea3a | ||
|
|
f1dbe3c9e2 | ||
|
|
9fb3201c8b | ||
|
|
96f8f99313 | ||
|
|
86c49f5e89 | ||
|
|
017dbb1d9f | ||
|
|
60eda52aba | ||
|
|
377fbced4a | ||
|
|
fb6a8da863 | ||
|
|
0cb5ba0f6e | ||
|
|
eb1b011989 | ||
|
|
72691b2e74 | ||
|
|
f9eeecf836 | ||
|
|
61e7936d79 | ||
|
|
4934fe5a8e | ||
|
|
2035398ef4 | ||
|
|
56160ef12b | ||
|
|
b0644ce18c | ||
|
|
cf5c3aa53b | ||
|
|
f9e87516ae | ||
|
|
ed1a30f67b | ||
|
|
77293b85e0 | ||
|
|
ad9210a7a7 | ||
|
|
15af61a7cc | ||
|
|
2d1417d72b | ||
|
|
41404424ac | ||
|
|
a2a531a747 | ||
|
|
a76c52ef84 | ||
|
|
ed75ef900a | ||
|
|
862502f3ed | ||
|
|
2b57b8371b | ||
|
|
4044b39ab7 | ||
|
|
e0bc56960b | ||
|
|
180352aa09 | ||
|
|
09a61f4706 | ||
|
|
5150251141 | ||
|
|
732d56b0c0 | ||
|
|
08aeb13804 | ||
|
|
1f0469894a | ||
|
|
8a0859fcba | ||
|
|
5212f57b5b | ||
|
|
6ac1301dc2 | ||
|
|
1eb0cde74f | ||
|
|
32f8fd4b9f | ||
|
|
90a5272860 | ||
|
|
40a8f0a243 | ||
|
|
f2ee9df600 | ||
|
|
9ab44b79ce | ||
|
|
50c11e105b | ||
|
|
b7c98ed433 | ||
|
|
d217b23719 | ||
|
|
171c6ab88f | ||
|
|
45411b1199 | ||
|
|
e0bfb13ed9 | ||
|
|
902332c5ae | ||
|
|
08d7211a93 | ||
|
|
1c0e204f50 | ||
|
|
d6e620a266 | ||
|
|
54b3d3abec | ||
|
|
31ed69a970 | ||
|
|
b1d9fd670a | ||
|
|
bf58511d81 | ||
|
|
b5317f3485 | ||
|
|
e805ffd945 | ||
|
|
40b5731198 | ||
|
|
ebd3d522e2 | ||
|
|
04179c5681 | ||
|
|
6c8ebdb456 | ||
|
|
85446c3b46 | ||
|
|
df7a68b709 | ||
|
|
1c65fd86ef | ||
|
|
bb00524f94 | ||
|
|
7f9e6bbf60 | ||
|
|
2ba21485f9 | ||
|
|
c998198aac | ||
|
|
3e8d4e4eb6 | ||
|
|
b15918b745 | ||
|
|
d2b7f18480 | ||
|
|
663b99d884 | ||
|
|
e3e18913f1 | ||
|
|
f98c454775 | ||
|
|
9c2944c090 | ||
|
|
66eb9095c1 | ||
|
|
e7c73518b3 | ||
|
|
172007f59c | ||
|
|
e262f8fb63 | ||
|
|
b6b3c04400 | ||
|
|
f97a3e0745 | ||
|
|
f9bccc83f9 | ||
|
|
761714036e | ||
|
|
d365d9d784 | ||
|
|
96f2985e86 | ||
|
|
7bad8e6ff3 | ||
|
|
55d53214a1 | ||
|
|
aee8398ee8 | ||
|
|
7cd63f2f8b | ||
|
|
8b5aafc4b4 | ||
|
|
f6323d94ec | ||
|
|
eb7ad07e31 | ||
|
|
7c7f87d201 | ||
|
|
18b94a2153 | ||
|
|
0b3e867362 | ||
|
|
3498273601 | ||
|
|
01a8c13ac0 | ||
|
|
194ba6009f | ||
|
|
c9c8acd029 | ||
|
|
7e2c06e301 | ||
|
|
40591cff25 | ||
|
|
5cf5168770 | ||
|
|
cb57dbf58a | ||
|
|
4b6df5d489 | ||
|
|
b6d29ccd30 | ||
|
|
16fb1e2078 | ||
|
|
ac00f7fee2 | ||
|
|
faeff029fa | ||
|
|
c6363aa146 | ||
|
|
2c70e53df6 | ||
|
|
81ab6aeeed | ||
|
|
d1a528eb07 | ||
|
|
c9c9f05e29 | ||
|
|
4e3e9ad5d4 | ||
|
|
3bd3d0285d | ||
|
|
343e678f09 | ||
|
|
b8adfcad87 | ||
|
|
ca3691e650 | ||
|
|
ad11d6e76b | ||
|
|
3e3216fb23 | ||
|
|
93cec9b3ee | ||
|
|
20c5c6b60c | ||
|
|
f29bb7d501 | ||
|
|
c3d9859c6e | ||
|
|
3b3b219a86 | ||
|
|
3f2e9c3592 | ||
|
|
787a3f8fcc | ||
|
|
a4cbf130b4 | ||
|
|
1c0e23db66 | ||
|
|
f33a1e2143 | ||
|
|
63ca9b2fe8 | ||
|
|
34f82fa1b1 | ||
|
|
5453bec1bf | ||
|
|
e65dd4fbc3 | ||
|
|
7b115b4b44 | ||
|
|
4d64f0e160 | ||
|
|
7453e96f5c | ||
|
|
9be9d3f580 | ||
|
|
7d51df4eed | ||
|
|
74fd904bc4 | ||
|
|
3c2a12d019 | ||
|
|
56f9aa41d0 | ||
|
|
e5d744f7d5 | ||
|
|
394676222f | ||
|
|
5464655bc2 | ||
|
|
768c3eb9a7 | ||
|
|
e316037910 | ||
|
|
97a08a1d99 | ||
|
|
db4420e10d | ||
|
|
480d4e6f4f | ||
|
|
0b701b3cf9 | ||
|
|
40216b5e7d | ||
|
|
b1fe07ac3d | ||
|
|
642de06fb5 | ||
|
|
7ad028fcb1 | ||
|
|
76385157fc | ||
|
|
c11f65720b | ||
|
|
5006fe2292 | ||
|
|
90fdb4889c | ||
|
|
c17a57d76c | ||
|
|
efcb749771 | ||
|
|
8c99a13387 | ||
|
|
79c1650c15 | ||
|
|
63ddabe5fb | ||
|
|
5448403345 | ||
|
|
5996149a8d | ||
|
|
62029e8a33 | ||
|
|
588e1711dd | ||
|
|
35c4a379ad | ||
|
|
cf62715499 | ||
|
|
1bfdff0e25 | ||
|
|
ba14b9d942 | ||
|
|
10fc7302eb | ||
|
|
3bea8f4adb | ||
|
|
24a36e6848 | ||
|
|
5d070cbf22 | ||
|
|
5e660977aa | ||
|
|
1f0600044a | ||
|
|
d3e3990d77 | ||
|
|
4a80f1e913 | ||
|
|
0550bdb467 | ||
|
|
5f07fa8057 | ||
|
|
10064fdac9 | ||
|
|
e7f6c780e2 | ||
|
|
e03b72df00 | ||
|
|
7d8b392fd9 | ||
|
|
afa8dc735d | ||
|
|
d49a74b927 | ||
|
|
ae36b3c832 | ||
|
|
e0c62e25b2 | ||
|
|
081958e282 | ||
|
|
379d5e3228 | ||
|
|
9b18601102 | ||
|
|
7868152ffe | ||
|
|
223cc1fb50 | ||
|
|
6ae9d19843 | ||
|
|
cbe4ff324c | ||
|
|
b8c06dd560 | ||
|
|
31d2cde6e5 | ||
|
|
75e2b404c8 | ||
|
|
d163dad3fe | ||
|
|
7271fdaaaa | ||
|
|
03fbb3c853 | ||
|
|
68c8bfa0e1 | ||
|
|
f34b47d29c | ||
|
|
a0b54ebedc | ||
|
|
ddb201db6c | ||
|
|
4069be3ff6 | ||
|
|
15f23eb045 | ||
|
|
77d17de14d | ||
|
|
bab08bf8f0 | ||
|
|
0d110ceb30 | ||
|
|
9cd3034762 | ||
|
|
ba51640c61 | ||
|
|
287593d75f | ||
|
|
3826e933c1 | ||
|
|
6b1020ec34 | ||
|
|
c8b22e71f0 | ||
|
|
41a5598103 | ||
|
|
fc92639d3f | ||
|
|
6587cd2478 | ||
|
|
e55c2ae554 | ||
|
|
693d6c0e5d | ||
|
|
952c1decf0 | ||
|
|
f3dbacabf8 | ||
|
|
819105c3aa | ||
|
|
06affc0700 | ||
|
|
f03d79c7d3 | ||
|
|
b52936bc5b | ||
|
|
3c4114091f | ||
|
|
d354aa1f62 | ||
|
|
45fd114143 | ||
|
|
32da5fea0a | ||
|
|
32c23c2410 | ||
|
|
802085f158 | ||
|
|
773c88cc04 | ||
|
|
197f51e50f | ||
|
|
1c66ce7dd7 | ||
|
|
8610a02d72 | ||
|
|
d7df86d6d0 | ||
|
|
e3d0f8f6e5 | ||
|
|
e8f2527fcd | ||
|
|
305dcb2b1e | ||
|
|
0ab352706b | ||
|
|
eac0bb4b37 | ||
|
|
3bc721720f | ||
|
|
54758b800b | ||
|
|
6cd6edce64 | ||
|
|
69a1d4d192 | ||
|
|
5d4864b82d | ||
|
|
3840aed5f7 | ||
|
|
6a629aec0c | ||
|
|
8b4bb72fb3 | ||
|
|
88d08c4f38 | ||
|
|
e3f5df3894 | ||
|
|
cfbd7d469f | ||
|
|
8fd7091068 | ||
|
|
9c97245c46 | ||
|
|
257aba4331 | ||
|
|
672e1b3575 | ||
|
|
ce50b0ed29 | ||
|
|
e88af874ca | ||
|
|
aed54439c2 | ||
|
|
c8c6e36fd9 | ||
|
|
e6ace84101 | ||
|
|
815b5e5f34 | ||
|
|
c149358028 | ||
|
|
b1265f6d70 | ||
|
|
a09e78873e | ||
|
|
17d8394ab6 | ||
|
|
e6a20aa44b | ||
|
|
458ca8a7ee | ||
|
|
b56e23eded | ||
|
|
d02c9c2150 | ||
|
|
cccb532a21 | ||
|
|
5c2bf7c822 | ||
|
|
e8758a77fb | ||
|
|
b2f0acfe26 | ||
|
|
8842d88058 | ||
|
|
739178d840 | ||
|
|
2454b3b644 | ||
|
|
87b243ed59 | ||
|
|
cec6f5db14 | ||
|
|
e7dd49b453 | ||
|
|
6fdc470b0b | ||
|
|
695aa7bec9 | ||
|
|
3952dba094 | ||
|
|
209f8155d1 | ||
|
|
8621733e17 | ||
|
|
621301862c | ||
|
|
fd4c5a90ed | ||
|
|
bfec073457 | ||
|
|
dc6e869c64 | ||
|
|
bed592460d | ||
|
|
46d3555798 | ||
|
|
74967737ee | ||
|
|
a347cb591d | ||
|
|
1ae60ef8a7 | ||
|
|
f9db687385 | ||
|
|
a38544796f | ||
|
|
5ecc8d1c71 | ||
|
|
c9cf7f6564 | ||
|
|
ba406d5747 | ||
|
|
c72ceadfce | ||
|
|
1e7f1b1e54 | ||
|
|
7c0f6f6e6e | ||
|
|
3f32cb154b | ||
|
|
6fa504489f | ||
|
|
433f373f60 | ||
|
|
b771b84f56 | ||
|
|
45abaec86e | ||
|
|
d0a96d463d | ||
|
|
12f1aedcd1 | ||
|
|
f0874bf585 | ||
|
|
1a749dc7b7 | ||
|
|
ec49d10007 | ||
|
|
294dc6fbd0 | ||
|
|
9e50a45b4c | ||
|
|
72ffb9dbb9 | ||
|
|
a677ab64e3 | ||
|
|
b33afcd47c | ||
|
|
659892edcb | ||
|
|
803fde6c1d | ||
|
|
83063a5740 | ||
|
|
7efa3a3ddf | ||
|
|
c1d93e251d | ||
|
|
8f3256675a | ||
|
|
9711ac2ecb | ||
|
|
833c56e17b | ||
|
|
9bb59c0f94 | ||
|
|
629ec6383e | ||
|
|
a6b6ecf4ba | ||
|
|
e5ce080fd3 | ||
|
|
80c4b2aa31 | ||
|
|
0b8f9edb9e | ||
|
|
63458a7de7 | ||
|
|
f6a080729a | ||
|
|
1dacddb7e3 | ||
|
|
334aa37b7f | ||
|
|
725f42e185 | ||
|
|
69ce1e05f0 | ||
|
|
8d3136188d | ||
|
|
cb4f856ab6 | ||
|
|
65b269cd54 | ||
|
|
df93244373 | ||
|
|
a8de125e26 | ||
|
|
7db06b8afb | ||
|
|
7c6032cc84 | ||
|
|
939da455d7 | ||
|
|
817dbce391 | ||
|
|
0f447fadd4 | ||
|
|
79825dfa1d | ||
|
|
b640e9fe39 | ||
|
|
9dd4cbb40e | ||
|
|
82423db239 | ||
|
|
0262b64062 | ||
|
|
bd920b8ba9 | ||
|
|
57da86c598 | ||
|
|
cd92cc504b | ||
|
|
e82e584b81 | ||
|
|
ccbd8e8c70 | ||
|
|
e396261399 | ||
|
|
aae368f1e7 | ||
|
|
5ac4a852e1 | ||
|
|
fad33bc50f | ||
|
|
d5925b8ccf | ||
|
|
5e97a46afc | ||
|
|
8ee2134e05 | ||
|
|
2da9986717 | ||
|
|
c3b6b07e3a | ||
|
|
045d6ef1d0 | ||
|
|
ecba291ea0 | ||
|
|
328ab1cc27 | ||
|
|
884f84d5ed | ||
|
|
b2d48c86a6 | ||
|
|
3c5a0a3394 | ||
|
|
6ec82865d3 | ||
|
|
dab2225a39 | ||
|
|
0e93603aee | ||
|
|
d44f347b08 | ||
|
|
99f12ff720 | ||
|
|
a3cb3730b4 | ||
|
|
2cca3bf570 | ||
|
|
33cd261d83 | ||
|
|
e515d7bbbe | ||
|
|
0c05dc093f | ||
|
|
68701900d8 | ||
|
|
ee18d062ab | ||
|
|
695213dd31 | ||
|
|
50fc083d97 | ||
|
|
798fd84698 | ||
|
|
19575b2c8f | ||
|
|
a52f7f9baa | ||
|
|
fc84ffbd65 | ||
|
|
27e5d9672a | ||
|
|
8f31425daf | ||
|
|
7c4591617b | ||
|
|
c21ab943bb | ||
|
|
d8c8afe070 | ||
|
|
d1a35a5acc | ||
|
|
2d4cda7eda | ||
|
|
5e731d9557 | ||
|
|
6df7a80352 | ||
|
|
d261bbef88 | ||
|
|
4fa903a02f | ||
|
|
f0fd9e6137 | ||
|
|
a45ffce118 | ||
|
|
c558e7e0b1 | ||
|
|
bfec70481b | ||
|
|
a7c8fe4375 | ||
|
|
da52a5c9cf | ||
|
|
639cf1e038 | ||
|
|
76bfbad2c4 | ||
|
|
cca352fa9f | ||
|
|
7043ecc21b | ||
|
|
c384b8a81f | ||
|
|
747738c0fc | ||
|
|
8fc5b00d91 | ||
|
|
80b071024f | ||
|
|
3efd103712 | ||
|
|
3035cbc5db | ||
|
|
facdd586a3 | ||
|
|
a119a46495 | ||
|
|
0d3a50411e | ||
|
|
3bed84d712 | ||
|
|
0485f5c43d |
No files matched your search
@@ -14,6 +14,7 @@
|
|||||||
nbactions.xml
|
nbactions.xml
|
||||||
nb-configuration.xml
|
nb-configuration.xml
|
||||||
catalog.xml
|
catalog.xml
|
||||||
|
nbproject
|
||||||
|
|
||||||
# Compiled source #
|
# Compiled source #
|
||||||
###################
|
###################
|
||||||
|
|||||||
+2
-1
@@ -12,11 +12,12 @@ env:
|
|||||||
- MAVEN_SKIP_RC=true
|
- MAVEN_SKIP_RC=true
|
||||||
- MAVEN_OPTS="-Xms512m -Xmx2048m"
|
- MAVEN_OPTS="-Xms512m -Xmx2048m"
|
||||||
matrix:
|
matrix:
|
||||||
- TESTS=old
|
|
||||||
- TESTS=group1
|
- TESTS=group1
|
||||||
- TESTS=group2
|
- TESTS=group2
|
||||||
- TESTS=group3
|
- TESTS=group3
|
||||||
|
- TESTS=group4
|
||||||
- TESTS=adapter
|
- TESTS=adapter
|
||||||
|
- TESTS=old
|
||||||
|
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- oraclejdk8
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+16
@@ -342,6 +342,12 @@ public class AdapterDeploymentContext {
|
|||||||
return delegate.getNotBefore();
|
return delegate.getNotBefore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNotBefore(int notBefore) {
|
||||||
|
delegate.setNotBefore(notBefore);
|
||||||
|
getPublicKeyLocator().reset(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setExposeToken(boolean exposeToken) {
|
public void setExposeToken(boolean exposeToken) {
|
||||||
delegate.setExposeToken(exposeToken);
|
delegate.setExposeToken(exposeToken);
|
||||||
@@ -446,6 +452,16 @@ public class AdapterDeploymentContext {
|
|||||||
public int getMinTimeBetweenJwksRequests() {
|
public int getMinTimeBetweenJwksRequests() {
|
||||||
return delegate.getMinTimeBetweenJwksRequests();
|
return delegate.getMinTimeBetweenJwksRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPublicKeyCacheTtl() {
|
||||||
|
return delegate.getPublicKeyCacheTtl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPublicKeyCacheTtl(int publicKeyCacheTtl) {
|
||||||
|
delegate.setPublicKeyCacheTtl(publicKeyCacheTtl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected KeycloakUriBuilder getBaseBuilder(HttpFacade facade, String base) {
|
protected KeycloakUriBuilder getBaseBuilder(HttpFacade facade, String base) {
|
||||||
|
|||||||
+1
-8
@@ -46,14 +46,7 @@ public class HttpAdapterUtils {
|
|||||||
}
|
}
|
||||||
InputStream is = entity.getContent();
|
InputStream is = entity.getContent();
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
return JsonSerialization.readValue(is, clazz);
|
||||||
int c;
|
|
||||||
while ((c = is.read()) != -1) {
|
|
||||||
os.write(c);
|
|
||||||
}
|
|
||||||
byte[] bytes = os.toByteArray();
|
|
||||||
String json = new String(bytes);
|
|
||||||
return JsonSerialization.readValue(json, clazz);
|
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
is.close();
|
is.close();
|
||||||
|
|||||||
+23
@@ -57,6 +57,7 @@ public class KeycloakDeployment {
|
|||||||
|
|
||||||
protected String resourceName;
|
protected String resourceName;
|
||||||
protected boolean bearerOnly;
|
protected boolean bearerOnly;
|
||||||
|
protected boolean autodetectBearerOnly;
|
||||||
protected boolean enableBasicAuth;
|
protected boolean enableBasicAuth;
|
||||||
protected boolean publicClient;
|
protected boolean publicClient;
|
||||||
protected Map<String, Object> resourceCredentials = new HashMap<>();
|
protected Map<String, Object> resourceCredentials = new HashMap<>();
|
||||||
@@ -81,6 +82,7 @@ public class KeycloakDeployment {
|
|||||||
protected volatile int notBefore;
|
protected volatile int notBefore;
|
||||||
protected int tokenMinimumTimeToLive;
|
protected int tokenMinimumTimeToLive;
|
||||||
protected int minTimeBetweenJwksRequests;
|
protected int minTimeBetweenJwksRequests;
|
||||||
|
protected int publicKeyCacheTtl;
|
||||||
private PolicyEnforcer policyEnforcer;
|
private PolicyEnforcer policyEnforcer;
|
||||||
|
|
||||||
public KeycloakDeployment() {
|
public KeycloakDeployment() {
|
||||||
@@ -200,6 +202,14 @@ public class KeycloakDeployment {
|
|||||||
this.bearerOnly = bearerOnly;
|
this.bearerOnly = bearerOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAutodetectBearerOnly() {
|
||||||
|
return autodetectBearerOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutodetectBearerOnly(boolean autodetectBearerOnly) {
|
||||||
|
this.autodetectBearerOnly = autodetectBearerOnly;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEnableBasicAuth() {
|
public boolean isEnableBasicAuth() {
|
||||||
return enableBasicAuth;
|
return enableBasicAuth;
|
||||||
}
|
}
|
||||||
@@ -328,6 +338,11 @@ public class KeycloakDeployment {
|
|||||||
this.notBefore = notBefore;
|
this.notBefore = notBefore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateNotBefore(int notBefore) {
|
||||||
|
this.notBefore = notBefore;
|
||||||
|
getPublicKeyLocator().reset(this);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAlwaysRefreshToken() {
|
public boolean isAlwaysRefreshToken() {
|
||||||
return alwaysRefreshToken;
|
return alwaysRefreshToken;
|
||||||
}
|
}
|
||||||
@@ -384,6 +399,14 @@ public class KeycloakDeployment {
|
|||||||
this.minTimeBetweenJwksRequests = minTimeBetweenJwksRequests;
|
this.minTimeBetweenJwksRequests = minTimeBetweenJwksRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPublicKeyCacheTtl() {
|
||||||
|
return publicKeyCacheTtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicKeyCacheTtl(int publicKeyCacheTtl) {
|
||||||
|
this.publicKeyCacheTtl = publicKeyCacheTtl;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPolicyEnforcer(PolicyEnforcer policyEnforcer) {
|
public void setPolicyEnforcer(PolicyEnforcer policyEnforcer) {
|
||||||
this.policyEnforcer = policyEnforcer;
|
this.policyEnforcer = policyEnforcer;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -99,12 +99,14 @@ public class KeycloakDeploymentBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deployment.setBearerOnly(adapterConfig.isBearerOnly());
|
deployment.setBearerOnly(adapterConfig.isBearerOnly());
|
||||||
|
deployment.setAutodetectBearerOnly(adapterConfig.isAutodetectBearerOnly());
|
||||||
deployment.setEnableBasicAuth(adapterConfig.isEnableBasicAuth());
|
deployment.setEnableBasicAuth(adapterConfig.isEnableBasicAuth());
|
||||||
deployment.setAlwaysRefreshToken(adapterConfig.isAlwaysRefreshToken());
|
deployment.setAlwaysRefreshToken(adapterConfig.isAlwaysRefreshToken());
|
||||||
deployment.setRegisterNodeAtStartup(adapterConfig.isRegisterNodeAtStartup());
|
deployment.setRegisterNodeAtStartup(adapterConfig.isRegisterNodeAtStartup());
|
||||||
deployment.setRegisterNodePeriod(adapterConfig.getRegisterNodePeriod());
|
deployment.setRegisterNodePeriod(adapterConfig.getRegisterNodePeriod());
|
||||||
deployment.setTokenMinimumTimeToLive(adapterConfig.getTokenMinimumTimeToLive());
|
deployment.setTokenMinimumTimeToLive(adapterConfig.getTokenMinimumTimeToLive());
|
||||||
deployment.setMinTimeBetweenJwksRequests(adapterConfig.getMinTimeBetweenJwksRequests());
|
deployment.setMinTimeBetweenJwksRequests(adapterConfig.getMinTimeBetweenJwksRequests());
|
||||||
|
deployment.setPublicKeyCacheTtl(adapterConfig.getPublicKeyCacheTtl());
|
||||||
|
|
||||||
if (realmKeyPem == null && adapterConfig.isBearerOnly() && adapterConfig.getAuthServerUrl() == null) {
|
if (realmKeyPem == null && adapterConfig.isBearerOnly() && adapterConfig.getAuthServerUrl() == null) {
|
||||||
throw new IllegalArgumentException("For bearer auth, you must set the realm-public-key or auth-server-url");
|
throw new IllegalArgumentException("For bearer auth, you must set the realm-public-key or auth-server-url");
|
||||||
|
|||||||
+5
-6
@@ -25,6 +25,7 @@ import org.keycloak.adapters.spi.AuthChallenge;
|
|||||||
import org.keycloak.adapters.spi.AuthOutcome;
|
import org.keycloak.adapters.spi.AuthOutcome;
|
||||||
import org.keycloak.adapters.spi.HttpFacade;
|
import org.keycloak.adapters.spi.HttpFacade;
|
||||||
import org.keycloak.common.VerificationException;
|
import org.keycloak.common.VerificationException;
|
||||||
|
import org.keycloak.common.util.Encode;
|
||||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||||
import org.keycloak.common.util.UriUtils;
|
import org.keycloak.common.util.UriUtils;
|
||||||
import org.keycloak.constants.AdapterConstants;
|
import org.keycloak.constants.AdapterConstants;
|
||||||
@@ -169,7 +170,7 @@ public class OAuthRequestAuthenticator {
|
|||||||
KeycloakUriBuilder redirectUriBuilder = deployment.getAuthUrl().clone()
|
KeycloakUriBuilder redirectUriBuilder = deployment.getAuthUrl().clone()
|
||||||
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
|
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
|
||||||
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
|
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
|
||||||
.queryParam(OAuth2Constants.REDIRECT_URI, url)
|
.queryParam(OAuth2Constants.REDIRECT_URI, Encode.encodeQueryParamAsIs(url)) // Need to encode uri ourselves as queryParam() will not encode % characters.
|
||||||
.queryParam(OAuth2Constants.STATE, state)
|
.queryParam(OAuth2Constants.STATE, state)
|
||||||
.queryParam("login", "true");
|
.queryParam("login", "true");
|
||||||
if(loginHint != null && loginHint.length() > 0){
|
if(loginHint != null && loginHint.length() > 0){
|
||||||
@@ -195,15 +196,13 @@ public class OAuthRequestAuthenticator {
|
|||||||
return sslRedirectPort;
|
return sslRedirectPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final AtomicLong counter = new AtomicLong();
|
|
||||||
|
|
||||||
protected String getStateCode() {
|
protected String getStateCode() {
|
||||||
return counter.getAndIncrement() + "/" + AdapterUtils.generateId();
|
return AdapterUtils.generateId();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AuthChallenge loginRedirect() {
|
protected AuthChallenge loginRedirect() {
|
||||||
final String state = getStateCode();
|
final String state = getStateCode();
|
||||||
final String redirect = getRedirectUri(state);
|
final String redirect = getRedirectUri(state);
|
||||||
if (redirect == null) {
|
if (redirect == null) {
|
||||||
return challenge(403, OIDCAuthenticationError.Reason.NO_REDIRECT_URI, null);
|
return challenge(403, OIDCAuthenticationError.Reason.NO_REDIRECT_URI, null);
|
||||||
}
|
}
|
||||||
@@ -357,7 +356,7 @@ public class OAuthRequestAuthenticator {
|
|||||||
return challenge(403, OIDCAuthenticationError.Reason.INVALID_TOKEN, null);
|
return challenge(403, OIDCAuthenticationError.Reason.INVALID_TOKEN, null);
|
||||||
}
|
}
|
||||||
if (tokenResponse.getNotBeforePolicy() > deployment.getNotBefore()) {
|
if (tokenResponse.getNotBeforePolicy() > deployment.getNotBefore()) {
|
||||||
deployment.setNotBefore(tokenResponse.getNotBeforePolicy());
|
deployment.updateNotBefore(tokenResponse.getNotBeforePolicy());
|
||||||
}
|
}
|
||||||
if (token.getIssuedAt() < deployment.getNotBefore()) {
|
if (token.getIssuedAt() < deployment.getNotBefore()) {
|
||||||
log.error("Stale token");
|
log.error("Stale token");
|
||||||
|
|||||||
+2
-2
@@ -155,7 +155,7 @@ public class PreAuthActionsHandler {
|
|||||||
} else {
|
} else {
|
||||||
log.debugf("logout of all sessions for application '%s'", action.getResource());
|
log.debugf("logout of all sessions for application '%s'", action.getResource());
|
||||||
if (action.getNotBefore() > deployment.getNotBefore()) {
|
if (action.getNotBefore() > deployment.getNotBefore()) {
|
||||||
deployment.setNotBefore(action.getNotBefore());
|
deployment.updateNotBefore(action.getNotBefore());
|
||||||
}
|
}
|
||||||
userSessionManagement.logoutAll();
|
userSessionManagement.logoutAll();
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ public class PreAuthActionsHandler {
|
|||||||
}
|
}
|
||||||
PushNotBeforeAction action = JsonSerialization.readValue(token.getContent(), PushNotBeforeAction.class);
|
PushNotBeforeAction action = JsonSerialization.readValue(token.getContent(), PushNotBeforeAction.class);
|
||||||
if (!validateAction(action)) return;
|
if (!validateAction(action)) return;
|
||||||
deployment.setNotBefore(action.getNotBefore());
|
deployment.updateNotBefore(action.getNotBefore());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -144,7 +144,7 @@ public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (response.getNotBeforePolicy() > deployment.getNotBefore()) {
|
if (response.getNotBeforePolicy() > deployment.getNotBefore()) {
|
||||||
deployment.setNotBefore(response.getNotBeforePolicy());
|
deployment.updateNotBefore(response.getNotBeforePolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
|
|||||||
+38
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package org.keycloak.adapters;
|
package org.keycloak.adapters;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.KeycloakPrincipal;
|
import org.keycloak.KeycloakPrincipal;
|
||||||
import org.keycloak.adapters.spi.AuthChallenge;
|
import org.keycloak.adapters.spi.AuthChallenge;
|
||||||
@@ -116,6 +118,12 @@ public abstract class RequestAuthenticator {
|
|||||||
return AuthOutcome.NOT_ATTEMPTED;
|
return AuthOutcome.NOT_ATTEMPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isAutodetectedBearerOnly(facade.getRequest())) {
|
||||||
|
challenge = bearer.getChallenge();
|
||||||
|
log.debug("NOT_ATTEMPTED: Treating as bearer only");
|
||||||
|
return AuthOutcome.NOT_ATTEMPTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace("try oauth");
|
log.trace("try oauth");
|
||||||
}
|
}
|
||||||
@@ -158,6 +166,36 @@ public abstract class RequestAuthenticator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isAutodetectedBearerOnly(HttpFacade.Request request) {
|
||||||
|
if (!deployment.isAutodetectBearerOnly()) return false;
|
||||||
|
|
||||||
|
String headerValue = facade.getRequest().getHeader("X-Requested-With");
|
||||||
|
if (headerValue != null && headerValue.equalsIgnoreCase("XMLHttpRequest")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
headerValue = facade.getRequest().getHeader("Faces-Request");
|
||||||
|
if (headerValue != null && headerValue.startsWith("partial/")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
headerValue = facade.getRequest().getHeader("SOAPAction");
|
||||||
|
if (headerValue != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> accepts = facade.getRequest().getHeaders("Accept");
|
||||||
|
if (accepts == null) accepts = Collections.emptyList();
|
||||||
|
|
||||||
|
for (String accept : accepts) {
|
||||||
|
if (accept.contains("text/html") || accept.contains("text/*") || accept.contains("*/*")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract OAuthRequestAuthenticator createOAuthAuthenticator();
|
protected abstract OAuthRequestAuthenticator createOAuthAuthenticator();
|
||||||
|
|
||||||
protected BearerTokenRequestAuthenticator createBearerTokenAuthenticator() {
|
protected BearerTokenRequestAuthenticator createBearerTokenAuthenticator() {
|
||||||
|
|||||||
+31
-24
@@ -17,6 +17,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.keycloak.adapters.authorization;
|
package org.keycloak.adapters.authorization;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.AuthorizationContext;
|
import org.keycloak.AuthorizationContext;
|
||||||
import org.keycloak.KeycloakSecurityContext;
|
import org.keycloak.KeycloakSecurityContext;
|
||||||
@@ -32,13 +39,6 @@ import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.Enforce
|
|||||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
||||||
import org.keycloak.representations.idm.authorization.Permission;
|
import org.keycloak.representations.idm.authorization.Permission;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
@@ -48,7 +48,7 @@ public abstract class AbstractPolicyEnforcer {
|
|||||||
private final PolicyEnforcerConfig enforcerConfig;
|
private final PolicyEnforcerConfig enforcerConfig;
|
||||||
private final PolicyEnforcer policyEnforcer;
|
private final PolicyEnforcer policyEnforcer;
|
||||||
|
|
||||||
private List<PathConfig> paths;
|
private Map<String, PathConfig> paths;
|
||||||
private AuthzClient authzClient;
|
private AuthzClient authzClient;
|
||||||
private PathMatcher pathMatcher;
|
private PathMatcher pathMatcher;
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ public abstract class AbstractPolicyEnforcer {
|
|||||||
this.enforcerConfig = policyEnforcer.getEnforcerConfig();
|
this.enforcerConfig = policyEnforcer.getEnforcerConfig();
|
||||||
this.authzClient = policyEnforcer.getClient();
|
this.authzClient = policyEnforcer.getClient();
|
||||||
this.pathMatcher = new PathMatcher();
|
this.pathMatcher = new PathMatcher();
|
||||||
this.paths = new ArrayList<>(policyEnforcer.getPaths());
|
this.paths = policyEnforcer.getPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthorizationContext authorize(OIDCHttpFacade httpFacade) {
|
public AuthorizationContext authorize(OIDCHttpFacade httpFacade) {
|
||||||
@@ -75,8 +75,7 @@ public abstract class AbstractPolicyEnforcer {
|
|||||||
if (accessToken != null) {
|
if (accessToken != null) {
|
||||||
Request request = httpFacade.getRequest();
|
Request request = httpFacade.getRequest();
|
||||||
Response response = httpFacade.getResponse();
|
Response response = httpFacade.getResponse();
|
||||||
String pathInfo = URI.create(request.getURI()).getPath().substring(1);
|
String path = getPath(request);
|
||||||
String path = pathInfo.substring(pathInfo.indexOf('/'), pathInfo.length());
|
|
||||||
PathConfig pathConfig = this.pathMatcher.matches(path, this.paths);
|
PathConfig pathConfig = this.pathMatcher.matches(path, this.paths);
|
||||||
|
|
||||||
LOGGER.debugf("Checking permissions for path [%s] with config [%s].", request.getURI(), pathConfig);
|
LOGGER.debugf("Checking permissions for path [%s] with config [%s].", request.getURI(), pathConfig);
|
||||||
@@ -122,12 +121,9 @@ public abstract class AbstractPolicyEnforcer {
|
|||||||
protected boolean isAuthorized(PathConfig actualPathConfig, Set<String> requiredScopes, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
protected boolean isAuthorized(PathConfig actualPathConfig, Set<String> requiredScopes, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
||||||
Request request = httpFacade.getRequest();
|
Request request = httpFacade.getRequest();
|
||||||
PolicyEnforcerConfig enforcerConfig = getEnforcerConfig();
|
PolicyEnforcerConfig enforcerConfig = getEnforcerConfig();
|
||||||
String accessDeniedPath = enforcerConfig.getOnDenyRedirectTo();
|
|
||||||
|
|
||||||
if (accessDeniedPath != null) {
|
if (isDefaultAccessDeniedUri(request, enforcerConfig)) {
|
||||||
if (request.getURI().contains(accessDeniedPath)) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessToken.Authorization authorization = accessToken.getAuthorization();
|
AccessToken.Authorization authorization = accessToken.getAuthorization();
|
||||||
@@ -173,6 +169,17 @@ public abstract class AbstractPolicyEnforcer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isDefaultAccessDeniedUri(Request request, PolicyEnforcerConfig enforcerConfig) {
|
||||||
|
String accessDeniedPath = enforcerConfig.getOnDenyRedirectTo();
|
||||||
|
|
||||||
|
if (accessDeniedPath != null) {
|
||||||
|
if (request.getURI().contains(accessDeniedPath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasResourceScopePermission(Set<String> requiredScopes, Permission permission, PathConfig actualPathConfig) {
|
private boolean hasResourceScopePermission(Set<String> requiredScopes, Permission permission, PathConfig actualPathConfig) {
|
||||||
Set<String> allowedScopes = permission.getScopes();
|
Set<String> allowedScopes = permission.getScopes();
|
||||||
return (allowedScopes.containsAll(requiredScopes) || allowedScopes.isEmpty());
|
return (allowedScopes.containsAll(requiredScopes) || allowedScopes.isEmpty());
|
||||||
@@ -220,27 +227,23 @@ public abstract class AbstractPolicyEnforcer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private PathConfig resolvePathConfig(PathConfig originalConfig, Request request) {
|
private PathConfig resolvePathConfig(PathConfig originalConfig, Request request) {
|
||||||
|
String path = getPath(request);
|
||||||
|
|
||||||
if (originalConfig.hasPattern()) {
|
if (originalConfig.hasPattern()) {
|
||||||
String pathInfo = URI.create(request.getURI()).getPath().substring(1);
|
|
||||||
String path = pathInfo.substring(pathInfo.indexOf('/'), pathInfo.length());
|
|
||||||
ProtectedResource resource = this.authzClient.protection().resource();
|
ProtectedResource resource = this.authzClient.protection().resource();
|
||||||
Set<String> search = resource.findByFilter("uri=" + path);
|
Set<String> search = resource.findByFilter("uri=" + path);
|
||||||
|
|
||||||
if (!search.isEmpty()) {
|
if (!search.isEmpty()) {
|
||||||
// resource does exist on the server, cache it
|
// resource does exist on the server, cache it
|
||||||
ResourceRepresentation targetResource = resource.findById(search.iterator().next()).getResourceDescription();
|
ResourceRepresentation targetResource = resource.findById(search.iterator().next()).getResourceDescription();
|
||||||
PathConfig config = new PathConfig();
|
PathConfig config = PolicyEnforcer.createPathConfig(targetResource);
|
||||||
|
|
||||||
config.setId(targetResource.getId());
|
|
||||||
config.setName(targetResource.getName());
|
|
||||||
config.setType(targetResource.getType());
|
|
||||||
config.setPath(targetResource.getUri());
|
|
||||||
config.setScopes(originalConfig.getScopes());
|
config.setScopes(originalConfig.getScopes());
|
||||||
config.setMethods(originalConfig.getMethods());
|
config.setMethods(originalConfig.getMethods());
|
||||||
config.setParentConfig(originalConfig);
|
config.setParentConfig(originalConfig);
|
||||||
config.setEnforcementMode(originalConfig.getEnforcementMode());
|
config.setEnforcementMode(originalConfig.getEnforcementMode());
|
||||||
|
|
||||||
this.paths.add(config);
|
this.policyEnforcer.addPath(config);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
@@ -249,6 +252,10 @@ public abstract class AbstractPolicyEnforcer {
|
|||||||
return originalConfig;
|
return originalConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getPath(Request request) {
|
||||||
|
return request.getRelativePath();
|
||||||
|
}
|
||||||
|
|
||||||
private Set<String> getRequiredScopes(PathConfig pathConfig, Request request) {
|
private Set<String> getRequiredScopes(PathConfig pathConfig, Request request) {
|
||||||
Set<String> requiredScopes = new HashSet<>();
|
Set<String> requiredScopes = new HashSet<>();
|
||||||
|
|
||||||
|
|||||||
+31
-34
@@ -17,6 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.keycloak.adapters.authorization;
|
package org.keycloak.adapters.authorization;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.adapters.KeycloakDeployment;
|
import org.keycloak.adapters.KeycloakDeployment;
|
||||||
import org.keycloak.adapters.OIDCHttpFacade;
|
import org.keycloak.adapters.OIDCHttpFacade;
|
||||||
@@ -34,10 +38,6 @@ import org.keycloak.representations.AccessToken;
|
|||||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
||||||
import org.keycloak.representations.idm.authorization.Permission;
|
import org.keycloak.representations.idm.authorization.Permission;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
@@ -51,39 +51,34 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isAuthorized(PathConfig pathConfig, Set<String> requiredScopes, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
protected boolean isAuthorized(PathConfig pathConfig, Set<String> requiredScopes, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
||||||
int retry = 2;
|
|
||||||
AccessToken original = accessToken;
|
AccessToken original = accessToken;
|
||||||
|
|
||||||
while (retry > 0) {
|
if (super.isAuthorized(pathConfig, requiredScopes, accessToken, httpFacade)) {
|
||||||
if (super.isAuthorized(pathConfig, requiredScopes, accessToken, httpFacade)) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
accessToken = requestAuthorizationToken(pathConfig, requiredScopes, httpFacade);
|
|
||||||
|
|
||||||
if (accessToken == null) {
|
|
||||||
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--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
accessToken = requestAuthorizationToken(pathConfig, requiredScopes, httpFacade);
|
||||||
|
|
||||||
|
if (accessToken == null) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
return super.isAuthorized(pathConfig, requiredScopes, accessToken, httpFacade);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,7 +103,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
|||||||
KeycloakDeployment deployment = getPolicyEnforcer().getDeployment();
|
KeycloakDeployment deployment = getPolicyEnforcer().getDeployment();
|
||||||
|
|
||||||
if (getEnforcerConfig().getUserManagedAccess() != null) {
|
if (getEnforcerConfig().getUserManagedAccess() != null) {
|
||||||
LOGGER.debug("Obtaining authorization for authenticated user.");
|
LOGGER.debug("Obtaining authorization for authenticated user.");
|
||||||
PermissionRequest permissionRequest = new PermissionRequest();
|
PermissionRequest permissionRequest = new PermissionRequest();
|
||||||
|
|
||||||
permissionRequest.setResourceSetId(pathConfig.getId());
|
permissionRequest.setResourceSetId(pathConfig.getId());
|
||||||
@@ -136,12 +131,14 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
|||||||
permissionRequest.setResourceSetId(pathConfig.getId());
|
permissionRequest.setResourceSetId(pathConfig.getId());
|
||||||
permissionRequest.setResourceSetName(pathConfig.getName());
|
permissionRequest.setResourceSetName(pathConfig.getName());
|
||||||
permissionRequest.setScopes(new HashSet<>(pathConfig.getScopes()));
|
permissionRequest.setScopes(new HashSet<>(pathConfig.getScopes()));
|
||||||
|
LOGGER.debugf("Sending entitlements request: resource_set_id [%s], resource_set_name [%s], scopes [%s].", permissionRequest.getResourceSetId(), permissionRequest.getResourceSetName(), permissionRequest.getScopes());
|
||||||
request.addPermission(permissionRequest);
|
request.addPermission(permissionRequest);
|
||||||
EntitlementResponse authzResponse = authzClient.entitlement(accessToken).get(authzClient.getConfiguration().getClientId(), request);
|
EntitlementResponse authzResponse = authzClient.entitlement(accessToken).get(authzClient.getConfiguration().getClientId(), request);
|
||||||
return AdapterRSATokenVerifier.verifyToken(authzResponse.getRpt(), deployment);
|
return AdapterRSATokenVerifier.verifyToken(authzResponse.getRpt(), deployment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (AuthorizationDeniedException e) {
|
} catch (AuthorizationDeniedException e) {
|
||||||
|
LOGGER.debug("Authorization denied", e);
|
||||||
return null;
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unexpected error during authorization request.", e);
|
throw new RuntimeException("Unexpected error during authorization request.", e);
|
||||||
|
|||||||
+9
-3
@@ -19,7 +19,7 @@ package org.keycloak.adapters.authorization;
|
|||||||
|
|
||||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
@@ -28,10 +28,16 @@ class PathMatcher {
|
|||||||
|
|
||||||
private static final String ANY_RESOURCE_PATTERN = "/*";
|
private static final String ANY_RESOURCE_PATTERN = "/*";
|
||||||
|
|
||||||
PathConfig matches(final String requestedUri, List<PathConfig> paths) {
|
PathConfig matches(final String requestedUri, Map<String, PathConfig> paths) {
|
||||||
|
PathConfig pathConfig = paths.get(requestedUri);
|
||||||
|
|
||||||
|
if (pathConfig != null) {
|
||||||
|
return pathConfig;
|
||||||
|
}
|
||||||
|
|
||||||
PathConfig actualConfig = null;
|
PathConfig actualConfig = null;
|
||||||
|
|
||||||
for (PathConfig entry : paths) {
|
for (PathConfig entry : paths.values()) {
|
||||||
String protectedUri = entry.getPath();
|
String protectedUri = entry.getPath();
|
||||||
String selectedUri = null;
|
String selectedUri = null;
|
||||||
|
|
||||||
|
|||||||
+20
-13
@@ -34,8 +34,10 @@ import org.keycloak.representations.idm.authorization.Permission;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +50,7 @@ public class PolicyEnforcer {
|
|||||||
private final KeycloakDeployment deployment;
|
private final KeycloakDeployment deployment;
|
||||||
private final AuthzClient authzClient;
|
private final AuthzClient authzClient;
|
||||||
private final PolicyEnforcerConfig enforcerConfig;
|
private final PolicyEnforcerConfig enforcerConfig;
|
||||||
private final List<PathConfig> paths;
|
private final Map<String, PathConfig> paths;
|
||||||
|
|
||||||
public PolicyEnforcer(KeycloakDeployment deployment, AdapterConfig adapterConfig) {
|
public PolicyEnforcer(KeycloakDeployment deployment, AdapterConfig adapterConfig) {
|
||||||
this.deployment = deployment;
|
this.deployment = deployment;
|
||||||
@@ -58,7 +60,7 @@ public class PolicyEnforcer {
|
|||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("Initialization complete. Path configurations:");
|
LOGGER.debug("Initialization complete. Path configurations:");
|
||||||
for (PathConfig pathConfig : this.paths) {
|
for (PathConfig pathConfig : this.paths.values()) {
|
||||||
LOGGER.debug(pathConfig);
|
LOGGER.debug(pathConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,15 +98,19 @@ public class PolicyEnforcer {
|
|||||||
return authzClient;
|
return authzClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PathConfig> getPaths() {
|
public Map<String, PathConfig> getPaths() {
|
||||||
return Collections.unmodifiableList(paths);
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPath(PathConfig pathConfig) {
|
||||||
|
paths.put(pathConfig.getPath(), pathConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeycloakDeployment getDeployment() {
|
KeycloakDeployment getDeployment() {
|
||||||
return deployment;
|
return deployment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PathConfig> configurePaths(ProtectedResource protectedResource, PolicyEnforcerConfig enforcerConfig) {
|
private Map<String, PathConfig> configurePaths(ProtectedResource protectedResource, PolicyEnforcerConfig enforcerConfig) {
|
||||||
boolean loadPathsFromServer = true;
|
boolean loadPathsFromServer = true;
|
||||||
|
|
||||||
for (PathConfig pathConfig : enforcerConfig.getPaths()) {
|
for (PathConfig pathConfig : enforcerConfig.getPaths()) {
|
||||||
@@ -123,8 +129,8 @@ public class PolicyEnforcer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PathConfig> configureDefinedPaths(ProtectedResource protectedResource, PolicyEnforcerConfig enforcerConfig) {
|
private Map<String, PathConfig> configureDefinedPaths(ProtectedResource protectedResource, PolicyEnforcerConfig enforcerConfig) {
|
||||||
List<PathConfig> paths = new ArrayList<>();
|
Map<String, PathConfig> paths = Collections.synchronizedMap(new HashMap<String, PathConfig>());
|
||||||
|
|
||||||
for (PathConfig pathConfig : enforcerConfig.getPaths()) {
|
for (PathConfig pathConfig : enforcerConfig.getPaths()) {
|
||||||
Set<String> search;
|
Set<String> search;
|
||||||
@@ -172,7 +178,7 @@ public class PolicyEnforcer {
|
|||||||
|
|
||||||
PathConfig existingPath = null;
|
PathConfig existingPath = null;
|
||||||
|
|
||||||
for (PathConfig current : paths) {
|
for (PathConfig current : paths.values()) {
|
||||||
if (current.getId().equals(pathConfig.getId()) && current.getPath().equals(pathConfig.getPath())) {
|
if (current.getId().equals(pathConfig.getId()) && current.getPath().equals(pathConfig.getPath())) {
|
||||||
existingPath = current;
|
existingPath = current;
|
||||||
break;
|
break;
|
||||||
@@ -180,7 +186,7 @@ public class PolicyEnforcer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (existingPath == null) {
|
if (existingPath == null) {
|
||||||
paths.add(pathConfig);
|
paths.put(pathConfig.getPath(), pathConfig);
|
||||||
} else {
|
} else {
|
||||||
existingPath.getMethods().addAll(pathConfig.getMethods());
|
existingPath.getMethods().addAll(pathConfig.getMethods());
|
||||||
existingPath.getScopes().addAll(pathConfig.getScopes());
|
existingPath.getScopes().addAll(pathConfig.getScopes());
|
||||||
@@ -190,23 +196,24 @@ public class PolicyEnforcer {
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PathConfig> configureAllPathsForResourceServer(ProtectedResource protectedResource) {
|
private Map<String, PathConfig> configureAllPathsForResourceServer(ProtectedResource protectedResource) {
|
||||||
LOGGER.info("Querying the server for all resources associated with this application.");
|
LOGGER.info("Querying the server for all resources associated with this application.");
|
||||||
List<PathConfig> paths = new ArrayList<>();
|
Map<String, PathConfig> paths = Collections.synchronizedMap(new HashMap<String, PathConfig>());
|
||||||
|
|
||||||
for (String id : protectedResource.findAll()) {
|
for (String id : protectedResource.findAll()) {
|
||||||
RegistrationResponse response = protectedResource.findById(id);
|
RegistrationResponse response = protectedResource.findById(id);
|
||||||
ResourceRepresentation resourceDescription = response.getResourceDescription();
|
ResourceRepresentation resourceDescription = response.getResourceDescription();
|
||||||
|
|
||||||
if (resourceDescription.getUri() != null) {
|
if (resourceDescription.getUri() != null) {
|
||||||
paths.add(createPathConfig(resourceDescription));
|
PathConfig pathConfig = createPathConfig(resourceDescription);
|
||||||
|
paths.put(pathConfig.getPath(), pathConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PathConfig createPathConfig(ResourceRepresentation resourceDescription) {
|
static PathConfig createPathConfig(ResourceRepresentation resourceDescription) {
|
||||||
PathConfig pathConfig = new PathConfig();
|
PathConfig pathConfig = new PathConfig();
|
||||||
|
|
||||||
pathConfig.setId(resourceDescription.getId());
|
pathConfig.setId(resourceDescription.getId());
|
||||||
|
|||||||
+5
@@ -37,4 +37,9 @@ public class HardcodedPublicKeyLocator implements PublicKeyLocator {
|
|||||||
public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) {
|
public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) {
|
||||||
return publicKey;
|
return publicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset(KeycloakDeployment deployment) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+30
-16
@@ -25,7 +25,6 @@ import org.keycloak.adapters.KeycloakDeployment;
|
|||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.jose.jwk.JSONWebKeySet;
|
import org.keycloak.jose.jwk.JSONWebKeySet;
|
||||||
import org.keycloak.jose.jwk.JWK;
|
import org.keycloak.jose.jwk.JWK;
|
||||||
import org.keycloak.jose.jws.JWSInput;
|
|
||||||
import org.keycloak.util.JWKSUtils;
|
import org.keycloak.util.JWKSUtils;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
@@ -48,36 +47,51 @@ public class JWKPublicKeyLocator implements PublicKeyLocator {
|
|||||||
@Override
|
@Override
|
||||||
public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) {
|
public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) {
|
||||||
int minTimeBetweenRequests = deployment.getMinTimeBetweenJwksRequests();
|
int minTimeBetweenRequests = deployment.getMinTimeBetweenJwksRequests();
|
||||||
|
int publicKeyCacheTtl = deployment.getPublicKeyCacheTtl();
|
||||||
|
int currentTime = Time.currentTime();
|
||||||
|
|
||||||
// Check if key is in cache.
|
// Check if key is in cache.
|
||||||
PublicKey publicKey = currentKeys.get(kid);
|
PublicKey publicKey = lookupCachedKey(publicKeyCacheTtl, currentTime, kid);
|
||||||
if (publicKey != null) {
|
if (publicKey != null) {
|
||||||
return publicKey;
|
return publicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentTime = Time.currentTime();
|
|
||||||
|
|
||||||
// Check if we are allowed to send request
|
// Check if we are allowed to send request
|
||||||
if (currentTime > lastRequestTime + minTimeBetweenRequests) {
|
synchronized (this) {
|
||||||
synchronized (this) {
|
currentTime = Time.currentTime();
|
||||||
currentTime = Time.currentTime();
|
if (currentTime > lastRequestTime + minTimeBetweenRequests) {
|
||||||
if (currentTime > lastRequestTime + minTimeBetweenRequests) {
|
sendRequest(deployment);
|
||||||
sendRequest(deployment);
|
lastRequestTime = currentTime;
|
||||||
lastRequestTime = currentTime;
|
} else {
|
||||||
} else {
|
log.debug("Won't send request to realm jwks url. Last request time was " + lastRequestTime);
|
||||||
log.debugf("Won't send request to realm jwks url. Last request time was %d", lastRequestTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return lookupCachedKey(publicKeyCacheTtl, currentTime, kid);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return currentKeys.get(kid);
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset(KeycloakDeployment deployment) {
|
||||||
|
synchronized (this) {
|
||||||
|
sendRequest(deployment);
|
||||||
|
lastRequestTime = Time.currentTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private PublicKey lookupCachedKey(int publicKeyCacheTtl, int currentTime, String kid) {
|
||||||
|
if (lastRequestTime + publicKeyCacheTtl > currentTime) {
|
||||||
|
return currentKeys.get(kid);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void sendRequest(KeycloakDeployment deployment) {
|
private void sendRequest(KeycloakDeployment deployment) {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.tracef("Going to send request to retrieve new set of realm public keys for client %s", deployment.getResourceName());
|
log.trace("Going to send request to retrieve new set of realm public keys for client " + deployment.getResourceName());
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpGet getMethod = new HttpGet(deployment.getJwksUrl());
|
HttpGet getMethod = new HttpGet(deployment.getJwksUrl());
|
||||||
@@ -87,7 +101,7 @@ public class JWKPublicKeyLocator implements PublicKeyLocator {
|
|||||||
Map<String, PublicKey> publicKeys = JWKSUtils.getKeysForUse(jwks, JWK.Use.SIG);
|
Map<String, PublicKey> publicKeys = JWKSUtils.getKeysForUse(jwks, JWK.Use.SIG);
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debugf("Realm public keys successfully retrieved for client %s. New kids: %s", deployment.getResourceName(), publicKeys.keySet().toString());
|
log.debug("Realm public keys successfully retrieved for client " + deployment.getResourceName() + ". New kids: " + publicKeys.keySet().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current keys
|
// Update current keys
|
||||||
|
|||||||
+7
@@ -34,4 +34,11 @@ public interface PublicKeyLocator {
|
|||||||
*/
|
*/
|
||||||
PublicKey getPublicKey(String kid, KeycloakDeployment deployment);
|
PublicKey getPublicKey(String kid, KeycloakDeployment deployment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the state of locator (eg. clear the cached keys)
|
||||||
|
*
|
||||||
|
* @param deployment
|
||||||
|
*/
|
||||||
|
void reset(KeycloakDeployment deployment);
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
@@ -69,6 +69,7 @@ public class KeycloakDeploymentBuilderTest {
|
|||||||
assertEquals("email", deployment.getPrincipalAttribute());
|
assertEquals("email", deployment.getPrincipalAttribute());
|
||||||
assertEquals(10, deployment.getTokenMinimumTimeToLive());
|
assertEquals(10, deployment.getTokenMinimumTimeToLive());
|
||||||
assertEquals(20, deployment.getMinTimeBetweenJwksRequests());
|
assertEquals(20, deployment.getMinTimeBetweenJwksRequests());
|
||||||
|
assertEquals(120, deployment.getPublicKeyCacheTtl());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -78,6 +79,7 @@ public class KeycloakDeploymentBuilderTest {
|
|||||||
|
|
||||||
assertTrue(deployment.getPublicKeyLocator() instanceof JWKPublicKeyLocator);
|
assertTrue(deployment.getPublicKeyLocator() instanceof JWKPublicKeyLocator);
|
||||||
assertEquals(10, deployment.getMinTimeBetweenJwksRequests());
|
assertEquals(10, deployment.getMinTimeBetweenJwksRequests());
|
||||||
|
assertEquals(86400, deployment.getPublicKeyCacheTtl());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -30,5 +30,6 @@
|
|||||||
"token-store": "cookie",
|
"token-store": "cookie",
|
||||||
"principal-attribute": "email",
|
"principal-attribute": "email",
|
||||||
"token-minimum-time-to-live": 10,
|
"token-minimum-time-to-live": 10,
|
||||||
"min-time-between-jwks-requests": 20
|
"min-time-between-jwks-requests": 20,
|
||||||
|
"public-key-cache-ttl": 120
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
|
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ public class JaxrsHttpFacade implements OIDCHttpFacade {
|
|||||||
return requestContext.getUriInfo().getRequestUri().toString();
|
return requestContext.getUriInfo().getRequestUri().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePath() {
|
||||||
|
return requestContext.getUriInfo().getPath();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecure() {
|
public boolean isSecure() {
|
||||||
return securityContext.isSecure();
|
return securityContext.isSecure();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak Jetty Integration</name>
|
<name>Keycloak Jetty Integration</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -153,7 +153,7 @@
|
|||||||
processCallback(callback, initPromise);
|
processCallback(callback, initPromise);
|
||||||
return;
|
return;
|
||||||
} else if (initOptions) {
|
} else if (initOptions) {
|
||||||
if (initOptions.token || initOptions.refreshToken) {
|
if (initOptions.refreshToken) {
|
||||||
setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
|
setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
|
||||||
|
|
||||||
if (loginIframe.enable) {
|
if (loginIframe.enable) {
|
||||||
@@ -379,7 +379,7 @@
|
|||||||
kc.updateToken = function(minValidity) {
|
kc.updateToken = function(minValidity) {
|
||||||
var promise = createPromise();
|
var promise = createPromise();
|
||||||
|
|
||||||
if (!kc.tokenParsed || !kc.refreshToken) {
|
if (!kc.refreshToken) {
|
||||||
promise.setError();
|
promise.setError();
|
||||||
return promise.promise;
|
return promise.promise;
|
||||||
}
|
}
|
||||||
@@ -388,14 +388,10 @@
|
|||||||
|
|
||||||
var exec = function() {
|
var exec = function() {
|
||||||
var refreshToken = false;
|
var refreshToken = false;
|
||||||
if (kc.timeSkew == -1) {
|
if (minValidity == -1) {
|
||||||
console.info('Skew ' + kc.timeSkew);
|
|
||||||
refreshToken = true;
|
|
||||||
console.info('[KEYCLOAK] Refreshing token: time skew not set');
|
|
||||||
} else if (minValidity == -1) {
|
|
||||||
refreshToken = true;
|
refreshToken = true;
|
||||||
console.info('[KEYCLOAK] Refreshing token: forced refresh');
|
console.info('[KEYCLOAK] Refreshing token: forced refresh');
|
||||||
} else if (kc.isTokenExpired(minValidity)) {
|
} else if (!kc.tokenParsed || kc.isTokenExpired(minValidity)) {
|
||||||
refreshToken = true;
|
refreshToken = true;
|
||||||
console.info('[KEYCLOAK] Refreshing token: token expired');
|
console.info('[KEYCLOAK] Refreshing token: token expired');
|
||||||
}
|
}
|
||||||
@@ -638,49 +634,6 @@
|
|||||||
kc.tokenTimeoutHandle = null;
|
kc.tokenTimeoutHandle = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token) {
|
|
||||||
kc.token = token;
|
|
||||||
kc.tokenParsed = decodeToken(token);
|
|
||||||
var sessionId = kc.realm + '/' + kc.tokenParsed.sub;
|
|
||||||
if (kc.tokenParsed.session_state) {
|
|
||||||
sessionId = sessionId + '/' + kc.tokenParsed.session_state;
|
|
||||||
}
|
|
||||||
kc.sessionId = sessionId;
|
|
||||||
kc.authenticated = true;
|
|
||||||
kc.subject = kc.tokenParsed.sub;
|
|
||||||
kc.realmAccess = kc.tokenParsed.realm_access;
|
|
||||||
kc.resourceAccess = kc.tokenParsed.resource_access;
|
|
||||||
|
|
||||||
if (timeLocal) {
|
|
||||||
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
|
|
||||||
console.info('[KEYCLOAK] Estimated time difference between browser and server is ' + kc.timeSkew + ' seconds');
|
|
||||||
} else {
|
|
||||||
kc.timeSkew = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kc.onTokenExpired) {
|
|
||||||
if (kc.timeSkew == -1) {
|
|
||||||
kc.onTokenExpired();
|
|
||||||
} else {
|
|
||||||
var expiresIn = (kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew) * 1000;
|
|
||||||
if (expiresIn <= 0) {
|
|
||||||
kc.onTokenExpired();
|
|
||||||
} else {
|
|
||||||
kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
delete kc.token;
|
|
||||||
delete kc.tokenParsed;
|
|
||||||
delete kc.subject;
|
|
||||||
delete kc.realmAccess;
|
|
||||||
delete kc.resourceAccess;
|
|
||||||
|
|
||||||
kc.authenticated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refreshToken) {
|
if (refreshToken) {
|
||||||
kc.refreshToken = refreshToken;
|
kc.refreshToken = refreshToken;
|
||||||
kc.refreshTokenParsed = decodeToken(refreshToken);
|
kc.refreshTokenParsed = decodeToken(refreshToken);
|
||||||
@@ -696,6 +649,48 @@
|
|||||||
delete kc.idToken;
|
delete kc.idToken;
|
||||||
delete kc.idTokenParsed;
|
delete kc.idTokenParsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
kc.token = token;
|
||||||
|
kc.tokenParsed = decodeToken(token);
|
||||||
|
|
||||||
|
var sessionId = kc.realm + '/' + kc.tokenParsed.sub;
|
||||||
|
if (kc.tokenParsed.session_state) {
|
||||||
|
sessionId = sessionId + '/' + kc.tokenParsed.session_state;
|
||||||
|
}
|
||||||
|
kc.sessionId = sessionId;
|
||||||
|
kc.authenticated = true;
|
||||||
|
kc.subject = kc.tokenParsed.sub;
|
||||||
|
kc.realmAccess = kc.tokenParsed.realm_access;
|
||||||
|
kc.resourceAccess = kc.tokenParsed.resource_access;
|
||||||
|
|
||||||
|
if (timeLocal) {
|
||||||
|
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
|
||||||
|
console.info('[KEYCLOAK] Estimated time difference between browser and server is ' + kc.timeSkew + ' seconds');
|
||||||
|
|
||||||
|
if (kc.onTokenExpired) {
|
||||||
|
var expiresIn = (kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew) * 1000;
|
||||||
|
console.info('[KEYCLOAK] Token expires in ' + Math.round(expiresIn / 1000) + ' s');
|
||||||
|
if (expiresIn <= 0) {
|
||||||
|
kc.onTokenExpired();
|
||||||
|
} else {
|
||||||
|
kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
kc.updateToken(-1);
|
||||||
|
}
|
||||||
|
} else if (refreshToken) {
|
||||||
|
kc.updateToken(-1);
|
||||||
|
} else {
|
||||||
|
delete kc.token;
|
||||||
|
delete kc.tokenParsed;
|
||||||
|
delete kc.subject;
|
||||||
|
delete kc.realmAccess;
|
||||||
|
delete kc.resourceAccess;
|
||||||
|
|
||||||
|
kc.authenticated = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeToken(str) {
|
function decodeToken(str) {
|
||||||
@@ -846,14 +841,15 @@
|
|||||||
kc.clearToken();
|
kc.clearToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = loginIframe.callbackList.length - 1; i >= 0; --i) {
|
var callbacks = loginIframe.callbackList.splice(0, loginIframe.callbackList.length);
|
||||||
var promise = loginIframe.callbackList[i];
|
|
||||||
|
for (var i = callbacks.length - 1; i >= 0; --i) {
|
||||||
|
var promise = callbacks[i];
|
||||||
if (event.data == "unchanged") {
|
if (event.data == "unchanged") {
|
||||||
promise.setSuccess();
|
promise.setSuccess();
|
||||||
} else {
|
} else {
|
||||||
promise.setError();
|
promise.setError();
|
||||||
}
|
}
|
||||||
loginIframe.callbackList.splice(i, 1);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function getCookie(cname)
|
||||||
|
{
|
||||||
|
var name = cname + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for(var i=0; i<ca.length; i++)
|
||||||
|
{
|
||||||
|
var c = ca[i].trim();
|
||||||
|
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
function receiveMessage(event)
|
||||||
|
{
|
||||||
|
if (event.origin !== "ORIGIN") {
|
||||||
|
console.log(event.origin + " does not match built origin");
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
var data = JSON.parse(event.data);
|
||||||
|
data.loggedIn = false;
|
||||||
|
var cookie = getCookie('KEYCLOAK_SESSION');
|
||||||
|
if (cookie) {
|
||||||
|
data.loggedIn = true;
|
||||||
|
data.session = cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.source.postMessage(JSON.stringify(data),
|
||||||
|
event.origin);
|
||||||
|
}
|
||||||
|
window.addEventListener("message", receiveMessage, false);
|
||||||
|
</script>
|
||||||
@@ -35,14 +35,14 @@
|
|||||||
req.open('GET', url, true);
|
req.open('GET', url, true);
|
||||||
|
|
||||||
req.onreadystatechange = function () {
|
req.onreadystatechange = function () {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState === 4) {
|
||||||
if (req.status == 204) {
|
if (req.status === 204) {
|
||||||
init = {
|
init = {
|
||||||
clientId: clientId,
|
clientId: clientId,
|
||||||
origin: origin
|
origin: origin
|
||||||
}
|
}
|
||||||
callback('unchanged');
|
callback('unchanged');
|
||||||
} else if (req.status = 404) {
|
} else if (req.status === 404) {
|
||||||
callback('changed');
|
callback('changed');
|
||||||
} else {
|
} else {
|
||||||
callback('error');
|
callback('error');
|
||||||
@@ -52,8 +52,8 @@
|
|||||||
|
|
||||||
req.send();
|
req.send();
|
||||||
} else {
|
} else {
|
||||||
if (clientId == init.clientId && origin == init.origin) {
|
if (clientId === init.clientId && origin === init.origin) {
|
||||||
if (sessionState == cookie) {
|
if (sessionState === cookie) {
|
||||||
callback('unchanged');
|
callback('unchanged');
|
||||||
} else {
|
} else {
|
||||||
callback('changed');
|
callback('changed');
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
for(var i=0; i<ca.length; i++)
|
for(var i=0; i<ca.length; i++)
|
||||||
{
|
{
|
||||||
var c = ca[i].trim();
|
var c = ca[i].trim();
|
||||||
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
|
if (c.indexOf(name)===0) return c.substring(name.length,c.length);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -95,4 +95,4 @@
|
|||||||
window.addEventListener("message", receiveMessage, false);
|
window.addEventListener("message", receiveMessage, false);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak OIDC Client Adapter Modules</name>
|
<name>Keycloak OIDC Client Adapter Modules</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+5
@@ -218,6 +218,11 @@ public class ServletOAuthClient extends KeycloakDeploymentDelegateOAuthClient {
|
|||||||
return servletRequest.getRequestURL().toString();
|
return servletRequest.getRequestURL().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePath() {
|
||||||
|
return servletRequest.getServletPath();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecure() {
|
public boolean isSecure() {
|
||||||
return servletRequest.isSecure();
|
return servletRequest.isSecure();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+12
-2
@@ -30,6 +30,12 @@ import javax.servlet.ServletException;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||||
|
import org.keycloak.adapters.spi.HttpFacade;
|
||||||
|
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
|
||||||
|
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a Keycloak {@link AuthenticationEntryPoint authentication entry point}. Uses a
|
* Provides a Keycloak {@link AuthenticationEntryPoint authentication entry point}. Uses a
|
||||||
@@ -56,12 +62,15 @@ public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoin
|
|||||||
private final RequestMatcher apiRequestMatcher;
|
private final RequestMatcher apiRequestMatcher;
|
||||||
private String loginUri = DEFAULT_LOGIN_URI;
|
private String loginUri = DEFAULT_LOGIN_URI;
|
||||||
private String realm = DEFAULT_REALM;
|
private String realm = DEFAULT_REALM;
|
||||||
|
|
||||||
|
private AdapterDeploymentContext adapterDeploymentContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Keycloak authentication entry point.
|
* Creates a new Keycloak authentication entry point.
|
||||||
*/
|
*/
|
||||||
public KeycloakAuthenticationEntryPoint() {
|
public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext) {
|
||||||
this(DEFAULT_API_REQUEST_MATCHER);
|
this(DEFAULT_API_REQUEST_MATCHER);
|
||||||
|
this.adapterDeploymentContext = adapterDeploymentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,7 +88,8 @@ public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoin
|
|||||||
@Override
|
@Override
|
||||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
if (apiRequestMatcher.matches(request)) {
|
HttpFacade facade = new SimpleHttpFacade(request, response);
|
||||||
|
if (apiRequestMatcher.matches(request) || adapterDeploymentContext.resolveDeployment(facade).isBearerOnly()) {
|
||||||
commenceUnauthorizedResponse(request, response);
|
commenceUnauthorizedResponse(request, response);
|
||||||
} else {
|
} else {
|
||||||
commenceLoginRedirect(request, response);
|
commenceLoginRedirect(request, response);
|
||||||
|
|||||||
+2
-2
@@ -71,8 +71,8 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
|
|||||||
return factoryBean.getObject();
|
return factoryBean.getObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AuthenticationEntryPoint authenticationEntryPoint() {
|
protected AuthenticationEntryPoint authenticationEntryPoint() throws Exception {
|
||||||
return new KeycloakAuthenticationEntryPoint();
|
return new KeycloakAuthenticationEntryPoint(adapterDeploymentContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected KeycloakAuthenticationProvider keycloakAuthenticationProvider() {
|
protected KeycloakAuthenticationProvider keycloakAuthenticationProvider() {
|
||||||
|
|||||||
+5
@@ -70,6 +70,11 @@ class WrappedHttpServletRequest implements Request {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePath() {
|
||||||
|
return request.getServletPath();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecure() {
|
public boolean isSecure() {
|
||||||
return request.isSecure();
|
return request.isSecure();
|
||||||
|
|||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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.springsecurity.filter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||||
|
import org.keycloak.adapters.AuthenticatedActionsHandler;
|
||||||
|
import org.keycloak.adapters.NodesRegistrationManagement;
|
||||||
|
import org.keycloak.adapters.OIDCHttpFacade;
|
||||||
|
import org.keycloak.adapters.spi.HttpFacade;
|
||||||
|
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.web.filter.GenericFilterBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes a Keycloak adapter {@link AuthenticatedActionsHandler} as a Spring Security filter.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:srossillo@smartling.com">Scott Rossillo</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class KeycloakAuthenticatedActionsFilter extends GenericFilterBean implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(KeycloakAuthenticatedActionsFilter.class);
|
||||||
|
|
||||||
|
private final NodesRegistrationManagement management = new NodesRegistrationManagement();
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
private AdapterDeploymentContext deploymentContext;
|
||||||
|
|
||||||
|
|
||||||
|
public KeycloakAuthenticatedActionsFilter() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilterBean() throws ServletException {
|
||||||
|
deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
log.debug("Unregistering deployment");
|
||||||
|
management.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
|
||||||
|
HttpFacade facade = new SimpleHttpFacade((HttpServletRequest)request, (HttpServletResponse)response);
|
||||||
|
AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deploymentContext.resolveDeployment(facade), (OIDCHttpFacade)facade);
|
||||||
|
boolean handled = handler.handledRequest();
|
||||||
|
if (handled) {
|
||||||
|
log.debug("Authenticated filter handled request: {}", ((HttpServletRequest) request).getRequestURI());
|
||||||
|
} else {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -142,6 +142,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
|
|||||||
if (AuthOutcome.FAILED.equals(result)) {
|
if (AuthOutcome.FAILED.equals(result)) {
|
||||||
throw new KeycloakAuthenticationException("Auth outcome: " + result);
|
throw new KeycloakAuthenticationException("Auth outcome: " + result);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (AuthOutcome.AUTHENTICATED.equals(result)) {
|
else if (AuthOutcome.AUTHENTICATED.equals(result)) {
|
||||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
Assert.notNull(authentication, "Authentication SecurityContextHolder was null");
|
Assert.notNull(authentication, "Authentication SecurityContextHolder was null");
|
||||||
|
|||||||
+22
-1
@@ -26,6 +26,15 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||||
|
import org.keycloak.adapters.KeycloakDeployment;
|
||||||
|
import org.keycloak.adapters.spi.HttpFacade;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keycloak authentication entry point tests.
|
* Keycloak authentication entry point tests.
|
||||||
@@ -35,12 +44,24 @@ public class KeycloakAuthenticationEntryPointTest {
|
|||||||
private KeycloakAuthenticationEntryPoint authenticationEntryPoint;
|
private KeycloakAuthenticationEntryPoint authenticationEntryPoint;
|
||||||
private MockHttpServletRequest request;
|
private MockHttpServletRequest request;
|
||||||
private MockHttpServletResponse response;
|
private MockHttpServletResponse response;
|
||||||
|
@Mock
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdapterDeploymentContext adapterDeploymentContext;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private KeycloakDeployment keycloakDeployment;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
authenticationEntryPoint = new KeycloakAuthenticationEntryPoint();
|
MockitoAnnotations.initMocks(this);
|
||||||
|
authenticationEntryPoint = new KeycloakAuthenticationEntryPoint(adapterDeploymentContext);
|
||||||
request = new MockHttpServletRequest();
|
request = new MockHttpServletRequest();
|
||||||
response = new MockHttpServletResponse();
|
response = new MockHttpServletResponse();
|
||||||
|
when(applicationContext.getBean(eq(AdapterDeploymentContext.class))).thenReturn(adapterDeploymentContext);
|
||||||
|
when(adapterDeploymentContext.resolveDeployment(any(HttpFacade.class))).thenReturn(keycloakDeployment);
|
||||||
|
when(keycloakDeployment.isBearerOnly()).thenReturn(Boolean.FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+1
@@ -154,6 +154,7 @@ public class KeycloakAuthenticationProcessingFilterTest {
|
|||||||
when(keycloakDeployment.getResourceName()).thenReturn("resource-name");
|
when(keycloakDeployment.getResourceName()).thenReturn("resource-name");
|
||||||
when(keycloakDeployment.getStateCookieName()).thenReturn("kc-cookie");
|
when(keycloakDeployment.getStateCookieName()).thenReturn("kc-cookie");
|
||||||
when(keycloakDeployment.getSslRequired()).thenReturn(SslRequired.NONE);
|
when(keycloakDeployment.getSslRequired()).thenReturn(SslRequired.NONE);
|
||||||
|
when(keycloakDeployment.isBearerOnly()).thenReturn(Boolean.FALSE);
|
||||||
filter.attemptAuthentication(request, response);
|
filter.attemptAuthentication(request, response);
|
||||||
|
|
||||||
verify(response).setStatus(302);
|
verify(response).setStatus(302);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak Tomcat Integration</name>
|
<name>Keycloak Tomcat Integration</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+9
-4
@@ -173,10 +173,15 @@ public class KeycloakServletExtension implements ServletExtension {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
log.debug("Setting jsession cookie path to: " + deploymentInfo.getContextPath());
|
ServletSessionConfig cookieConfig = deploymentInfo.getServletSessionConfig();
|
||||||
ServletSessionConfig cookieConfig = new ServletSessionConfig();
|
if (cookieConfig == null) {
|
||||||
cookieConfig.setPath(deploymentInfo.getContextPath());
|
cookieConfig = new ServletSessionConfig();
|
||||||
deploymentInfo.setServletSessionConfig(cookieConfig);
|
}
|
||||||
|
if (cookieConfig.getPath() == null) {
|
||||||
|
log.debug("Setting jsession cookie path to: " + deploymentInfo.getContextPath());
|
||||||
|
cookieConfig.setPath(deploymentInfo.getContextPath());
|
||||||
|
deploymentInfo.setServletSessionConfig(cookieConfig);
|
||||||
|
}
|
||||||
ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
|
ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
|
||||||
deploymentInfo.addListener(new ListenerInfo(UndertowNodesRegistrationManagementWrapper.class, new InstanceFactory<UndertowNodesRegistrationManagementWrapper>() {
|
deploymentInfo.addListener(new ListenerInfo(UndertowNodesRegistrationManagementWrapper.class, new InstanceFactory<UndertowNodesRegistrationManagementWrapper>() {
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak WildFly Integration</name>
|
<name>Keycloak WildFly Integration</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -20,10 +20,10 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak Integration</name>
|
<name>Keycloak Adapters</name>
|
||||||
<description/>
|
<description/>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak SAML EAP Integration</name>
|
<name>Keycloak SAML EAP Integration</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class SamlUtil {
|
|||||||
httpFacade.getResponse().setHeader("Content-Type", "text/html");
|
httpFacade.getResponse().setHeader("Content-Type", "text/html");
|
||||||
httpFacade.getResponse().setHeader("Pragma", "no-cache");
|
httpFacade.getResponse().setHeader("Pragma", "no-cache");
|
||||||
httpFacade.getResponse().setHeader("Cache-Control", "no-cache, no-store");
|
httpFacade.getResponse().setHeader("Cache-Control", "no-cache, no-store");
|
||||||
httpFacade.getResponse().getOutputStream().write(html.getBytes());
|
httpFacade.getResponse().getOutputStream().write(html.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
httpFacade.getResponse().end();
|
httpFacade.getResponse().end();
|
||||||
} else {
|
} else {
|
||||||
String uri = asRequest ? binding.redirectBinding(document).requestURI(actionUrl).toString() : binding.redirectBinding(document).responseURI(actionUrl).toString();
|
String uri = asRequest ? binding.redirectBinding(document).requestURI(actionUrl).toString() : binding.redirectBinding(document).responseURI(actionUrl).toString();
|
||||||
|
|||||||
+32
-12
@@ -60,6 +60,7 @@ import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
|||||||
import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil;
|
import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil;
|
||||||
import org.keycloak.saml.processing.web.util.PostBindingUtil;
|
import org.keycloak.saml.processing.web.util.PostBindingUtil;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -70,14 +71,11 @@ import java.security.KeyManagementException;
|
|||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.keycloak.dom.saml.v2.SAML2Object;
|
import org.keycloak.dom.saml.v2.SAML2Object;
|
||||||
import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
|
import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
|
||||||
import org.keycloak.rotation.KeyLocator;
|
import org.keycloak.rotation.KeyLocator;
|
||||||
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
||||||
import org.w3c.dom.Element;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -196,7 +194,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
|||||||
challenge = new AuthChallenge() {
|
challenge = new AuthChallenge() {
|
||||||
@Override
|
@Override
|
||||||
public boolean challenge(HttpFacade exchange) {
|
public boolean challenge(HttpFacade exchange) {
|
||||||
SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE);
|
SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE, statusResponse);
|
||||||
exchange.getRequest().setError(error);
|
exchange.getRequest().setError(error);
|
||||||
exchange.getResponse().sendError(403);
|
exchange.getResponse().sendError(403);
|
||||||
return true;
|
return true;
|
||||||
@@ -312,8 +310,25 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AuthOutcome handleLoginResponse(ResponseType responseType, boolean postBinding, OnSessionCreated onCreateSession) {
|
protected AuthOutcome handleLoginResponse(final ResponseType responseType, boolean postBinding, OnSessionCreated onCreateSession) {
|
||||||
AssertionType assertion = null;
|
AssertionType assertion = null;
|
||||||
|
if (! isSuccessfulSamlResponse(responseType) || responseType.getAssertions() == null || responseType.getAssertions().isEmpty()) {
|
||||||
|
challenge = new AuthChallenge() {
|
||||||
|
@Override
|
||||||
|
public boolean challenge(HttpFacade exchange) {
|
||||||
|
SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.ERROR_STATUS, responseType);
|
||||||
|
exchange.getRequest().setError(error);
|
||||||
|
exchange.getResponse().sendError(403);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResponseCode() {
|
||||||
|
return 403;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return AuthOutcome.FAILED;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey());
|
assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey());
|
||||||
if (AssertionUtil.hasExpired(assertion)) {
|
if (AssertionUtil.hasExpired(assertion)) {
|
||||||
@@ -335,6 +350,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
|||||||
return 403;
|
return 403;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
return AuthOutcome.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deployment.getIDP().getSingleSignOnService().validateAssertionSignature()) {
|
if (deployment.getIDP().getSingleSignOnService().validateAssertionSignature()) {
|
||||||
@@ -346,7 +362,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
|||||||
challenge = new AuthChallenge() {
|
challenge = new AuthChallenge() {
|
||||||
@Override
|
@Override
|
||||||
public boolean challenge(HttpFacade exchange) {
|
public boolean challenge(HttpFacade exchange) {
|
||||||
SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE);
|
SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE, responseType);
|
||||||
exchange.getRequest().setError(error);
|
exchange.getRequest().setError(error);
|
||||||
exchange.getResponse().sendError(403);
|
exchange.getResponse().sendError(403);
|
||||||
return true;
|
return true;
|
||||||
@@ -449,6 +465,14 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
|||||||
return AuthOutcome.AUTHENTICATED;
|
return AuthOutcome.AUTHENTICATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isSuccessfulSamlResponse(ResponseType responseType) {
|
||||||
|
return responseType != null
|
||||||
|
&& responseType.getStatus() != null
|
||||||
|
&& responseType.getStatus().getStatusCode() != null
|
||||||
|
&& responseType.getStatus().getStatusCode().getValue() != null
|
||||||
|
&& Objects.equals(responseType.getStatus().getStatusCode().getValue().toString(), JBossSAMLURIConstants.STATUS_SUCCESS.get());
|
||||||
|
}
|
||||||
|
|
||||||
private String getAttributeValue(Object attrValue) {
|
private String getAttributeValue(Object attrValue) {
|
||||||
String value = null;
|
String value = null;
|
||||||
if (attrValue instanceof String) {
|
if (attrValue instanceof String) {
|
||||||
@@ -571,12 +595,8 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
|||||||
key = locator.getKey(keyId);
|
key = locator.getKey(keyId);
|
||||||
boolean keyLocated = key != null;
|
boolean keyLocated = key != null;
|
||||||
|
|
||||||
if (validateRedirectBindingSignatureForKey(sigAlg, rawQueryBytes, decodedSignature, key)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyLocated) {
|
if (keyLocated) {
|
||||||
return false;
|
return validateRedirectBindingSignatureForKey(sigAlg, rawQueryBytes, decodedSignature, key);
|
||||||
}
|
}
|
||||||
} catch (KeyManagementException ex) {
|
} catch (KeyManagementException ex) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak SAML Jetty Integration</name>
|
<name>Keycloak SAML Jetty Integration</name>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak SAML Client Adapter Modules</name>
|
<name>Keycloak SAML Client Adapter Modules</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak SAML Tomcat Integration</name>
|
<name>Keycloak SAML Tomcat Integration</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+9
-4
@@ -182,10 +182,15 @@ public class SamlServletExtension implements ServletExtension {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
log.debug("Setting jsession cookie path to: " + deploymentInfo.getContextPath());
|
ServletSessionConfig cookieConfig = deploymentInfo.getServletSessionConfig();
|
||||||
ServletSessionConfig cookieConfig = new ServletSessionConfig();
|
if (cookieConfig == null) {
|
||||||
cookieConfig.setPath(deploymentInfo.getContextPath());
|
cookieConfig = new ServletSessionConfig();
|
||||||
deploymentInfo.setServletSessionConfig(cookieConfig);
|
}
|
||||||
|
if (cookieConfig.getPath() == null) {
|
||||||
|
log.debug("Setting jsession cookie path to: " + deploymentInfo.getContextPath());
|
||||||
|
cookieConfig.setPath(deploymentInfo.getContextPath());
|
||||||
|
deploymentInfo.setServletSessionConfig(cookieConfig);
|
||||||
|
}
|
||||||
addEndpointConstraint(deploymentInfo);
|
addEndpointConstraint(deploymentInfo);
|
||||||
|
|
||||||
ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
|
ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak SAML Wildfly Integration</name>
|
<name>Keycloak SAML Wildfly Integration</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../../pom.xml</relativePath>
|
<relativePath>../../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ public interface HttpFacade {
|
|||||||
*/
|
*/
|
||||||
String getURI();
|
String getURI();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the request relative path.
|
||||||
|
*
|
||||||
|
* @return the request relative path
|
||||||
|
*/
|
||||||
|
String getRelativePath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTPS?
|
* HTTPS?
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+5
@@ -78,6 +78,11 @@ public class JettyHttpFacade implements HttpFacade {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePath() {
|
||||||
|
return request.getServletPath();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFirstParam(String param) {
|
public String getFirstParam(String param) {
|
||||||
return request.getParameter(param);
|
return request.getParameter(param);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<name>Keycloak Client Adapter SPI Modules</name>
|
<name>Keycloak Client Adapter SPI Modules</name>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+5
@@ -65,6 +65,11 @@ public class ServletHttpFacade implements HttpFacade {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePath() {
|
||||||
|
return request.getServletPath();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecure() {
|
public boolean isSecure() {
|
||||||
return request.isSecure();
|
return request.isSecure();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+5
@@ -78,6 +78,11 @@ public class CatalinaHttpFacade implements HttpFacade {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePath() {
|
||||||
|
return request.getServletPath();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecure() {
|
public boolean isSecure() {
|
||||||
return request.isSecure();
|
return request.isSecure();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>keycloak-parent</artifactId>
|
<artifactId>keycloak-parent</artifactId>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<version>2.4.0.CR1-SNAPSHOT</version>
|
<version>2.5.2.Final</version>
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
+5
@@ -83,6 +83,11 @@ public class UndertowHttpFacade implements HttpFacade {
|
|||||||
return uriBuilder.build().toString();
|
return uriBuilder.build().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePath() {
|
||||||
|
return exchange.getRelativePath();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecure() {
|
public boolean isSecure() {
|
||||||
String protocol = exchange.getRequestScheme();
|
String protocol = exchange.getRequestScheme();
|
||||||
|
|||||||
Loaded 100 of 1447 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user