1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.security.wss4j.callback;
18
19 import java.io.IOException;
20 import javax.security.auth.callback.UnsupportedCallbackException;
21
22 import org.apache.ws.security.WSPasswordCallback;
23 import org.apache.ws.security.WSUsernameTokenPrincipal;
24
25 import org.springframework.beans.factory.InitializingBean;
26 import org.springframework.dao.DataAccessException;
27 import org.springframework.security.context.SecurityContextHolder;
28 import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
29 import org.springframework.security.providers.dao.UserCache;
30 import org.springframework.security.providers.dao.cache.NullUserCache;
31 import org.springframework.security.userdetails.UserDetails;
32 import org.springframework.security.userdetails.UserDetailsService;
33 import org.springframework.security.userdetails.UsernameNotFoundException;
34 import org.springframework.util.Assert;
35 import org.springframework.ws.soap.security.callback.CleanupCallback;
36 import org.springframework.ws.soap.security.support.SpringSecurityUtils;
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class SpringDigestPasswordValidationCallbackHandler extends AbstractWsPasswordCallbackHandler
51 implements InitializingBean {
52
53 private UserCache userCache = new NullUserCache();
54
55 private UserDetailsService userDetailsService;
56
57
58 public void setUserCache(UserCache userCache) {
59 this.userCache = userCache;
60 }
61
62
63 public void setUserDetailsService(UserDetailsService userDetailsService) {
64 this.userDetailsService = userDetailsService;
65 }
66
67 public void afterPropertiesSet() throws Exception {
68 Assert.notNull(userDetailsService, "userDetailsService is required");
69 }
70
71 protected void handleUsernameToken(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
72 String identifier = callback.getIdentifier();
73 UserDetails user = loadUserDetails(identifier);
74 if (user != null) {
75 SpringSecurityUtils.checkUserValidity(user);
76 callback.setPassword(user.getPassword());
77 }
78 }
79
80 protected void handleUsernameTokenPrincipal(UsernameTokenPrincipalCallback callback)
81 throws IOException, UnsupportedCallbackException {
82 UserDetails user = loadUserDetails(callback.getPrincipal().getName());
83 WSUsernameTokenPrincipal principal = callback.getPrincipal();
84 UsernamePasswordAuthenticationToken authRequest =
85 new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), user.getAuthorities());
86 if (logger.isDebugEnabled()) {
87 logger.debug("Authentication success: " + authRequest.toString());
88 }
89 SecurityContextHolder.getContext().setAuthentication(authRequest);
90 }
91
92 protected void handleCleanup(CleanupCallback callback) throws IOException, UnsupportedCallbackException {
93 SecurityContextHolder.clearContext();
94 }
95
96 private UserDetails loadUserDetails(String username) throws DataAccessException {
97 UserDetails user = userCache.getUserFromCache(username);
98
99 if (user == null) {
100 try {
101 user = userDetailsService.loadUserByUsername(username);
102 }
103 catch (UsernameNotFoundException notFound) {
104 if (logger.isDebugEnabled()) {
105 logger.debug("Username '" + username + "' not found");
106 }
107 return null;
108 }
109 userCache.putUserInCache(user);
110 }
111 return user;
112 }
113 }