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.springframework.beans.factory.InitializingBean;
23 import org.springframework.dao.DataAccessException;
24 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
25 import org.springframework.security.core.context.SecurityContextHolder;
26 import org.springframework.security.core.userdetails.UserCache;
27 import org.springframework.security.core.userdetails.UserDetails;
28 import org.springframework.security.core.userdetails.UserDetailsService;
29 import org.springframework.security.core.userdetails.UsernameNotFoundException;
30 import org.springframework.security.core.userdetails.cache.NullUserCache;
31 import org.springframework.util.Assert;
32 import org.springframework.ws.soap.security.callback.CleanupCallback;
33 import org.springframework.ws.soap.security.support.SpringSecurityUtils;
34
35 import org.apache.ws.security.WSPasswordCallback;
36 import org.apache.ws.security.WSUsernameTokenPrincipal;
37
38
39
40
41
42
43
44
45
46
47 public class SpringSecurityPasswordValidationCallbackHandler extends AbstractWsPasswordCallbackHandler
48 implements InitializingBean {
49
50 private UserCache userCache = new NullUserCache();
51
52 private UserDetailsService userDetailsService;
53
54
55 public void setUserCache(UserCache userCache) {
56 this.userCache = userCache;
57 }
58
59
60 public void setUserDetailsService(UserDetailsService userDetailsService) {
61 this.userDetailsService = userDetailsService;
62 }
63
64 public void afterPropertiesSet() throws Exception {
65 Assert.notNull(userDetailsService, "userDetailsService is required");
66 }
67
68 @Override
69 protected void handleUsernameToken(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
70 String identifier = callback.getIdentifier();
71 UserDetails user = loadUserDetails(identifier);
72 if (user != null) {
73 SpringSecurityUtils.checkUserValidity(user);
74 callback.setPassword(user.getPassword());
75 }
76 }
77
78 @Override
79 protected void handleUsernameTokenPrincipal(UsernameTokenPrincipalCallback callback)
80 throws IOException, UnsupportedCallbackException {
81 UserDetails user = loadUserDetails(callback.getPrincipal().getName());
82 WSUsernameTokenPrincipal principal = callback.getPrincipal();
83 UsernamePasswordAuthenticationToken authRequest =
84 new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), user.getAuthorities());
85 if (logger.isDebugEnabled()) {
86 logger.debug("Authentication success: " + authRequest.toString());
87 }
88 SecurityContextHolder.getContext().setAuthentication(authRequest);
89 }
90
91 @Override
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 }