1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.security.xwss.callback;
18
19 import java.io.IOException;
20 import java.security.cert.X509Certificate;
21 import javax.security.auth.callback.Callback;
22 import javax.security.auth.callback.UnsupportedCallbackException;
23
24 import com.sun.xml.wss.impl.callback.CertificateValidationCallback;
25
26 import org.springframework.beans.factory.InitializingBean;
27 import org.springframework.security.core.Authentication;
28 import org.springframework.security.core.AuthenticationException;
29 import org.springframework.security.authentication.AuthenticationManager;
30 import org.springframework.security.core.context.SecurityContextHolder;
31 import org.springframework.ws.soap.security.x509.X509AuthenticationToken;
32 import org.springframework.util.Assert;
33 import org.springframework.ws.soap.security.callback.AbstractCallbackHandler;
34 import org.springframework.ws.soap.security.callback.CleanupCallback;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class SpringCertificateValidationCallbackHandler extends AbstractCallbackHandler implements InitializingBean {
53
54 private AuthenticationManager authenticationManager;
55
56 private boolean ignoreFailure = false;
57
58
59 public void setAuthenticationManager(AuthenticationManager authenticationManager) {
60 this.authenticationManager = authenticationManager;
61 }
62
63 public void setIgnoreFailure(boolean ignoreFailure) {
64 this.ignoreFailure = ignoreFailure;
65 }
66
67 public void afterPropertiesSet() throws Exception {
68 Assert.notNull(authenticationManager, "authenticationManager is required");
69 }
70
71
72
73
74
75
76
77
78 @Override
79 protected void handleInternal(Callback callback) throws IOException, UnsupportedCallbackException {
80 if (callback instanceof CertificateValidationCallback) {
81 ((CertificateValidationCallback) callback).setValidator(new SpringSecurityCertificateValidator());
82 }
83 else if (callback instanceof CleanupCallback) {
84 SecurityContextHolder.clearContext();
85 }
86 else {
87 throw new UnsupportedCallbackException(callback);
88 }
89 }
90
91 private class SpringSecurityCertificateValidator implements CertificateValidationCallback.CertificateValidator {
92
93 public boolean validate(X509Certificate certificate)
94 throws CertificateValidationCallback.CertificateValidationException {
95 boolean result;
96 try {
97 Authentication authResult =
98 authenticationManager.authenticate(new X509AuthenticationToken(certificate));
99 if (logger.isDebugEnabled()) {
100 logger.debug("Authentication request for certificate with DN [" +
101 certificate.getSubjectX500Principal().getName() + "] successful");
102 }
103 SecurityContextHolder.getContext().setAuthentication(authResult);
104 return true;
105 }
106 catch (AuthenticationException failed) {
107 if (logger.isDebugEnabled()) {
108 logger.debug("Authentication request for certificate with DN [" +
109 certificate.getSubjectX500Principal().getName() + "] failed: " + failed.toString());
110 }
111 SecurityContextHolder.clearContext();
112 result = ignoreFailure;
113 }
114 return result;
115 }
116 }
117 }