Spring security 3可能会做一些技巧来验证幕后的用户密码,但现在这已成为我的问题,我试图拦截用户输入的任何密码,但是找不到线索。
@Component("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
............
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
User user = userService.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User '"+username+"' not found !");
}
return user;
}
}
我可以使用任何API拦截用户的密码吗?
答案 0 :(得分:2)
UserDetailsService
负责加载用户并提供包含存储在数据库中的密码的UserDetails
对象。不幸的是(对你而言)在大多数情况下,这个密码被哈希(SHA或MD5)。
如果要拦截用户输入的密码,则有不同的选择:
UserNamePasswordFilter
(当您使用表单身份验证时,如果您使用其他类型的身份验证,则需要其他过滤器)在一个点上截取密码。它负责获取登录http请求,创建UserNamePasswordAuthenticationToken
并将其转发给AuthenticationManager
。
另一个拦截点是AuthenticationManager
(更准确的是ProviderManager
- 然后才真正实现AuthenticationManager
)。它有一个方法Authentication authenticate(Authentication authentication)
,用于输入用户输入(Authentication
的子类,例如UsernamePasswordAuthenticationToken
)并验证它(通过将其转发到AuthenticationProvider
)
AuthenticationProvider
(例如DaoAuthenticationProvider
)将是拦截密码的另一个地方。
DaoAuthenticationProvider
使用PasswordEncoder
来哈希用户输入的密码。然后DaoAuthenticationProvider
将比较从数据库获得的哈希密码和用户输入的哈希密码。 因此PasswordEncoder
可能是截取用户输入密码的最简单方法!
当然你可以拦截HttpRequest本身:你可以注册一个额外的SecurityFilter(在UsernamePasswordFilter
之前)或一个简单的Servlet过滤器(在Spring安全过滤器之前)。 (Spring Interceptor不起作用,因为Spring Security Filter会处理请求而不会将它转发给Spring Dispatcher,因此Spring Dispatcher无法调用Spring Interceptor。)
密码编码器注册:
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider user-service-ref="jdbcUserService">
<sec:password-encoder ref="myPasswordEncoder"/>
</sec:authentication-provider>
</sec:authentication-manager>
<beans:bean id="myPasswordEncoder"class="InterceptingPassordEncoderSubclassShaPasswordEncoder" />