【问题标题】:How to get the username and entered password without encoding with spring boot security如何使用spring boot security获取用户名和输入的密码而不进行编码
【发布时间】:2016-02-29 18:04:17
【问题描述】:

我已经使用 Spring Boot 安全性实现了安全层,并且我使用了 MD5 加密机制来对提供的密码进行编码。它按预期完美运行,但我需要获取用户在 DAO 或服务层中输入的用户名和原始密码。以下是我使用的代码

@Autowired
UserDao userDao;

@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;

@Autowired
private RESTAuthenticationEntryPoint authenticationEntryPoint;

@Autowired
private RESTAuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private RESTAuthenticationSuccessHandler authenticationSuccessHandler;

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/css/**", "/fonts/**", "/images/**");
}


/**
 * Security implementation to access the services
 */
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/", "/index.html","/home.html","/page/*","/home/*", "/login.html","/login","/cms/createPhoneNo").permitAll();
    http.authorizeRequests().anyRequest().fullyAuthenticated().and().httpBasic().and().csrf().disable();
    http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
    http.formLogin().loginProcessingUrl("/login/authenticate").successHandler(authenticationSuccessHandler);
    http.formLogin().failureHandler(authenticationFailureHandler);
    http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).invalidateHttpSession(true);
    http.exceptionHandling().accessDeniedHandler(accessDeniedHandler());

    // CSRF tokens handling
    http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);
}

/**
 * Configures the authentication manager bean which processes authentication
 * requests.
 */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // Dao based authentication
    auth.userDetailsService(userDetailsService).passwordEncoder(new Md5PasswordEncoder());
}

private AccessDeniedHandler accessDeniedHandler() {
    return new AccessDeniedHandler() {

        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response,
                AccessDeniedException accessDeniedException) throws IOException, ServletException {
            response.getWriter().append("Access denied");
            response.setStatus(403);
        }
    };
}

/**
 * This bean is load the user specific data when form login is used.
 */
@Bean
public UserDetailsService userDetailsService() {
    return new MyCustomUserDetailsService(userDao);
}

}

有人可以帮我实现这个场景吗?

谢谢,

【问题讨论】:

  • 你不能“解码”md5。 Md5 是(非常弱的)单向哈希。我能问你为什么要原始密码吗?散列的重点是没有这个。另外,请考虑至少使用 sha-256 或 bcrypt 或 scrypt,md5 非常弱,除了校验和之外,它并不适合任何东西。
  • @Taylor 实际上,我需要根据用户类型检查两个数据库的用户身份验证。在一个数据库中,如果找不到输入的用户,我会为具有用户类型的用户编码密码该用户类型我需要切换到另一个数据库,我将密码作为原始密码,所以我需要输入原始密码。你对此有任何想法吗?
  • 您不需要原始密码。您只需使用与前端相同的方法对数据库中的密码进行哈希处理并比较哈希值。

标签: spring-security spring-boot


【解决方案1】:

在我提供答案之前,必须警告:

以明文形式存储用户密码是非常危险的。无论谁 有权访问 db 有权访问用户的密码,这意味着他们可以 在您的应用程序中模拟用户。用户也倾向于重用 密码,因此您将该用户暴露在其他系统上的风险(他们的 电子邮件、他们的 Facebook 等...)。

别挡道,哦等等,再来一个:

MD5 是一种非常弱的单向哈希。以rainbow tables为准 生成给定哈希的纯文本很容易被发现。 考虑改用更强大的东西,比如 SHA-256、Scrypt、 Bcrypt 或 PBKDF2。

好的,完成了。使用 org.springframework.security.authentication.encoding.PlaintextPasswordEncoder 并在您的 DAO 中按需应用 MD5(或更好的轻推)哈希。

【讨论】:

  • 如何使用该类获取daoorg.springframework.security.authentication.encoding.PlaintextPasswordEncoder中的原始密码
  • @TaylorActually 我需要用户在 Dao 中提供密码,就像我们使用 HttpServletRequest 来获取请求参数一样。有可能吗?
  • 如果你使用上面的,它应该在auth token中。
【解决方案2】:

添加到您的configure(AuthenticationManagerBuilder) 方法中:

auth.eraseCredentials(false);

然后你可以得到当前用户的用户名和密码:

String username = SecurityContextHolder.getContext().getAuthentication().getName();
Object rawPassword  = SecurityContextHolder.getContext().getAuthentication().getCredentials();

【讨论】:

  • @holmis我们可以使用该方法在用户通过身份验证后获取。我说得对吗?
  • @DIVA 是的,经过身份验证后。
  • 在验证用户之前我需要用户凭据。然后,只有我可以实现方案。是否可以在 Dao 中使用 HttpServletRequest。我使用了如下但我收到如下错误,“未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?”。你能帮帮我?
  • @DIVA 不,您无法恢复散列密码。
  • @HomisYes。我同意,但是有什么方法可以在 Dao 中获取请求参数。我可以在一个通用类中获取请求参数,如下面的代码。我想在 Dao 中使用它。
猜你喜欢
  • 2016-05-16
  • 2020-01-18
  • 2013-08-12
  • 2019-03-23
  • 2017-10-16
  • 2015-03-09
  • 2016-08-04
  • 2020-09-07
  • 2015-07-25
相关资源
最近更新 更多