如何在UserDetailsS​​ervice中检索用户输入的密码

时间:2014-01-15 20:03:18

标签: spring spring-security

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拦截用户的密码吗?

1 个答案:

答案 0 :(得分:2)

UserDetailsService负责加载用户并提供包含存储在数据库中的密码的UserDetails对象。不幸的是(对你而言)在大多数情况下,这个密码被哈希(SHA或MD5)。

如果要拦截用户输入的密码,则有不同的选择:

  • UserNamePasswordFilter(当您使用表单身份验证时,如果您使用其他类型的身份验证,则需要其他过滤器)在一个点上截取密码。它负责获取登录http请求,创建UserNamePasswordAuthenticationToken并将其转发给AuthenticationManager

  • 另一个拦截点是AuthenticationManager(更准确的是ProviderManager - 然后才真正实现AuthenticationManager)。它有一个方法Authentication authenticate(Authentication authentication),用于输入用户输入(Authentication的子类,例如UsernamePasswordAuthenticationToken)并验证它(通过将其转发到AuthenticationProvider

    < / LI>
  • 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" />