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