1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.ws.soap.security.x509.populator;
17
18 import org.springframework.security.core.SpringSecurityMessageSource;
19 import org.springframework.security.core.AuthenticationException;
20 import org.springframework.security.authentication.BadCredentialsException;
21 import org.springframework.security.authentication.AuthenticationServiceException;
22
23 import org.springframework.ws.soap.security.x509.X509AuthoritiesPopulator;
24
25 import org.springframework.security.core.userdetails.UserDetails;
26 import org.springframework.security.core.userdetails.UserDetailsService;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import org.springframework.beans.factory.InitializingBean;
32
33 import org.springframework.context.MessageSource;
34 import org.springframework.context.MessageSourceAware;
35 import org.springframework.context.support.MessageSourceAccessor;
36
37 import org.springframework.util.Assert;
38
39 import java.security.cert.X509Certificate;
40 import java.util.regex.Pattern;
41 import java.util.regex.Matcher;
42
43
44
45
46
47
48
49
50 public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, InitializingBean, MessageSourceAware {
51
52
53 private static final Log logger = LogFactory.getLog(DaoX509AuthoritiesPopulator.class);
54
55
56
57 protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
58 private Pattern subjectDNPattern;
59 private String subjectDNRegex = "CN=(.*?),";
60 private UserDetailsService userDetailsService;
61
62
63
64 public void afterPropertiesSet() throws Exception {
65 Assert.notNull(userDetailsService, "An authenticationDao must be set");
66 Assert.notNull(this.messages, "A message source must be set");
67
68 subjectDNPattern = Pattern.compile(subjectDNRegex, Pattern.CASE_INSENSITIVE);
69 }
70
71 public UserDetails getUserDetails(X509Certificate clientCert) throws AuthenticationException {
72 String subjectDN = clientCert.getSubjectDN().getName();
73
74 Matcher matcher = subjectDNPattern.matcher(subjectDN);
75
76 if (!matcher.find()) {
77 throw new BadCredentialsException(messages.getMessage("DaoX509AuthoritiesPopulator.noMatching",
78 new Object[] {subjectDN}, "No matching pattern was found in subjectDN: {0}"));
79 }
80
81 if (matcher.groupCount() != 1) {
82 throw new IllegalArgumentException("Regular expression must contain a single group ");
83 }
84
85 String userName = matcher.group(1);
86
87 UserDetails user = this.userDetailsService.loadUserByUsername(userName);
88
89 if (user == null) {
90 throw new AuthenticationServiceException(
91 "UserDetailsService returned null, which is an interface contract violation");
92 }
93
94 return user;
95 }
96
97 public void setMessageSource(MessageSource messageSource) {
98 this.messages = new MessageSourceAccessor(messageSource);
99 }
100
101
102
103
104
105
106
107
108
109
110
111 public void setSubjectDNRegex(String subjectDNRegex) {
112 this.subjectDNRegex = subjectDNRegex;
113 }
114
115 public void setUserDetailsService(UserDetailsService userDetailsService) {
116 this.userDetailsService = userDetailsService;
117 }
118 }