Beginning of changes to remove Axis dependency.
This commit is contained in:
parent
2a063797fe
commit
c5912db983
142
CASA-auth-token/server-java/Svc/external/xmlsec/KEYS
vendored
Normal file
142
CASA-auth-token/server-java/Svc/external/xmlsec/KEYS
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQGiBDxEPCgRBADeMrVI5GwYKss+WbhLYEHaDoyVHsK85zwGk5uv4cMKk4qsmrxu
|
||||
T15j/9SYHmlp9jNR7ZdzKSonVV8ME+qpWnCrwv/vKg4WuHELS8lk9FE5jXtn9MDH
|
||||
cDZllccnrRMFLJdDXJuYuYXRtBvt3ZEULUVsRwJAmFdZjrAxsEtFTdSvJQCg/x2X
|
||||
HwKkTutgVbQDrV7MUAMxP20D/Rj518EIR7zJ8+ev2lWV99RoZO/l44guwklwC3H+
|
||||
wqUhAJ898E7CQsHMOa1PsciYizl+YAQC0AQ3K9j64sj7hHD4ZNngWVOEOO7s36hl
|
||||
PTuzL2WOx76O49oCVtfxiM0DtKQolVMqN1OfiHHMFRIj1SFsruVBdEkwYKGvfVWk
|
||||
/LPiA/9Lb0fJlcQDdpGEtijnuMu2xTJMAb/Xcq6sSuZkl/Ykij64lk9BdsfcFRBr
|
||||
0Xh7KzqtADLZ8XPTJI6XZj+ytbWXXdi2Hahs4HK/y7vveErKiviYSxFhRlgpY6lV
|
||||
uiuIPENy/+wfZx3Fpdk2YDXeJIBN70FWAbmlDsvj3ZsnW1EQwLQsQ2hyaXN0aWFu
|
||||
IEdldWVyLVBvbGxtYW5uIDxnZXVlcnBAYXBhY2hlLm9yZz6JAFgEEBECABgFAjxE
|
||||
PCkICwMJCAcCAQoCGQEFGwMAAAAACgkQrc03WC8EhM0OzQCg2Pzsq+09gIsK6qTV
|
||||
quduJCHMNykAn0u+Rq2ftJQPXOwcUGvF4yxcsF54iQEcBBABAgAGBQI8RDxHAAoJ
|
||||
EE/ylwIE5/aVtAMIALcvI/B8FhjnS7RPJU1q9oCXdb5jgDVvXgFJEuDghSATxOjn
|
||||
Hrjtrsj1x9QdAY23lBDy4GKgiwwZDAy2hcmr2DL20AqdA6FAy8H1/7Cgl8MUNI2m
|
||||
Q2BjLnjuIlH9RZXhkJhUv4E7Np0IaRQMtCzW/oqu2LGRHqiq4R1ZiIhsHGfeAfrd
|
||||
2skJPTs+9SHg4dndfvueOS0mLbeOztwN5k1N2uHafFkcFCDx4vKjcn7+qnw/YaYG
|
||||
g2tsIGkwKr8dh+Yxf2Xhej7vRGgnNf1QMkvLFXiHEtx0o83GloR2bI8AFYp5ba9D
|
||||
veMXNk5SUUd5O9AOqMe1f74LMAIFtGC/K6aOCIGJAEYEEBECAAYFAjxEPFkACgkQ
|
||||
9kCJQ/wGyi3orACgiJIRnrQRN8ANs6xiKnwNdPLq6MsAoN3wyfQV5L1MV7zlO6ne
|
||||
FxdUBDBzuQINBDxEPCkQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoB
|
||||
p1ajFOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnh
|
||||
V5JZzf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr
|
||||
5fSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4
|
||||
XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zaf
|
||||
q9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/9LL8Uz61JXVOxZ
|
||||
C4hYgyP0SV0GgYoUiKmVbU1+/1dkiFvMV7beDJEDOKbVUurdpEKLTwO7s9YUAmp6
|
||||
6WvwtqGkCU7aHEsXMRSwSGoEXpQDHXHTwUjTtRvoBpd/LQ4t+ny1+B+p+PLt/cGJ
|
||||
RqvGHK/n9rlTb5jxzjCxRbhXqezmnJSwGG5fQD2mRtCQ9w3wgaxN/bVvxGnBgJO+
|
||||
TYo5PomNLa/24ujT4dPxKf2SFokuLJmgNRzRkaEtSV97t7lCYM05crOdcWbI2rPr
|
||||
c2FuzTig9gL4qB9QJRnpYI/VfbnsVAI+Qn66O+dPz7T2WNwj6CihodSdSxO3oo7Z
|
||||
rJsNjeOLiQBMBBgRAgAMBQI8RDwpBRsMAAAAAAoJEK3NN1gvBITNRqwAnRLnb+ng
|
||||
Bsho6M4hWqkwmdxRNw1xAJ9Jor374EYfbkYkHxejfoQUkJTmeg==
|
||||
=fPiH
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
pub 1024D/B990D401 2003-02-15 Berin Lautenbach <blautenb@apache.org>
|
||||
Key fingerprint = 03A7 690B E75C F9BF 15FF A362 7042 2E3D B990 D401
|
||||
sig 3 B990D401 2003-02-15 Berin Lautenbach <blautenb@apache.org>
|
||||
sig 609CD2C0 2003-02-15 Berin Lautenbach <berin@ozemail.com.au>
|
||||
sub 2048g/04284FDD 2003-02-15
|
||||
sig B990D401 2003-02-15 Berin Lautenbach <blautenb@apache.org>
|
||||
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.2.1 (GNU/Linux)
|
||||
|
||||
mQGiBD5OCBQRBACt0CGpKMnjauQ5FXwshMRRA+t706lf16ANsXBpdADkQTJXby0O
|
||||
Vj/c9xzyEGi+H3ODBl6BIqMkGZKXwVFfJus8ctBkvBs1vCObzVH6xxCzVzwFo+rc
|
||||
5mdJbf3EV65roAFLG1jbLgwadEgZumj7tNYuX8fpAZkVqR0FyE4q8Nr8PwCgzc4J
|
||||
6Za6y+on5Rw61cN6vyovJZsEAKoSupBUfs945BBnK+QwfgpWRKeybF4bO27rtAVH
|
||||
fFqEjOlBIM0tTbcA4q5T+1rFKOIOqsYVb50mVBybo6n4zRXOvZmoe5fAHlyN6GDA
|
||||
zn0ozfCd3e+skB1FBkxo/x6miWqv2ks5IF1VOYZRknGfudBhUoUZY0dintohxVuA
|
||||
eL71A/4tsx5TdPsZtUp7rfmOoj9S7F8As8rJ7ijfticdg6Z50IJKhuCsS3Vgwmnz
|
||||
Zi4QSlGfbvCql38Kdwhsyx2jjR3AK0GTeq4ik1jv+HmsW//OnA8CDEljVnyVKZz+
|
||||
hVx7sakniAXAggOXSRs8WE2aYZcwTKbUqJeRd1rA7DEJ/g2GEbQmQmVyaW4gTGF1
|
||||
dGVuYmFjaCA8YmxhdXRlbmJAYXBhY2hlLm9yZz6IVwQTEQIAFwUCPk4IFAULBwoD
|
||||
BAMVAwIDFgIBAheAAAoJEHBCLj25kNQByp8AnArT68V2aV8ti5epH9wc/FrVKbiS
|
||||
AKDMztjQXlkVYjsOhh6DIYabN3I8m4hGBBARAgAGBQI+TgkbAAoJEBf9q+hgnNLA
|
||||
Q5AAn2Lyyyq/Uy3T8zclslGQUby+1VaQAKCPL28vDFp2TrX07TDkXMJqJzI0TLkC
|
||||
DQQ+Tgg2EAgAm32VA74jozy/kz39ph0rbLnpJzYxnB9ksVmxEMgtj7x8+qth7CIH
|
||||
DjopxSYCf1j4RF3sHQtlyAZafbulV3mU7xA0vDq4fVsNLRV51NFjULHxSkt/rA6C
|
||||
KbjRq2qYIeCtaqivWUwxjKo06WmDq6dCavDdqf9J8opVv7QUvXiT/vV6yBzygkr0
|
||||
T1C9Gny4jiIryUSi1eWxbKLHLh1zj/zCgOjyDbsyKHF5wefF0PzNrak+IzTwP6gj
|
||||
FSLl+DFjEZsINDR1lKiAQucm2xfqLLttAEEXhW25D3/BuD92eVXx9bpz6kw4ZB9A
|
||||
Yk+4tbrr2ly4+9PDLCZjWGDSDAGWhlGYzwADBQf9HbL9wOex+LKDlSCW1ZckRvOK
|
||||
jGwvvhr8YUDinK7B3pYs3pLOVXxd14kHryhE8iEWnCrzgLMgJxS3/ryzvOOvL5Rr
|
||||
F9B94doNvxeUzk5Cn4ppMlmhB74Jp6QbXj7rVa5LpnphdrnNxMMRiWCEjrJMC1Og
|
||||
dokRWI9hAhyAYEqQKGt/Vy8o+FVs1yM4DxK8X0L6z6OnrpVqfNBDRs2R1lTs0G/u
|
||||
LS30dsBTXn5IZAYllb2VU3ocL40e45emmLTxVSvSRDBkcULYo4ZydNR9hMVy6TfU
|
||||
Q0cZZ6tpiL+exlYb6MeOQb5lbDzCnWQ5pOW7RCjOevyf6pFV7HUgSWAcJpNl/ohG
|
||||
BBgRAgAGBQI+Tgg2AAoJEHBCLj25kNQBeA0AoJ25w7yjduC3BedW4izdUCKcDZLe
|
||||
AJsEGTqwf0MYTdebbMXoZlVStqiRBQ==
|
||||
=e1F3
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.2.6 (GNU/Linux)
|
||||
|
||||
mQGiBEG1ilMRBACUX9pWnOfhIWK+aAZPydwqABQRmhBim0LqrmbqEcW/6Aaiv05H
|
||||
8+2Y88ENzhSUpoobx/mlkfi+H/sdi86J2zd26kPevykoXmPkQ+Dcj1sif7K21RIX
|
||||
b2QFoPD9lki6ffk8H38Xx/UaAz9xeyKZEBBMICUd/pFcJDwpwMa9AsGCxwCg5fBD
|
||||
8WeNuEqmV918e0UNCCfbvisD/R7iN2PrhCp3ERqGjmRM+TjgmfS8CnXinOYLNp5H
|
||||
lxgjdqy497VLEYoZgFGsG5TYyK9QmWYiQ4HdlwkSBQeZcIuhs+D/16HFXgXRTQhQ
|
||||
KN3hNOjn5vA6m6kEpkKis72Kvdn1lcWdWJNBTiXdK4O7232k1N+8pglF642M3fNB
|
||||
WzVSA/9sU5AbnU9cQ3wOitGhIONNPt76KjtNvS3AYuR+3Zo0KIaDd1Rxvfzob2xr
|
||||
t1unZRW2jd6FYVz2qtCHXG07bbkmRbttBDw0IJIPw9lkvdyF71WTZH+6U633TxLM
|
||||
3ZT+3TfcOi8fSQiWnJzASZ2Yy/ZfnG9YxmMhtuiDkAGbcR11UrQkUmF1bCBCZW5p
|
||||
dG8gR2FyY2lhIDxyYXVsQGFwYWNoZS5vcmc+iF4EExECAB4FAkG1ilMCGwMGCwkI
|
||||
BwMCAxUCAwMWAgECHgECF4AACgkQtImwQHrM6+xGlwCfVlNi4dz6bbPUyFqIZB5F
|
||||
7sKwe7YAoJ5yZ92LrG71QBp53PZu/d6F4zGwuQINBEG1imwQCACMhxnoh563xmVa
|
||||
xB4l0Zs1ZwXQ61aNJT67p+8vvGyzMQ0T2HYHt59ZyuWmV8U0kDQe4A8AVm7HnANZ
|
||||
1LyCiNM/3xLmNoZzek9dOqzBrJqtUjLXJSE81wZJzTscDdW9K6hoSIwnUYxzt0ie
|
||||
oup+Rm/BWSlSvSx35X9aFpcFM1Iru66nvolNfNgjGN4mpp2r/W3yOsW6DcapWmp0
|
||||
t891tGHU4E19DtjFmMC55eO9Vp3gxOpIP2MxICVB8GBkwMt4ecuoI++znJcBXpo+
|
||||
bvF75OaHeP9qVLy7UV1walZfO3fLO3GegI9oMiI4uvc9CYiJpBa3mBDNYr9Axl4z
|
||||
9ajJz9e3AAMFB/95RK3Ioh4u3cEE5jY7yLwSDAuqD6GjGHywqkmT6k5WOQHqy7HI
|
||||
Sjk5Aye3dyNyl5POTMPmSZn4u6lIlWSj1zbipmVF6UvlX9ei6YKTJo8pDcjSZdb6
|
||||
1vdeJd1l9taoKXHPE1u/xvNsZgH6+QjlGb1lxs0m/1qfNyzZqKPZNHXiqvVHMNH6
|
||||
vTSCqW+OO1aPnSEOcSq6NX6X9Un6n/p3WLu5eD+2eObYL0oCTMf7Idwlzo/kXDtp
|
||||
sCktwTR4pSPbXeMSaKztpWfXEz8CLQ2YIer66+b6Sbp1n+H/kPp+8aTZYs8fGZe0
|
||||
mRv4mbxIr041YpV4vLqbtPNvwMPNYcm+DHZBiEkEGBECAAkFAkG1imwCGwwACgkQ
|
||||
tImwQHrM6+wXfACgpdr9BhV7M2j5uype8R839dlGuyMAnREBnNTtKqss7+S87nyU
|
||||
KlDKaJbI
|
||||
=zQ4J
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
pub 1024D/6103BF59 9/5/2003 Davanum Srinivas (CODE SIGNING) <dims@apache.org>
|
||||
Primary key fingerprint: A67E 5FD8 80EB 089F 2317 7967 80D8 3A79 6103 BF59
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.3 (MingW32) - WinPT 0.11.12
|
||||
|
||||
mQGiBD9Y7IURBAD6qYBnCjMLzjfKqAtfBvmOHBLwfpv1NPZPQXbkpO15tRvU0FRX
|
||||
W9eoqgpRwFvc3+gMsnRuQ5t4pHM4qrbFYIPmGh+uA3CzhVmd9+b5v0WnbIpF7PGU
|
||||
ttvK7ICKUCewuHA0lYZ0hNjGynRLl2ehR9HCrPTZeTskq4iGYXsO5w7PEQCg/05A
|
||||
gW5oQIQr7YwvhorDFWiv/EsD/jILL+hmxKpKht1D+YJG6s+aHzMEHIG9/NAhjq6+
|
||||
K4L7ZdDoLjkX04oXXZjNsV3FZopMw9AtMlqELw4l6CIPEWOL6Tkh6/UmmnwpUuvr
|
||||
bXfYFvqhFckq4VgC52chLYmVoNI6YFhrhLFGoeluYY5e2oV+Rg4Wngn8FqmL4/Tl
|
||||
xUToA/4mMl4ECPUVPEA+5f7r/9lRI9B6qJPYTQ8gaGo2SxHS8t6AwnjEyGG7ZNWd
|
||||
rZSj2gsOS6BcyCXuiGwS1CUMr9oHvCprsLGai5i/d8DR/I89krUYVIymVcW3DqGa
|
||||
zXW6vSi5ryxDiYwWl5bS3JKr5cSMilLrlRuWx461Y3upuaaZ+bQxRGF2YW51bSBT
|
||||
cmluaXZhcyAoQ09ERSBTSUdOSU5HKSA8ZGltc0BhcGFjaGUub3JnPohOBBARAgAO
|
||||
BQI/WOyFBAsDAgECGQEACgkQgNg6eWEDv1md5gCgrhuJC5pQmpsVUzhb6s6qrky+
|
||||
lzoAoLWG370yw84vCTtm4rqukCxKckFxuQINBD9Y7IUQCAD2Qle3CH8IF3Kiutap
|
||||
QvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfU
|
||||
odNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7H
|
||||
AarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxb
|
||||
LY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyE
|
||||
pwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1Xp
|
||||
Mgs7AAICB/9A7c0FSYaXGQwQmwCNMc2HHuwJiUqgO50SDbjiYGyKDM9QCVonbu/V
|
||||
zKIJ1+caCnAaqlYZRXB53AYa3pk0teO39hT1YqNequfYcZdd7+R00YBPM409Ja4f
|
||||
Az/A9YYxC/IDiu0YOA+/kuZsatUv/mvOf6hW7UDr0BgFy79CAhhQZgwJm3rilkeu
|
||||
py5L3ns+H5EJ2/NI2IGbzcQMTWWFT4WY1LHreS7yPvDLvtlZmBhlEN0JZJQM5oRZ
|
||||
R1hOcSA5elQMYrn056I1u0FrX3TEZG/RPNkPv7C68sxEUmus0lviq4hqydKE/qgB
|
||||
qIEZEHhzgPrNhw1D/O59+ZN/WMzB9IigiEYEGBECAAYFAj9Y7IUACgkQgNg6eWED
|
||||
v1l9ygCghBaiVuzN0Z5XZw7IGyGEn4sqkvMAoMzWc6pmSDSX+6hmhli4WXCIsldH
|
||||
=yLoD
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
|
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-1_4_0/libs/commons-logging.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-1_4_0/libs/commons-logging.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-1_4_0/libs/xalan.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-1_4_0/libs/xalan.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-1_4_0/libs/xmlsec-1.4.0.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-1_4_0/libs/xmlsec-1.4.0.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-bin-1_4_0.zip
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-bin-1_4_0.zip
vendored
Normal file
Binary file not shown.
7
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-bin-1_4_0.zip.asc
vendored
Normal file
7
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-bin-1_4_0.zip.asc
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.5 (Cygwin)
|
||||
|
||||
iD8DBQBFhwWdtImwQHrM6+wRAt6YAKDD2KsP/owrw4SWu7bfdejXr4NbOwCeMhyd
|
||||
1EPh+zzlfrSAoEatfVB3lYI=
|
||||
=R9lz
|
||||
-----END PGP SIGNATURE-----
|
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-src-1_4_0.zip
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-src-1_4_0.zip
vendored
Normal file
Binary file not shown.
7
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-src-1_4_0.zip.asc
vendored
Normal file
7
CASA-auth-token/server-java/Svc/external/xmlsec/xml-security-src-1_4_0.zip.asc
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.5 (Cygwin)
|
||||
|
||||
iD8DBQBFhwWotImwQHrM6+wRAtvUAJ9R6uUWCw+1RYfAi4AO7srYQ7mxUwCdGDPn
|
||||
L02dDJKgli5he+UE3GQGWss=
|
||||
=sMrX
|
||||
-----END PGP SIGNATURE-----
|
@ -26,21 +26,17 @@ package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.apache.axis.Message;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.client.AxisClient;
|
||||
import org.apache.axis.configuration.NullProvider;
|
||||
import org.apache.axis.message.SOAPEnvelope;
|
||||
import org.apache.axis.message.SOAPBody;
|
||||
import org.apache.axis.message.MessageElement;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.xml.serialize.OutputFormat;
|
||||
import org.apache.xml.serialize.XMLSerializer;
|
||||
import org.apache.xml.security.utils.Constants;
|
||||
import org.apache.xerces.parsers.DOMParser;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.io.*;
|
||||
|
||||
// Un-comment the following line to print Authentication Token Messages
|
||||
//import org.apache.axis.utils.XMLUtils;
|
||||
|
||||
|
||||
/**
|
||||
* AuthToken Class.
|
||||
@ -51,7 +47,10 @@ import java.io.*;
|
||||
* and with a timestamp. The body of the SOAP message is as follows:
|
||||
* <p>
|
||||
* <auth_token>
|
||||
* <ident_token><type>Identity Token type</type>identity token data</ident_token>
|
||||
* <ident_token>
|
||||
* <ident_token_provider>Identity Token type</ident_token_provider>
|
||||
* <ident_token_data>identity token data</ident_token_datar>
|
||||
* </ident_token>
|
||||
* </auth_token>
|
||||
*
|
||||
*/
|
||||
@ -65,18 +64,9 @@ public final class AuthToken
|
||||
private String m_identityTokenType = null;
|
||||
private String m_identityToken = null;
|
||||
|
||||
static final String authTokenSoapMsg =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<SOAP-ENV:Envelope" +
|
||||
" xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"\n" +
|
||||
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" +
|
||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
" <SOAP-ENV:Body>" +
|
||||
" <auth_token><ident_token><type></type></ident_token></auth_token>" +
|
||||
" </SOAP-ENV:Body>" +
|
||||
"</SOAP-ENV:Envelope>";
|
||||
static private SecureTokenUtil m_serverSecTokenUtil = null;
|
||||
static private SecureTokenUtil m_clientSecTokenUtil = null;
|
||||
|
||||
static final private MessageContext axisMsgContext = new MessageContext(new AxisClient(new NullProvider()));
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -102,61 +92,90 @@ public final class AuthToken
|
||||
AuthTokenConfig authTokenConfig = enabledSvcsConfig.getAuthTokenConfig(targetHost, targetService);
|
||||
if (authTokenConfig != null)
|
||||
{
|
||||
OutputStream outStream = null;
|
||||
try
|
||||
// For now lets use the services of the only IdentityToken provider
|
||||
// that we have.
|
||||
//
|
||||
// tbd - Add code to allow for the consumption of tokens
|
||||
// from different providers.
|
||||
CasaIdentityToken identityToken = new CasaIdentityToken(enabledSvcsConfig.getIdenTokenConfig(targetHost, targetService));
|
||||
identityToken.initialize(identityId,
|
||||
realm,
|
||||
realmUrl,
|
||||
targetService,
|
||||
targetHost,
|
||||
svcConfig);
|
||||
|
||||
m_identityToken = identityToken.getEncodedToken();
|
||||
m_identityTokenType = identityToken.getProviderType();
|
||||
|
||||
m_lifetime = authTokenConfig.getSetting(AuthTokenConfig.TokenLifetime);
|
||||
m_lifetimeShorter = authTokenConfig.getSetting(AuthTokenConfig.LifetimeShorter);
|
||||
|
||||
// Get secure token util object
|
||||
SecureTokenUtil secTokenUtil = getSecureTokenUtilObj(true);
|
||||
if (secTokenUtil != null)
|
||||
{
|
||||
// For now lets use the services of the only IdentityToken provider
|
||||
// that we have.
|
||||
//
|
||||
// tbd - Add code to allow for the consumption of tokens
|
||||
// from different providers.
|
||||
CasaIdentityToken identityToken = new CasaIdentityToken(enabledSvcsConfig.getIdenTokenConfig(targetHost, targetService));
|
||||
identityToken.initialize(identityId,
|
||||
realm,
|
||||
realmUrl,
|
||||
targetService,
|
||||
targetHost,
|
||||
svcConfig);
|
||||
|
||||
m_identityToken = identityToken.getEncodedToken();
|
||||
m_identityTokenType = identityToken.getProviderType();
|
||||
|
||||
m_lifetime = authTokenConfig.getSetting(AuthTokenConfig.TokenLifetime);
|
||||
m_lifetimeShorter = authTokenConfig.getSetting(AuthTokenConfig.LifetimeShorter);
|
||||
|
||||
// Create AuthTokenMessage
|
||||
Message authTokenMessage = getMessage(identityToken.getEncodedToken(),
|
||||
identityToken.getProviderType(),
|
||||
Integer.valueOf(m_lifetime).intValue(),
|
||||
svcConfig,
|
||||
(targetHost.compareTo("localhost") == 0) ? false : true);
|
||||
|
||||
// Un-comment the following line to print Authentication Token Messages
|
||||
//XMLUtils.PrettyElementToWriter(authTokenMessage.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
|
||||
|
||||
// Now save the message as a string
|
||||
outStream = new ByteArrayOutputStream();
|
||||
authTokenMessage.writeTo(outStream);
|
||||
m_token = outStream.toString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.error("Constructor()- Exception: " + e.toString());
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (outStream != null)
|
||||
// Obtain secure token template document
|
||||
Document tokenDoc = SecureTokenUtil.getSecureTokenTemplate();
|
||||
if (tokenDoc != null)
|
||||
{
|
||||
// Secure token template obtained, now get its top most element.
|
||||
Node tokenElement = tokenDoc.getDocumentElement();
|
||||
|
||||
// Add authentication token payload to the token
|
||||
Node soapBodyElement = SecureTokenUtil.findChildNodeNS(tokenElement, "http://www.w3.org/2003/05/soap-envelope", "Body");
|
||||
Node authTokenElement = tokenDoc.createElement("auth_token");
|
||||
soapBodyElement.appendChild(authTokenElement);
|
||||
Node idenTokenElement = tokenDoc.createElement("ident_token");
|
||||
authTokenElement.appendChild(idenTokenElement);
|
||||
Node idenTokenProviderElement = tokenDoc.createElement("ident_token_provider");
|
||||
idenTokenProviderElement.setTextContent(m_identityTokenType);
|
||||
idenTokenElement.appendChild(idenTokenProviderElement);
|
||||
Node idenTokenDataElement = tokenDoc.createElement("ident_token_data");
|
||||
idenTokenDataElement.setTextContent(m_identityTokenType);
|
||||
idenTokenElement.appendChild(idenTokenDataElement);
|
||||
|
||||
// Secure the token
|
||||
secTokenUtil.secure(tokenDoc, Integer.valueOf(m_lifetime).intValue());
|
||||
|
||||
// Now save the token as a string
|
||||
OutputStream outStream = null;
|
||||
try
|
||||
{
|
||||
outStream.close();
|
||||
outStream = new ByteArrayOutputStream();
|
||||
OutputFormat format = new OutputFormat(tokenDoc);
|
||||
XMLSerializer serializer = new XMLSerializer(outStream, format);
|
||||
serializer.serialize(tokenDoc.getDocumentElement());
|
||||
m_token = outStream.toString();
|
||||
}
|
||||
catch (IOException e)
|
||||
finally
|
||||
{
|
||||
// Do nothing
|
||||
if (outStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to obtain secure token template
|
||||
m_log.warn("Constructor()- Failed to obtain secure token template");
|
||||
throw new Exception("AuthToken.Constructor()- Failed to obtain secure token template");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to obtain secure token util object
|
||||
m_log.warn("Constructor()- Failed to obtain secure token util object");
|
||||
throw new Exception("SessionToken.Constructor()- Failed to obtain secure token util object");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -177,24 +196,106 @@ public final class AuthToken
|
||||
public AuthToken(String token,
|
||||
boolean encodedToken) throws Exception
|
||||
{
|
||||
// Decode the token string if necessary
|
||||
if (encodedToken)
|
||||
m_token = Base64Coder.decode(token);
|
||||
else
|
||||
m_token = token;
|
||||
|
||||
// Now instantiate a SOAP message with the string
|
||||
InputStream inStream = null;
|
||||
org.apache.axis.Message message = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Decode the token string if necessary
|
||||
if (encodedToken)
|
||||
m_token = Base64Coder.decode(token);
|
||||
else
|
||||
m_token = token;
|
||||
|
||||
// Now instantiate token document with the token string
|
||||
inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||
message = new Message(inStream);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.warn("Constructor()- Exception caught creating message, msg: " + e.getMessage());
|
||||
throw new Exception("Invalid Authentication Token", e);
|
||||
Constants.setSignatureSpecNSprefix("");
|
||||
|
||||
DOMParser parser = new DOMParser();
|
||||
parser.setFeature("http://xml.org/sax/features/namespaces", true);
|
||||
parser.parse(new InputSource(inStream));
|
||||
Document tokenDoc = parser.getDocument();
|
||||
|
||||
// Obtain secure token util object
|
||||
SecureTokenUtil secTokenUtil = getSecureTokenUtilObj(false);
|
||||
if (secTokenUtil != null)
|
||||
{
|
||||
// Use the secure token util to validate the token
|
||||
if (secTokenUtil.valid(tokenDoc))
|
||||
{
|
||||
// The authentication token is valid, now obtain the identity token
|
||||
// information from it.
|
||||
Node tokenElement = tokenDoc.getDocumentElement();
|
||||
if (tokenElement != null)
|
||||
{
|
||||
Node soapBodyElement = SecureTokenUtil.findChildNodeNS(tokenElement,
|
||||
"http://www.w3.org/2003/05/soap-envelope",
|
||||
"Body");
|
||||
if (soapBodyElement != null)
|
||||
{
|
||||
Node authTokenElement = SecureTokenUtil.findChildNode(soapBodyElement, "auth_token");
|
||||
if (authTokenElement != null)
|
||||
{
|
||||
Node identTokenElement = SecureTokenUtil.findChildNode(authTokenElement, "ident_token");
|
||||
if (identTokenElement != null)
|
||||
{
|
||||
Node identTokenProviderElement = SecureTokenUtil.findChildNode(identTokenElement,
|
||||
"ident_token_provider");
|
||||
Node identTokenDataElement = SecureTokenUtil.findChildNode(identTokenElement,
|
||||
"ident_token_data");
|
||||
if (identTokenProviderElement != null
|
||||
&& identTokenDataElement != null)
|
||||
{
|
||||
m_identityTokenType = identTokenProviderElement.getTextContent();
|
||||
m_identityToken = identTokenDataElement.getTextContent();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing identity token element child
|
||||
m_log.warn("Constructor(String)- Unable to obtain identity token element child");
|
||||
throw new Exception("AuthToken.Constructor(String)- Unable to obtain identity token element child");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing ident token element
|
||||
m_log.warn("Constructor(String)- Unable to obtain ident token element");
|
||||
throw new Exception("AuthToken.Constructor(String)- Unable to obtain ident token element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing auth token element
|
||||
m_log.warn("Constructor(String)- Unable to obtain auth token element");
|
||||
throw new Exception("AuthToken.Constructor(String)- Unable to obtain auth token element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid SOAP message
|
||||
m_log.warn("Constructor(String)- Unable to obtain soap body element");
|
||||
throw new Exception("AuthToken.Constructor(String)- Unable to obtain soap body element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid XML document
|
||||
m_log.warn("Constructor(String)- Unable to obtain document element");
|
||||
throw new Exception("AuthToken.Constructor(String)- Unable to obtain document element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message verification failed
|
||||
m_log.warn("Constructor(String)- Invalid Auth Token");
|
||||
throw new Exception("AuthToken.Constructor(String)- Invalid Auth Token");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to obtain secure token util object
|
||||
m_log.warn("Constructor(String)- Failed to obtain secure token util object");
|
||||
throw new Exception("AuthToken.Constructor(String)- Failed to obtain secure token util object");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -210,114 +311,57 @@ public final class AuthToken
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get access to the SOAP Envelope
|
||||
SOAPEnvelope envelope = message.getSOAPEnvelope();
|
||||
|
||||
// Verify the message
|
||||
if (WSSecurity.verifyMessage(envelope))
|
||||
{
|
||||
// Message verification succeded, now obtain the identity token
|
||||
// and its type from the message body.
|
||||
SOAPBody body = (SOAPBody) envelope.getBody();
|
||||
QName authTokenElementName = new QName("auth_token");
|
||||
MessageElement authTokenElement = body.getChildElement(authTokenElementName);
|
||||
QName identTokenElementName = new QName("ident_token");
|
||||
MessageElement identTokenElement = authTokenElement.getChildElement(identTokenElementName);
|
||||
if (identTokenElement != null)
|
||||
{
|
||||
QName identTokenTypeElementName = new QName("type");
|
||||
MessageElement identTokenTypeElement = identTokenElement.getChildElement(identTokenTypeElementName);
|
||||
if (identTokenTypeElement != null)
|
||||
{
|
||||
m_identityToken = identTokenElement.getChildNodes().item(1).getNodeValue();
|
||||
m_identityTokenType = identTokenTypeElement.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_identityToken == null || m_identityTokenType == null)
|
||||
{
|
||||
m_log.warn("Constructor()- Required data missing from authentication token");
|
||||
throw new Exception("Error: Required data missing from Authentication Token");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message verification failed
|
||||
m_log.warn("Constructor()- Invalid Authentication Token");
|
||||
throw new Exception("Invalid Authentication Token");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AuthToken SOAP Message.
|
||||
* Gets object to be utilized for creating and verifying secure tokens.
|
||||
*
|
||||
* @param identityToken String containing the identity token that should be part of the message.
|
||||
* @param identityTokenType String containing the identity token type.
|
||||
* @param lifetime Lifetime that should be specified in the message timestamp (seconds).
|
||||
* @param svcConfig Service configuration object.
|
||||
* @param includeCert True if the message should include the Public Certificate.
|
||||
* @return AuthToken message, null if the method fails.
|
||||
* @param serverMode True if to be used to secure tokens.
|
||||
* @return SecuteTokenUtil object or null if the method fails.
|
||||
*/
|
||||
private static Message getMessage(String identityToken,
|
||||
String identityTokenType,
|
||||
int lifetime,
|
||||
SvcConfig svcConfig,
|
||||
boolean includeCert)
|
||||
private static synchronized SecureTokenUtil getSecureTokenUtilObj(boolean serverMode)
|
||||
{
|
||||
Message secureMessage;
|
||||
InputStream inStream = null;
|
||||
|
||||
try
|
||||
// Proceed based on the mode spacified
|
||||
if (serverMode)
|
||||
{
|
||||
// Build SOAP Message with an identity token in the body
|
||||
//
|
||||
// First create a message and obtain its body
|
||||
inStream = new ByteArrayInputStream(authTokenSoapMsg.getBytes());
|
||||
Message message = new Message(inStream);
|
||||
message.setMessageContext(axisMsgContext);
|
||||
SOAPBody body = (SOAPBody) message.getSOAPBody();
|
||||
|
||||
// Get access to the auth_token element
|
||||
QName authTokenElementName = new QName("auth_token");
|
||||
MessageElement authTokenElement = body.getChildElement(authTokenElementName);
|
||||
|
||||
// Get access to the ident_token element and set its value
|
||||
QName identTokenElementName = new QName("ident_token");
|
||||
MessageElement identTokenElement = authTokenElement.getChildElement(identTokenElementName);
|
||||
identTokenElement.addTextNode(identityToken);
|
||||
|
||||
// Get access to the identity token type element element and set its value
|
||||
QName identTokenTypeElementName = new QName("type");
|
||||
MessageElement identTokenTypeElement = identTokenElement.getChildElement(identTokenTypeElementName);
|
||||
identTokenTypeElement.setValue(identityTokenType);
|
||||
|
||||
// Now we need to secure the SOAP message that we created, we are doing to
|
||||
// do so by adding a timestamp and signing the timestamp as well as the body.
|
||||
// To do this we are going to leverage WS-Security.
|
||||
secureMessage = WSSecurity.secureSOAPEnvelope(message.getSOAPEnvelope(),
|
||||
lifetime,
|
||||
svcConfig,
|
||||
includeCert);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.error("getMessage() - Exception caught building message, error: " + e.getMessage());
|
||||
secureMessage = null;
|
||||
}
|
||||
if (inStream != null)
|
||||
{
|
||||
try
|
||||
// Instantiate the server object if it has not been instantiated already
|
||||
if (m_serverSecTokenUtil == null)
|
||||
{
|
||||
inStream.close();
|
||||
try
|
||||
{
|
||||
// Instantiate secure token object to be utilized in server type operations
|
||||
m_serverSecTokenUtil = new SecureTokenUtil(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Exception caught
|
||||
m_log.warn("getSecureTokenUtilObj()- Exception caught, message = " + e.getMessage());
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
return secureMessage;
|
||||
// Return the object
|
||||
return m_serverSecTokenUtil;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Instantiate the client object if it has not been instantiated already
|
||||
if (m_clientSecTokenUtil == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Instantiate secure token object to be utilized in server type operations
|
||||
m_clientSecTokenUtil = new SecureTokenUtil(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Exception caught
|
||||
m_log.warn("getSecureTokenUtilObj()- Exception caught, message = " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Return the object
|
||||
return m_clientSecTokenUtil;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -346,8 +346,7 @@ public final class Authenticate implements RpcMethod
|
||||
// An identity was resolved, get a SessionToken for it.
|
||||
SessionToken sessionToken = new SessionToken(identId,
|
||||
authReqMsg.getRealm(),
|
||||
m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime),
|
||||
m_svcConfig);
|
||||
m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime));
|
||||
|
||||
// Write out the response
|
||||
String respLifetime = Integer.toString(Integer.valueOf(m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime)).intValue()
|
||||
|
@ -0,0 +1,749 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
//package com.novell.casa.authtoksvc;
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import org.apache.xml.security.c14n.Canonicalizer;
|
||||
import org.apache.xml.security.utils.Constants;
|
||||
import org.apache.xml.security.signature.XMLSignature;
|
||||
import org.apache.xml.security.transforms.Transforms;
|
||||
import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
|
||||
import org.apache.xml.security.keys.content.X509Data;
|
||||
import org.apache.xerces.parsers.DOMParser;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import java.util.*;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
|
||||
/**
|
||||
* SecureTokenUtil Class.
|
||||
* <p>
|
||||
* This class provides methods for creating secure tokens. Tokens are secured in SOAP messages
|
||||
* by applying a timestamp and signing the appropriate elements. The class utilizes XMlSec and
|
||||
* headers defined by WS* specifications.
|
||||
*
|
||||
*/
|
||||
public final class SecureTokenUtil
|
||||
{
|
||||
private static final Logger m_log = Logger.getLogger(SecureTokenUtil.class);
|
||||
|
||||
// Signing key and related certificate
|
||||
private PrivateKey m_signingKey;
|
||||
private X509Certificate m_signingCert;
|
||||
|
||||
// Certificate issuer:sn map
|
||||
//
|
||||
// The map key has the format: "IssuerDN=certissuername SN=certserialnumber"
|
||||
private Map<String,X509Certificate> m_x509ISNCertMap;
|
||||
|
||||
// SecureToken template
|
||||
private static final String m_secureTokenTemplate =
|
||||
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"" +
|
||||
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" +
|
||||
" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"" +
|
||||
" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"" +
|
||||
" xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">" +
|
||||
"<SOAP-ENV:Header>" +
|
||||
"<wsse:Security SOAP-ENV:mustUnderstand=\"true\">" +
|
||||
"<wsu:Timestamp wsu:Id=\"CASA-TIMESTAMP\">" +
|
||||
"<wsu:Created></wsu:Created>" +
|
||||
"<wsu:Expires></wsu:Expires>" +
|
||||
"</wsu:Timestamp>" +
|
||||
"</wsse:Security>" +
|
||||
"</SOAP-ENV:Header>" +
|
||||
"<SOAP-ENV:Body wsu:Id=\"CASA-SOAPBODY\">" +
|
||||
"</SOAP-ENV:Body>" +
|
||||
"</SOAP-ENV:Envelope>";
|
||||
|
||||
/**
|
||||
* SecureTokenUtil Constructor.
|
||||
* <p/>
|
||||
* @param serverMode Running as server and will be creating secure tokens.
|
||||
* @throws Exception
|
||||
*/
|
||||
public SecureTokenUtil(boolean serverMode) throws Exception
|
||||
{
|
||||
InputStream inStream = null;
|
||||
try
|
||||
{
|
||||
// Load our crypto properties
|
||||
Properties cryptoProperties = new Properties();
|
||||
ClassLoader classLoader = SecureTokenUtil.class.getClassLoader();
|
||||
inStream = classLoader.getResourceAsStream("crypto.properties");
|
||||
cryptoProperties.load(inStream);
|
||||
|
||||
// Get necessary keystore info from the crypto properties
|
||||
String keystoreType = cryptoProperties.getProperty("org.apache.ws.security.crypto.merlin.keystore.type", "jks");
|
||||
String keystoreFile = cryptoProperties.getProperty("org.apache.ws.security.crypto.merlin.file");
|
||||
String keystorePass = cryptoProperties.getProperty("org.apache.ws.security.crypto.merlin.keystore.password");
|
||||
if (keystoreType == null
|
||||
|| keystoreFile == null
|
||||
|| keystorePass == null)
|
||||
{
|
||||
m_log.error("Constructor()- Missing crypto configuration");
|
||||
throw new Exception("SecureTokenUtil()- Missing crypto configuration");
|
||||
}
|
||||
|
||||
// Instantiate and load the keystore
|
||||
KeyStore keyStore = KeyStore.getInstance(keystoreType);
|
||||
FileInputStream fis = new FileInputStream(keystoreFile);
|
||||
keyStore.load(fis, keystorePass.toCharArray());
|
||||
|
||||
// Get signing key and cert if in server mode
|
||||
if (serverMode)
|
||||
{
|
||||
String privateKeyAlias = cryptoProperties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
|
||||
String privateKeyPass = cryptoProperties.getProperty("org.apache.ws.security.crypto.merlin.alias.password");
|
||||
String certificateAlias = cryptoProperties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
|
||||
if (privateKeyAlias == null
|
||||
|| privateKeyPass == null
|
||||
|| certificateAlias == null)
|
||||
{
|
||||
m_log.error("Constructor()- Missing crypto configuration");
|
||||
throw new Exception("SecureTokenUtil()- Missing crypto configuration");
|
||||
}
|
||||
|
||||
// Get the key that will be used for signing tokens
|
||||
m_signingKey = (PrivateKey) keyStore.getKey(privateKeyAlias,
|
||||
privateKeyPass.toCharArray());
|
||||
if (m_signingKey == null)
|
||||
{
|
||||
m_log.error("Constructor()- Signing key not found in keystore");
|
||||
throw new Exception("SecureTokenUtil()- Signing key not found in keystore");
|
||||
}
|
||||
|
||||
// Get the signing certificate
|
||||
m_signingCert = (X509Certificate) keyStore.getCertificate(certificateAlias);
|
||||
if (m_signingCert == null)
|
||||
{
|
||||
m_log.error("Constructor()- Signing cert not found in keystore");
|
||||
throw new Exception("SecureTokenUtil()- Signing cert not found in keystore");
|
||||
}
|
||||
}
|
||||
|
||||
// Create the Certificate issuer:sn map
|
||||
m_x509ISNCertMap = new HashMap<String,X509Certificate>();
|
||||
Enumeration<String> aliases = keyStore.aliases();
|
||||
while (aliases.hasMoreElements())
|
||||
{
|
||||
X509Certificate cert = (X509Certificate) keyStore.getCertificate(aliases.nextElement());
|
||||
if (cert != null)
|
||||
{
|
||||
// Add this certificate to our map
|
||||
m_x509ISNCertMap.put("IssuerDN=" + cert.getIssuerDN().getName() + " SN=" + cert.getSerialNumber().toString(), cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Make sure that the input stream has been closed
|
||||
if (inStream != null)
|
||||
inStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the referenced X509Certificate.
|
||||
*
|
||||
* @param issuerName Name of the certificate issuer.
|
||||
* @param serialNumber Certificate serial number.
|
||||
* @return Referenced X509Certificate.
|
||||
*/
|
||||
private X509Certificate getCertWithX509IssuerSerialData(String issuerName, String serialNumber)
|
||||
{
|
||||
return m_x509ISNCertMap.get("IssuerDN=" + issuerName + " SN=" + serialNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove white space from XML.
|
||||
* <p/>
|
||||
* Note that this operation is recursively performed,
|
||||
* thus limiting document depth.
|
||||
*
|
||||
* @param startNode Start node.
|
||||
*/
|
||||
private void removeWhiteSpace(Node startNode)
|
||||
{
|
||||
// Loop through child nodes
|
||||
Node childNode;
|
||||
Node nextNode = startNode.getFirstChild();
|
||||
while ((childNode = nextNode) != null) {
|
||||
|
||||
// Set next before we change anything
|
||||
nextNode = childNode.getNextSibling();
|
||||
|
||||
// Handle child by node type
|
||||
if (childNode.getNodeType() == Node.TEXT_NODE)
|
||||
{
|
||||
// Trim whitespace from content text
|
||||
String trimmed = childNode.getNodeValue().trim();
|
||||
if (trimmed.length() == 0)
|
||||
{
|
||||
// Delete child if nothing but whitespace
|
||||
startNode.removeChild(childNode);
|
||||
}
|
||||
}
|
||||
else if (childNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
// Handle child elements with recursive call
|
||||
removeWhiteSpace(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specified prefix on elements in the specified namespace
|
||||
* and remove the namespace attribute from them.
|
||||
* <p/>
|
||||
* Note that this operation is recursively performed,
|
||||
* thus limiting document depth.
|
||||
*
|
||||
* @param startNode Start node.
|
||||
* @param prefix Prefix.
|
||||
* @param nsURI Name space URI.
|
||||
*/
|
||||
private void setPrefixSubtree(Node startNode, String prefix, String nsURI)
|
||||
{
|
||||
// Set the prefix on the element if necessary
|
||||
if (startNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
NamedNodeMap attributes = startNode.getAttributes();
|
||||
Node nsAttr = attributes.getNamedItem("xmlns");
|
||||
if (nsAttr != null)
|
||||
{
|
||||
if (nsAttr.getTextContent().equalsIgnoreCase(nsURI))
|
||||
{
|
||||
attributes.removeNamedItem("xmlns");
|
||||
startNode.setPrefix(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through child nodes
|
||||
Node childNode;
|
||||
Node nextNode = startNode.getFirstChild();
|
||||
while ((childNode = nextNode) != null) {
|
||||
|
||||
// Set next before we change anything
|
||||
nextNode = childNode.getNextSibling();
|
||||
|
||||
// Handle child by node type
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
// Handle child elements with recursive call
|
||||
setPrefixSubtree(childNode, prefix, nsURI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first child node with matching node name.
|
||||
*
|
||||
* @param parentNode Parent node.
|
||||
* @param nodeName Name of node.
|
||||
* @return Child node found or null.
|
||||
*/
|
||||
public static Node findChildNode(Node parentNode, String nodeName)
|
||||
{
|
||||
Node retNode = null;
|
||||
Node childNode;
|
||||
Node nextNode = parentNode.getFirstChild();
|
||||
while ((childNode = nextNode) != null)
|
||||
{
|
||||
// Set next before we change anything
|
||||
nextNode = childNode.getNextSibling();
|
||||
|
||||
// Handle child by node type
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
// Check if this is the element node wanted
|
||||
if (childNode.getNodeName().equalsIgnoreCase(nodeName))
|
||||
{
|
||||
// Found the node
|
||||
retNode = childNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first child node with matching node name.
|
||||
*
|
||||
* @param parentNode Parent node.
|
||||
* @param nsURI Namespace URI.
|
||||
* @param nodeLocalName Local name of node.
|
||||
* @return Child node found or null.
|
||||
*/
|
||||
public static Node findChildNodeNS(Node parentNode, String nsURI, String nodeLocalName)
|
||||
{
|
||||
Node retNode = null;
|
||||
Node childNode;
|
||||
Node next = parentNode.getFirstChild();
|
||||
while ((childNode = next) != null)
|
||||
{
|
||||
// Set next before we change anything
|
||||
next = childNode.getNextSibling();
|
||||
|
||||
// Handle child by node type
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
// Check if this is the element node wanted
|
||||
if (childNode.getLocalName().equalsIgnoreCase(nodeLocalName)
|
||||
&& childNode.getNamespaceURI().equals(nsURI))
|
||||
{
|
||||
// Found the node
|
||||
retNode = childNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timestamp element.
|
||||
*
|
||||
* @param timeStampNode Timestamp node.
|
||||
* @param ttl Time to live in seconds.
|
||||
* @throws Exception
|
||||
*/
|
||||
private void setTimeStamp(Node timeStampNode, long ttl) throws Exception
|
||||
{
|
||||
boolean success = false;
|
||||
|
||||
// Find the Created and Expires nodes
|
||||
Node wsCreated = findChildNode(timeStampNode, "wsu:Created");
|
||||
Node wsExpires = findChildNode(timeStampNode, "wsu:Expires");
|
||||
if (wsCreated != null
|
||||
&& wsExpires != null)
|
||||
{
|
||||
// We found the nodes, now set the needed information in them.
|
||||
SimpleDateFormat ISO8601UTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
ISO8601UTC.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
Date date = new Date();
|
||||
|
||||
wsCreated.setTextContent(ISO8601UTC.format(date));
|
||||
|
||||
date.setTime(date.getTime() + (ttl * 1000));
|
||||
wsExpires.setTextContent(ISO8601UTC.format(date));
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
// Throw exception if not successful
|
||||
if (!success)
|
||||
{
|
||||
m_log.error("setTimeStamp()- Failed to set timestamp");
|
||||
throw new Exception("SecureTokenUtil.setTimeStamp()- Failed to set timestamp");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates timestamp element.
|
||||
*
|
||||
* @param timeStampNode Timestamp node.
|
||||
* @throws Exception
|
||||
*/
|
||||
private void validateTimeStamp(Node timeStampNode) throws Exception
|
||||
{
|
||||
// Find Expires node
|
||||
Node wsExpires = findChildNodeNS(timeStampNode,
|
||||
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
|
||||
"Expires");
|
||||
if (wsExpires != null)
|
||||
{
|
||||
// We found the node, now check if it has expired.
|
||||
SimpleDateFormat ISO8601UTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
ISO8601UTC.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
Date currDate = new Date();
|
||||
Date expiresDate = ISO8601UTC.parse(wsExpires.getTextContent());
|
||||
if (currDate.compareTo(expiresDate) > 0)
|
||||
{
|
||||
m_log.warn("validateTimeStamp()- Timestamp expired");
|
||||
throw new Exception("SecureTokenUtil.validateTimeStamp()- Timestamp expired");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.error("validateTimeStamp()- Bad timestamp element");
|
||||
throw new Exception("SecureTokenUtil.validateTimeStamp()- Bad timestamp element");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates secure token.
|
||||
*
|
||||
* @param tokenDoc Token document.
|
||||
* @return True if validation succeeded.
|
||||
*/
|
||||
public boolean valid(Document tokenDoc)
|
||||
{
|
||||
boolean msgVerificationStatus = false;
|
||||
|
||||
try
|
||||
{
|
||||
// Get document element
|
||||
Element docElement = tokenDoc.getDocumentElement();
|
||||
|
||||
// Find the relevant nodes in the document
|
||||
Node soapHeaderNode = findChildNodeNS(docElement, "http://www.w3.org/2003/05/soap-envelope", "Header");
|
||||
Node soapBodyNode = findChildNodeNS(docElement, "http://www.w3.org/2003/05/soap-envelope", "Body");
|
||||
if (soapHeaderNode != null && soapBodyNode != null)
|
||||
{
|
||||
// We found the header of the message, now find the
|
||||
// WS-Security node.
|
||||
Node wsSecurityNode = findChildNodeNS(soapHeaderNode,
|
||||
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
|
||||
"Security");
|
||||
if (wsSecurityNode != null)
|
||||
{
|
||||
// We found the WS-Security node, now find the
|
||||
// Signature and Timestamp nodes.
|
||||
Node signatureNode = findChildNodeNS(wsSecurityNode,
|
||||
"http://www.w3.org/2000/09/xmldsig#",
|
||||
"Signature");
|
||||
Node timeStampNode = findChildNodeNS(wsSecurityNode,
|
||||
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
|
||||
"Timestamp");
|
||||
if (signatureNode != null && timeStampNode != null)
|
||||
{
|
||||
// Validate the timestamp before doing any other processing
|
||||
validateTimeStamp(timeStampNode);
|
||||
|
||||
Node signedInfoNode = findChildNodeNS(signatureNode,
|
||||
"http://www.w3.org/2000/09/xmldsig#",
|
||||
"SignedInfo");
|
||||
Node keyInfoNode = findChildNodeNS(signatureNode,
|
||||
"http://www.w3.org/2000/09/xmldsig#",
|
||||
"KeyInfo");
|
||||
if (signedInfoNode != null && keyInfoNode != null)
|
||||
{
|
||||
// Make sure that we are referencing the Timestamp and Soap Body nodes in the signature
|
||||
boolean timeStampReferenced = false;
|
||||
boolean soapBodyReferenced = false;
|
||||
NamedNodeMap attributes = timeStampNode.getAttributes();
|
||||
Node timeStampIdNode = attributes.getNamedItemNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
|
||||
"Id");
|
||||
attributes = soapBodyNode.getAttributes();
|
||||
Node soapBodyIdNode = attributes.getNamedItemNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
|
||||
"Id");
|
||||
if (timeStampIdNode != null && soapBodyIdNode != null)
|
||||
{
|
||||
Node child;
|
||||
Node next = signedInfoNode.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
// Set next
|
||||
next = child.getNextSibling();
|
||||
|
||||
// Check if we are dealinf with a reference node
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE
|
||||
&& child.getLocalName().equalsIgnoreCase("Reference")
|
||||
&& child.getNamespaceURI().equals("http://www.w3.org/2000/09/xmldsig#"))
|
||||
{
|
||||
// Found a reference node, get its attributes.
|
||||
attributes = child.getAttributes();
|
||||
Node refUriNode = attributes.getNamedItem("URI");
|
||||
if (refUriNode != null)
|
||||
{
|
||||
if (refUriNode.getTextContent().equals("#" + timeStampIdNode.getTextContent()))
|
||||
{
|
||||
timeStampReferenced = true;
|
||||
}
|
||||
else if (refUriNode.getTextContent().equals("#" + soapBodyIdNode.getTextContent()))
|
||||
{
|
||||
soapBodyReferenced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed if both the Timestamp and the Soap Body are referenced in the signature
|
||||
if (timeStampReferenced && soapBodyReferenced)
|
||||
{
|
||||
Node secTokenRefNode = findChildNodeNS(keyInfoNode,
|
||||
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
|
||||
"SecurityTokenReference");
|
||||
if (secTokenRefNode != null)
|
||||
{
|
||||
Node x509DataNode = findChildNodeNS(secTokenRefNode,
|
||||
"http://www.w3.org/2000/09/xmldsig#",
|
||||
"X509Data");
|
||||
if (x509DataNode != null)
|
||||
{
|
||||
Node x509IssuerSerialNode = findChildNodeNS(x509DataNode,
|
||||
"http://www.w3.org/2000/09/xmldsig#",
|
||||
"X509IssuerSerial");
|
||||
if (x509IssuerSerialNode != null)
|
||||
{
|
||||
Element x509IssuerNameNode = (Element) findChildNodeNS(x509IssuerSerialNode,
|
||||
"http://www.w3.org/2000/09/xmldsig#",
|
||||
"X509IssuerName");
|
||||
Element x509SerialNumberNode = (Element) findChildNodeNS(x509IssuerSerialNode,
|
||||
"http://www.w3.org/2000/09/xmldsig#",
|
||||
"X509SerialNumber");
|
||||
if (x509IssuerNameNode != null && x509SerialNumberNode != null)
|
||||
{
|
||||
// Find the certificate in our KeyStore
|
||||
X509Certificate cert = getCertWithX509IssuerSerialData(x509IssuerNameNode.getTextContent(),
|
||||
x509SerialNumberNode.getTextContent());
|
||||
|
||||
// Verify signature that we found the referenced certificate
|
||||
if (cert != null)
|
||||
{
|
||||
// Verify the signature
|
||||
XMLSignature sig = new XMLSignature((Element) signatureNode, "");
|
||||
boolean signatureOk = sig.checkSignatureValue(cert);
|
||||
if (signatureOk)
|
||||
{
|
||||
// Success
|
||||
msgVerificationStatus = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Signature verification failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Referenced certificate not found");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find X509IssuerSerial node child");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find X509IssuerSerial node");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find X509Data node");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find SecurityTokenReference node");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Signature does not cover necessary elements");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find Signature node child");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find Security node child");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find Security node");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("valid()- Not able to find SOAP Header node");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.warn("valid()- Exception caught, msg = " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return msgVerificationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a secure token template document.
|
||||
*
|
||||
* @return Secure token template document.
|
||||
*/
|
||||
public static Document getSecureTokenTemplate()
|
||||
{
|
||||
Document tokenDoc = null;
|
||||
|
||||
try
|
||||
{
|
||||
InputStream inStream = null;
|
||||
try
|
||||
{
|
||||
Constants.setSignatureSpecNSprefix("");
|
||||
|
||||
// Get document from our template
|
||||
inStream = new ByteArrayInputStream(m_secureTokenTemplate.getBytes());
|
||||
|
||||
DOMParser parser = new DOMParser();
|
||||
parser.setFeature("http://xml.org/sax/features/namespaces", true);
|
||||
parser.parse(new InputSource(inStream));
|
||||
tokenDoc = parser.getDocument();
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Close input stream if necessary
|
||||
if (inStream != null)
|
||||
inStream.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.error("getSecureTokenTemplate()- Exception caught, msg = " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Return token if successful
|
||||
return tokenDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure token.
|
||||
*
|
||||
* @param tokenDoc Token document.
|
||||
* @param timeToLive Token time to live in seconds.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void secure(Document tokenDoc,
|
||||
int timeToLive) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Find all of the relevant nodes in the document
|
||||
Element tokenElement = tokenDoc.getDocumentElement();
|
||||
Node soapHeaderNode = findChildNode(tokenElement, "SOAP-ENV:Header");
|
||||
Node soapBodyNode = findChildNode(tokenElement, "SOAP-ENV:Body");
|
||||
if (soapHeaderNode != null && soapBodyNode != null)
|
||||
{
|
||||
// We found the header of the message, now find the WS-Security node.
|
||||
Node wsSecurityNode = findChildNode(soapHeaderNode, "wsse:Security");
|
||||
if (wsSecurityNode != null)
|
||||
{
|
||||
// We found the WS-Security node, now find the Timestamp node.
|
||||
Node timeStampNode = findChildNode(wsSecurityNode, "wsu:Timestamp");
|
||||
if (timeStampNode != null)
|
||||
{
|
||||
// Set the timestamp
|
||||
setTimeStamp(timeStampNode, timeToLive);
|
||||
|
||||
// Get ready to sign the body and the timestamp elements.
|
||||
XMLSignature sig;
|
||||
if (m_signingKey.getAlgorithm().equalsIgnoreCase("DSA"))
|
||||
{
|
||||
sig = new XMLSignature(tokenDoc, "", XMLSignature.ALGO_ID_SIGNATURE_DSA, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
|
||||
}
|
||||
else if (m_signingKey.getAlgorithm().equalsIgnoreCase("RSA"))
|
||||
{
|
||||
sig = new XMLSignature(tokenDoc, "", XMLSignature.ALGO_ID_SIGNATURE_RSA, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.error("secure()- Unsupported signature algorithm - " + m_signingKey.getAlgorithm());
|
||||
throw new Exception("SecureTokenUtil.secure()- Unsupported signature algorithm - " + m_signingKey.getAlgorithm());
|
||||
}
|
||||
|
||||
wsSecurityNode.insertBefore(sig.getElement(), timeStampNode);
|
||||
|
||||
// Specify the transforms and the elements to be signed
|
||||
Transforms transforms = new Transforms(tokenDoc);
|
||||
transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
|
||||
Transforms transforms2 = new Transforms(tokenDoc);
|
||||
transforms2.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
|
||||
sig.addDocument("#CASA-SOAPBODY", transforms, org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
|
||||
sig.addDocument("#CASA-TIMESTAMP", transforms2, org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
|
||||
|
||||
Node sigNode = sig.getElement();
|
||||
|
||||
// Add X509 stuff
|
||||
XMLX509IssuerSerial x509IssuerSerial = new XMLX509IssuerSerial(tokenDoc, m_signingCert);
|
||||
|
||||
X509Data x509Data = new X509Data(tokenDoc);
|
||||
x509Data.add(x509IssuerSerial);
|
||||
Node x509Element = x509Data.getElement();
|
||||
|
||||
Node keyInfoNode = tokenDoc.createElementNS("http://www.w3.org/2000/09/xmldsig#", "ds:KeyInfo");
|
||||
|
||||
Node secTokenRefNode = tokenDoc.createElementNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse:SecurityTokenReference");
|
||||
|
||||
keyInfoNode.appendChild(secTokenRefNode);
|
||||
secTokenRefNode.appendChild(x509Element);
|
||||
sigNode.appendChild(keyInfoNode);
|
||||
|
||||
// Perform some cleanup
|
||||
setPrefixSubtree(sigNode, "ds", "http://www.w3.org/2000/09/xmldsig#");
|
||||
removeWhiteSpace(tokenElement);
|
||||
|
||||
// Sign the appropriate elements
|
||||
sig.sign(m_signingKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.error("secure()- Missing template element");
|
||||
throw new Exception("SecureTokenUtil.secure()- Missing template element.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.error("secure()- Missing template element");
|
||||
throw new Exception("SecureTokenUtil.secure()- Missing template element.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.error("secure()- Missing template element");
|
||||
throw new Exception("SecureTokenUtil.secure()- Missing template element.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.error("secure()- Exception caught, msg = " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
@ -26,18 +26,18 @@ package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.apache.axis.Message;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.client.AxisClient;
|
||||
import org.apache.axis.configuration.NullProvider;
|
||||
import org.apache.axis.message.SOAPEnvelope;
|
||||
import org.apache.axis.message.SOAPBody;
|
||||
import org.apache.axis.message.MessageElement;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.xml.serialize.XMLSerializer;
|
||||
import org.apache.xml.serialize.OutputFormat;
|
||||
import org.apache.xml.security.utils.Constants;
|
||||
import org.apache.xerces.parsers.DOMParser;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* SessionToken class.
|
||||
* <p>
|
||||
@ -61,18 +61,7 @@ public final class SessionToken
|
||||
private String m_realm = null;
|
||||
private final String m_token;
|
||||
|
||||
static final String sessionTokenSoapMsg =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<SOAP-ENV:Envelope" +
|
||||
" xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"\n" +
|
||||
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" +
|
||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
" <SOAP-ENV:Body>" +
|
||||
" <session_token><realm></realm><ident_id></ident_id></session_token>" +
|
||||
" </SOAP-ENV:Body>" +
|
||||
"</SOAP-ENV:Envelope>";
|
||||
|
||||
static final private MessageContext axisMsgContext = new MessageContext(new AxisClient(new NullProvider()));
|
||||
static private SecureTokenUtil m_secTokenUtil = null;
|
||||
|
||||
|
||||
/**
|
||||
@ -81,46 +70,79 @@ public final class SessionToken
|
||||
* @param id Id of the authenticated identity.
|
||||
* @param realm Realm where the identity id is valid.
|
||||
* @param lifetime Token lifetime.
|
||||
* @param svcConfig Service configuration object.
|
||||
* @throws Exception
|
||||
*/
|
||||
public SessionToken(String id,
|
||||
String realm,
|
||||
String lifetime,
|
||||
SvcConfig svcConfig) throws Exception
|
||||
String lifetime) throws Exception
|
||||
{
|
||||
// Save copies of the input parameters
|
||||
// Save some of the input parameters
|
||||
m_id = id;
|
||||
m_realm = realm;
|
||||
|
||||
// Create SessionTokenMessage
|
||||
Message sessionTokenMessage = getMessage(realm,
|
||||
id,
|
||||
Integer.valueOf(lifetime).intValue(),
|
||||
svcConfig);
|
||||
|
||||
// Now save the message as a string
|
||||
OutputStream outStream = null;
|
||||
try
|
||||
// Get secure token util object
|
||||
SecureTokenUtil secTokenUtil = getSecureTokenUtilObj();
|
||||
if (secTokenUtil != null)
|
||||
{
|
||||
outStream = new ByteArrayOutputStream();
|
||||
sessionTokenMessage.writeTo(outStream);
|
||||
m_token = outStream.toString();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (outStream != null)
|
||||
// Obtain secure token template document
|
||||
Document tokenDoc = SecureTokenUtil.getSecureTokenTemplate();
|
||||
if (tokenDoc != null)
|
||||
{
|
||||
// Secure token template obtained, now get its top most element.
|
||||
Node tokenElement = tokenDoc.getDocumentElement();
|
||||
|
||||
// Add session token payload to the token
|
||||
Node soapBodyElement = SecureTokenUtil.findChildNodeNS(tokenElement, "http://www.w3.org/2003/05/soap-envelope", "Body");
|
||||
Node sessionTokenElement = tokenDoc.createElement("session_token");
|
||||
soapBodyElement.appendChild(sessionTokenElement);
|
||||
Node realmElement = tokenDoc.createElement("realm");
|
||||
realmElement.setTextContent(m_realm);
|
||||
sessionTokenElement.appendChild(realmElement);
|
||||
Node idenIdElement = tokenDoc.createElement("ident_id");
|
||||
idenIdElement.setTextContent(m_id);
|
||||
realmElement.appendChild(idenIdElement);
|
||||
|
||||
// Secure the token
|
||||
secTokenUtil.secure(tokenDoc, Integer.valueOf(lifetime).intValue());
|
||||
|
||||
// Now save the token as a string
|
||||
OutputStream outStream = null;
|
||||
try
|
||||
{
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
outStream = new ByteArrayOutputStream();
|
||||
OutputFormat format = new OutputFormat(tokenDoc);
|
||||
XMLSerializer serializer = new XMLSerializer(outStream, format);
|
||||
serializer.serialize(tokenDoc.getDocumentElement());
|
||||
m_token = outStream.toString();
|
||||
}
|
||||
catch (Exception e)
|
||||
finally
|
||||
{
|
||||
// Do nothing
|
||||
if (outStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to obtain secure token template
|
||||
m_log.warn("Constructor()- Failed to obtain secure token template");
|
||||
throw new Exception("SessionToken.Constructor()- Failed to obtain secure token template");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to obtain secure token util object
|
||||
m_log.warn("Constructor()- Failed to obtain secure token util object");
|
||||
throw new Exception("SessionToken.Constructor()- Failed to obtain secure token util object");
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,45 +162,83 @@ public final class SessionToken
|
||||
// Decode the token string
|
||||
m_token = Base64Coder.decode(token);
|
||||
|
||||
// Now instantiate a SOAP message with the string
|
||||
// Now instantiate token document with the token string
|
||||
inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||
Message message = new Message(inStream);
|
||||
Constants.setSignatureSpecNSprefix("");
|
||||
|
||||
// Get access to the SOAP Envelope
|
||||
SOAPEnvelope envelope = message.getSOAPEnvelope();
|
||||
DOMParser parser = new DOMParser();
|
||||
parser.setFeature("http://xml.org/sax/features/namespaces", true);
|
||||
parser.parse(new InputSource(inStream));
|
||||
Document tokenDoc = parser.getDocument();
|
||||
|
||||
// Verify the message
|
||||
if (WSSecurity.verifyMessage(envelope))
|
||||
// Obtain secure token util object
|
||||
SecureTokenUtil secTokenUtil = getSecureTokenUtilObj();
|
||||
if (secTokenUtil != null)
|
||||
{
|
||||
// Message verification succeded, now obtain the realm and identity id
|
||||
// from the message body.
|
||||
SOAPBody body = (SOAPBody) envelope.getBody();
|
||||
QName sessionTokenElementName = new QName("session_token");
|
||||
MessageElement sessionTokenElement = body.getChildElement(sessionTokenElementName);
|
||||
QName realmElementName = new QName("realm");
|
||||
MessageElement realmElement = sessionTokenElement.getChildElement(realmElementName);
|
||||
if (realmElement != null)
|
||||
// Use the secure token util to validate the token
|
||||
if (secTokenUtil.valid(tokenDoc))
|
||||
{
|
||||
m_realm = realmElement.getChildNodes().item(0).getNodeValue();
|
||||
// The session token is valid, now obtain the realm and identity id
|
||||
// information from it.
|
||||
Node tokenElement = tokenDoc.getDocumentElement();
|
||||
if (tokenElement != null)
|
||||
{
|
||||
Node soapBodyElement = SecureTokenUtil.findChildNodeNS(tokenElement,
|
||||
"http://www.w3.org/2003/05/soap-envelope",
|
||||
"Body");
|
||||
if (soapBodyElement != null)
|
||||
{
|
||||
Node sessionTokenElement = SecureTokenUtil.findChildNode(soapBodyElement, "session_token");
|
||||
if (sessionTokenElement != null)
|
||||
{
|
||||
Node realmElement = SecureTokenUtil.findChildNode(sessionTokenElement, "realm");
|
||||
Node identIdElement = SecureTokenUtil.findChildNode(sessionTokenElement, "ident_id");
|
||||
if (realmElement != null
|
||||
&& identIdElement != null)
|
||||
{
|
||||
m_realm = realmElement.getTextContent();
|
||||
m_id = identIdElement.getTextContent();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing session token element child
|
||||
m_log.warn("Constructor(String)- Unable to obtain session token element child");
|
||||
throw new Exception("SessionToken.Constructor(String)- Unable to obtain session token element child");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing session token element
|
||||
m_log.warn("Constructor(String)- Unable to obtain session token element");
|
||||
throw new Exception("SessionToken.Constructor(String)- Unable to obtain session token element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid SOAP message
|
||||
m_log.warn("Constructor(String)- Unable to obtain soap body element");
|
||||
throw new Exception("SessionToken.Constructor(String)- Unable to obtain soap body element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid XML document
|
||||
m_log.warn("Constructor(String)- Unable to obtain document element");
|
||||
throw new Exception("SessionToken.Constructor(String)- Unable to obtain document element");
|
||||
}
|
||||
}
|
||||
QName identIdElementName = new QName("ident_id");
|
||||
MessageElement identIdElement = sessionTokenElement.getChildElement(identIdElementName);
|
||||
if (identIdElement != null)
|
||||
else
|
||||
{
|
||||
m_id = identIdElement.getChildNodes().item(0).getNodeValue();
|
||||
}
|
||||
|
||||
if (m_realm == null || m_id == null)
|
||||
{
|
||||
m_log.warn("Constructor()- Required data missing from session token");
|
||||
throw new Exception("Error: Required data missing from session Token");
|
||||
// Message verification failed
|
||||
m_log.warn("Constructor(String)- Invalid Session Token");
|
||||
throw new Exception("SessionToken.Constructor(String)- Invalid Session Token");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message verification failed
|
||||
m_log.warn("Constructor()- Invalid Session Token");
|
||||
throw new Exception("Invalid Session Token");
|
||||
// Failed to obtain secure token util object
|
||||
m_log.warn("Constructor(String)- Failed to obtain secure token util object");
|
||||
throw new Exception("SessionToken.Constructor(String)- Failed to obtain secure token util object");
|
||||
}
|
||||
}
|
||||
finally
|
||||
@ -198,75 +258,29 @@ public final class SessionToken
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SessionToken SOAP Message.
|
||||
* Gets object to be utilized for creating and verifying secure tokens.
|
||||
*
|
||||
* @param realm String containing the identity token that should be part of the message.
|
||||
* @param identityId String containing the identity token type.
|
||||
* @param lifetime Lifetime that should be specified in the message timestamp (seconds).
|
||||
* @param svcConfig Service Config object.
|
||||
* @return SessionToken message, null if the method fails.
|
||||
* @return SecuteTokenUtil object or null if the method fails.
|
||||
*/
|
||||
private static Message getMessage(String realm,
|
||||
String identityId,
|
||||
int lifetime,
|
||||
SvcConfig svcConfig)
|
||||
private static synchronized SecureTokenUtil getSecureTokenUtilObj()
|
||||
{
|
||||
Message secureMessage;
|
||||
InputStream inStream = null;
|
||||
|
||||
try
|
||||
// Instantiate the object if it has not been instantiated already
|
||||
if (m_secTokenUtil == null)
|
||||
{
|
||||
// Build SOAP Message with an identity token in the body
|
||||
//
|
||||
// First create a message and obtain its body
|
||||
inStream = new ByteArrayInputStream(sessionTokenSoapMsg.getBytes());
|
||||
Message message = new Message(inStream);
|
||||
message.setMessageContext(axisMsgContext);
|
||||
SOAPBody body = (SOAPBody) message.getSOAPBody();
|
||||
|
||||
// Get access to the session_token element
|
||||
QName sessionTokenElementName = new QName("session_token");
|
||||
MessageElement sessionTokenElement = body.getChildElement(sessionTokenElementName);
|
||||
|
||||
// Get access to the realm element and set its value
|
||||
QName realmElementName = new QName("realm");
|
||||
MessageElement realmElement = sessionTokenElement.getChildElement(realmElementName);
|
||||
realmElement.addTextNode(realm);
|
||||
|
||||
// Get access to the ident_id element and set its value
|
||||
QName identIdElementName = new QName("ident_id");
|
||||
MessageElement identIdElement = sessionTokenElement.getChildElement(identIdElementName);
|
||||
identIdElement.addTextNode(identityId);
|
||||
|
||||
// Now we need to secure the SOAP message that we created, we are doing to
|
||||
// do so by adding a timestamp and signing the timestamp as well as the body.
|
||||
// To do this we are going to leverage WS-Security.
|
||||
secureMessage = WSSecurity.secureSOAPEnvelope(message.getSOAPEnvelope(),
|
||||
lifetime,
|
||||
svcConfig,
|
||||
false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.error("getMessage() - Exception caught building message, error: " + e.getMessage());
|
||||
secureMessage = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (inStream != null)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
inStream.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
// Instantiate secure token object to be utilized in server type operations
|
||||
m_secTokenUtil = new SecureTokenUtil(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Exception caught
|
||||
m_log.warn("getSecureTokenUtilObj()- Exception caught, message = " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return secureMessage;
|
||||
// Return the object
|
||||
return m_secTokenUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,311 +0,0 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.axis.Message;
|
||||
import org.apache.axis.message.SOAPEnvelope;
|
||||
import org.apache.ws.security.*;
|
||||
import org.apache.ws.security.components.crypto.Crypto;
|
||||
import org.apache.ws.security.components.crypto.CryptoFactory;
|
||||
import org.apache.ws.security.message.WSSecHeader;
|
||||
import org.apache.ws.security.message.WSSecSignature;
|
||||
import org.apache.ws.security.message.WSSecTimestamp;
|
||||
import org.apache.xml.security.c14n.Canonicalizer;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* WSSecurity Class.
|
||||
* <p>
|
||||
* This class provides static methods for securing and verifying SOAP messages. SOAP messages
|
||||
* are secured by adding a timestamp and signing the appropriate elements using methods and
|
||||
* headers defined by WS* specifications.
|
||||
*
|
||||
*/
|
||||
public final class WSSecurity
|
||||
{
|
||||
private static final Logger m_log = Logger.getLogger(WSSecurity.class);
|
||||
|
||||
static final private WSSecurityEngine secEngine = new WSSecurityEngine();
|
||||
static final private Crypto crypto = CryptoFactory.getInstance();
|
||||
|
||||
/**
|
||||
* Creates a SOAP message from a document.
|
||||
*
|
||||
* @param doc Message document.
|
||||
* @return SOAP message.
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Message toSOAPMessage(Document doc) throws Exception
|
||||
{
|
||||
ByteArrayInputStream inStream = null;
|
||||
Message msg = null;
|
||||
|
||||
try
|
||||
{
|
||||
Canonicalizer c14n = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
|
||||
byte[] canonicalMessage = c14n.canonicalizeSubtree(doc);
|
||||
inStream = new ByteArrayInputStream(canonicalMessage);
|
||||
MessageFactory factory = MessageFactory.newInstance();
|
||||
msg = (org.apache.axis.Message) factory.createMessage(null, inStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (inStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
inStream.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element that containes an Id with value
|
||||
* uri and namespace.
|
||||
* <p>
|
||||
* Copyright Note: The code for this function was copied from file
|
||||
* WSSecurityUtil.java from package org.apache.ws.security.util.
|
||||
* The Copyright notice on this file is as follows:
|
||||
* <p>
|
||||
* Copyright 2003-2006 The Apache Software Foundation, or their licensors, as
|
||||
* appropriate.
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* @param startNode Where to start the search.
|
||||
* @param value Value of the Id attribute.
|
||||
* @param namespace Namespace URI of the Id.
|
||||
* @return The found element or null.
|
||||
*/
|
||||
private static Element findElementById(Node startNode,
|
||||
String value,
|
||||
String namespace)
|
||||
{
|
||||
// Just return null if startNode is set to null
|
||||
if (startNode == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Node startParent = startNode.getParentNode();
|
||||
Node processedNode;
|
||||
while (startNode != null)
|
||||
{
|
||||
// start node processing at this point
|
||||
if (startNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
Element se = (Element) startNode;
|
||||
if (se.hasAttributeNS(namespace, "Id")
|
||||
&& value.equals(se.getAttributeNS(namespace, "Id")))
|
||||
{
|
||||
return se;
|
||||
}
|
||||
}
|
||||
|
||||
processedNode = startNode;
|
||||
startNode = startNode.getFirstChild();
|
||||
|
||||
// no child, this node is done.
|
||||
if (startNode == null)
|
||||
{
|
||||
// close node processing, get sibling
|
||||
startNode = processedNode.getNextSibling();
|
||||
}
|
||||
|
||||
// no more siblings, get parent, all children
|
||||
// of parent are processed.
|
||||
while (startNode == null)
|
||||
{
|
||||
processedNode = processedNode.getParentNode();
|
||||
if (processedNode == startParent)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// close parent node processing (processed node now)
|
||||
startNode = processedNode.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies SOAP envelope timestamp and signatures.
|
||||
*
|
||||
* @param envelope SOAP envelope with timestamp
|
||||
* @return True if verification succeeds.
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean verifyMessage(SOAPEnvelope envelope) throws Exception
|
||||
{
|
||||
boolean msgVerificationStatus = false;
|
||||
|
||||
try
|
||||
{
|
||||
boolean timeStampProcessed = false;
|
||||
boolean signatureProcessed = false;
|
||||
Vector<WSSecurityEngineResult> results;
|
||||
Document signedDoc = envelope.getAsDocument();
|
||||
results = secEngine.processSecurityHeader(signedDoc, null, null, crypto);
|
||||
if (results != null)
|
||||
{
|
||||
for (WSSecurityEngineResult result : results)
|
||||
{
|
||||
if (result.getAction() == WSConstants.TS)
|
||||
{
|
||||
timeStampProcessed = true;
|
||||
}
|
||||
else if (result.getAction() == WSConstants.SIGN)
|
||||
{
|
||||
// A signature was processed, verify that the signature was over the timestamp
|
||||
// and the body.
|
||||
boolean timeStampSigned = false;
|
||||
boolean bodySigned = false;
|
||||
Set signedElements = result.getSignedElements();
|
||||
for (Object signedElement : signedElements)
|
||||
{
|
||||
String elementId = (String) signedElement;
|
||||
Element element = findElementById(signedDoc.getDocumentElement(), elementId, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
|
||||
if (element != null)
|
||||
{
|
||||
if ("wsu:Timestamp".equalsIgnoreCase(element.getNodeName()))
|
||||
{
|
||||
timeStampSigned = true;
|
||||
}
|
||||
else if ("SOAP-ENV:Body".equalsIgnoreCase(element.getNodeName()))
|
||||
{
|
||||
bodySigned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timeStampSigned && bodySigned)
|
||||
{
|
||||
signatureProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timeStampProcessed && signatureProcessed)
|
||||
{
|
||||
m_log.debug("verifyMessage() - Validation succeded");
|
||||
msgVerificationStatus = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.warn("verifyMessage() - validation failed");
|
||||
}
|
||||
}
|
||||
catch (WSSecurityException e)
|
||||
{
|
||||
m_log.warn("verifyMessage() - Verification failed with error:" + e.getMessage() + " code = " + e.getErrorCode());
|
||||
}
|
||||
|
||||
return msgVerificationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add timestamp and sign SOAP message in compliance with WS-Security.
|
||||
*
|
||||
* @param envelope String containing a SOAP envelope
|
||||
* @param timeToLive Value to set the timestamp timeToLive parameter in seconds
|
||||
* @param svcConfig Service Config object
|
||||
* @param includeCert True if the message should include the Public Certificate
|
||||
* @return Signed and timestamped SOAP message
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Message secureSOAPEnvelope(SOAPEnvelope envelope,
|
||||
int timeToLive,
|
||||
SvcConfig svcConfig,
|
||||
boolean includeCert) throws Exception
|
||||
{
|
||||
WSSecSignature signer = new WSSecSignature();
|
||||
signer.setUserInfo(svcConfig.getSetting(SvcConfig.SigningKeyAliasName),
|
||||
svcConfig.getSetting(SvcConfig.SigningKeyPassword));
|
||||
if (includeCert)
|
||||
{
|
||||
signer.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER); // Include X509 Cert in message
|
||||
}
|
||||
else
|
||||
{
|
||||
signer.setKeyIdentifierType(WSConstants.ISSUER_SERIAL); // Use X509 Cert Serial Number and issuer info
|
||||
}
|
||||
|
||||
Document doc = envelope.getAsDocument();
|
||||
|
||||
WSSecHeader secHeader = new WSSecHeader();
|
||||
secHeader.insertSecurityHeader(doc);
|
||||
|
||||
WSSecTimestamp timeStamper = new WSSecTimestamp();
|
||||
timeStamper.setTimeToLive(timeToLive);
|
||||
timeStamper.build(doc, secHeader);
|
||||
|
||||
Vector<WSEncryptionPart> parts = new Vector<WSEncryptionPart>();
|
||||
|
||||
String soapNamespace = doc.getDocumentElement().getNamespaceURI();
|
||||
WSEncryptionPart bodyPart = new WSEncryptionPart("Body", soapNamespace, "");
|
||||
parts.add(bodyPart);
|
||||
|
||||
WSEncryptionPart timeStampPart = new WSEncryptionPart(timeStamper.getId());
|
||||
parts.add(timeStampPart);
|
||||
|
||||
signer.setParts(parts);
|
||||
|
||||
Document signedDoc = signer.build(doc, crypto, secHeader);
|
||||
|
||||
// Convert the signed document into a SOAP message and return it.
|
||||
return toSOAPMessage(signedDoc);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user