1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.security.x509;
18
19 import java.security.cert.X509Certificate;
20
21 import org.springframework.beans.factory.InitializingBean;
22 import org.springframework.context.MessageSource;
23 import org.springframework.context.MessageSourceAware;
24 import org.springframework.context.support.MessageSourceAccessor;
25 import org.springframework.security.authentication.AuthenticationProvider;
26 import org.springframework.security.authentication.BadCredentialsException;
27 import org.springframework.security.core.Authentication;
28 import org.springframework.security.core.AuthenticationException;
29 import org.springframework.security.core.SpringSecurityMessageSource;
30 import org.springframework.security.core.userdetails.UserDetails;
31 import org.springframework.util.Assert;
32 import org.springframework.ws.soap.security.x509.cache.NullX509UserCache;
33 import org.springframework.ws.soap.security.x509.cache.X509UserCache;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38
39
40
41
42
43
44
45
46 public class X509AuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware {
47
48
49 private static final Log logger = LogFactory.getLog(X509AuthenticationProvider.class);
50
51
52
53 protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
54 private X509AuthoritiesPopulator x509AuthoritiesPopulator;
55 private X509UserCache userCache = new NullX509UserCache();
56
57
58
59 public void afterPropertiesSet() throws Exception {
60 Assert.notNull(userCache, "An x509UserCache must be set");
61 Assert.notNull(x509AuthoritiesPopulator, "An X509AuthoritiesPopulator must be set");
62 Assert.notNull(this.messages, "A message source must be set");
63 }
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public Authentication authenticate(Authentication authentication)
80 throws AuthenticationException {
81 if (!supports(authentication.getClass())) {
82 return null;
83 }
84
85 if (logger.isDebugEnabled()) {
86 logger.debug("X509 authentication request: " + authentication);
87 }
88
89 X509Certificate clientCertificate = (X509Certificate) authentication.getCredentials();
90
91 if (clientCertificate == null) {
92 throw new BadCredentialsException(messages.getMessage("X509AuthenticationProvider.certificateNull",
93 "Certificate is null"));
94 }
95
96 UserDetails user = userCache.getUserFromCache(clientCertificate);
97
98 if (user == null) {
99 if (logger.isDebugEnabled()) {
100 logger.debug("Authenticating with certificate " + clientCertificate);
101 }
102 user = x509AuthoritiesPopulator.getUserDetails(clientCertificate);
103 userCache.putUserInCache(clientCertificate, user);
104 }
105
106 X509AuthenticationToken result = new X509AuthenticationToken(user, clientCertificate, user.getAuthorities());
107
108 result.setDetails(authentication.getDetails());
109
110 return result;
111 }
112
113 public void setMessageSource(MessageSource messageSource) {
114 this.messages = new MessageSourceAccessor(messageSource);
115 }
116
117 public void setX509AuthoritiesPopulator(X509AuthoritiesPopulator x509AuthoritiesPopulator) {
118 this.x509AuthoritiesPopulator = x509AuthoritiesPopulator;
119 }
120
121 public void setX509UserCache(X509UserCache cache) {
122 this.userCache = cache;
123 }
124
125 public boolean supports(Class authentication) {
126 return X509AuthenticationToken.class.isAssignableFrom(authentication);
127 }
128 }