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.acegi;
18
19 import java.io.IOException;
20 import javax.security.auth.callback.Callback;
21 import javax.security.auth.callback.UnsupportedCallbackException;
22
23 import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
24 import com.sun.xml.wss.impl.callback.TimestampValidationCallback;
25 import org.acegisecurity.context.SecurityContextHolder;
26 import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
27 import org.acegisecurity.providers.dao.UserCache;
28 import org.acegisecurity.providers.dao.cache.NullUserCache;
29 import org.acegisecurity.userdetails.UserDetails;
30 import org.acegisecurity.userdetails.UserDetailsService;
31 import org.acegisecurity.userdetails.UsernameNotFoundException;
32
33 import org.springframework.beans.factory.InitializingBean;
34 import org.springframework.dao.DataAccessException;
35 import org.springframework.util.Assert;
36 import org.springframework.ws.soap.security.callback.AbstractCallbackHandler;
37 import org.springframework.ws.soap.security.callback.CleanupCallback;
38 import org.springframework.ws.soap.security.xwss.callback.DefaultTimestampValidator;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class AcegiDigestPasswordValidationCallbackHandler extends AbstractCallbackHandler implements InitializingBean {
58
59 private UserCache userCache = new NullUserCache();
60
61 private UserDetailsService userDetailsService;
62
63
64 public void setUserCache(UserCache userCache) {
65 this.userCache = userCache;
66 }
67
68
69 public void setUserDetailsService(UserDetailsService userDetailsService) {
70 this.userDetailsService = userDetailsService;
71 }
72
73 public void afterPropertiesSet() throws Exception {
74 Assert.notNull(userDetailsService, "userDetailsService is required");
75 }
76
77
78
79
80
81
82
83 protected void handleInternal(Callback callback) throws IOException, UnsupportedCallbackException {
84 if (callback instanceof PasswordValidationCallback) {
85 PasswordValidationCallback passwordCallback = (PasswordValidationCallback) callback;
86 if (passwordCallback.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {
87 PasswordValidationCallback.DigestPasswordRequest request =
88 (PasswordValidationCallback.DigestPasswordRequest) passwordCallback.getRequest();
89 String username = request.getUsername();
90 UserDetails user = loadUserDetails(username);
91 if (user != null) {
92 request.setPassword(user.getPassword());
93 }
94 AcegiDigestPasswordValidator validator = new AcegiDigestPasswordValidator(user);
95 passwordCallback.setValidator(validator);
96 return;
97 }
98 }
99 else if (callback instanceof TimestampValidationCallback) {
100 TimestampValidationCallback timestampCallback = (TimestampValidationCallback) callback;
101 timestampCallback.setValidator(new DefaultTimestampValidator());
102
103 }
104 else if (callback instanceof CleanupCallback) {
105 SecurityContextHolder.clearContext();
106 return;
107 }
108 throw new UnsupportedCallbackException(callback);
109 }
110
111 private UserDetails loadUserDetails(String username) throws DataAccessException {
112 UserDetails user = userCache.getUserFromCache(username);
113
114 if (user == null) {
115 try {
116 user = userDetailsService.loadUserByUsername(username);
117 }
118 catch (UsernameNotFoundException notFound) {
119 if (logger.isDebugEnabled()) {
120 logger.debug("Username '" + username + "' not found");
121 }
122 return null;
123 }
124 userCache.putUserInCache(user);
125 }
126 return user;
127 }
128
129 private class AcegiDigestPasswordValidator extends PasswordValidationCallback.DigestPasswordValidator {
130
131 private UserDetails user;
132
133 private AcegiDigestPasswordValidator(UserDetails user) {
134 this.user = user;
135 }
136
137 public boolean validate(PasswordValidationCallback.Request request)
138 throws PasswordValidationCallback.PasswordValidationException {
139 if (super.validate(request)) {
140 UsernamePasswordAuthenticationToken authRequest =
141 new UsernamePasswordAuthenticationToken(user, user.getPassword());
142 if (logger.isDebugEnabled()) {
143 logger.debug("Authentication success: " + authRequest.toString());
144 }
145
146 SecurityContextHolder.getContext().setAuthentication(authRequest);
147 return true;
148 }
149 else {
150 return false;
151 }
152 }
153 }
154
155 }