繁体   English   中英

绕过 Spring 中的 PasswordEncoder 已加密密码的安全性

[英]Bypass PasswordEncoder in Spring Security for already encrypted passwords

我有一个 REST Spring Boot 2 应用程序。 对于这个应用程序,我正在尝试实现一种安全机制,该机制将接受带有原始密码和加密密码的登录请求。

对于原始密码,应用程序可以正常工作。 我可以创建用户,将他们的加密密码存储在数据库中,并在他们发送原始密码时对其进行身份验证。

问题是在某些情况下,我们的客户端服务具有预先配置的用户,他们的密码已经加密,他们需要发送这个加密的密码进行身份验证。

我目前的配置如下:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Autowired
    private AuthEntryPointJwt unauthorizedHandler;

    @Bean
    public AuthTokenFilter authenticationJwtTokenFilter() {
        return new AuthTokenFilter();
    }

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new PasswordEncoder() {

            final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10, new SecureRandom());

            @Override public String encode(CharSequence rawPassword) {
                return encoder.encode(rawPassword);
            }

            @Override public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return encoder.matches(rawPassword, encodedPassword);
            }
        };
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated();

        http.headers()
                .frameOptions()
                .sameOrigin();
        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

有没有办法绕过 PasswordEncoder? 因为在某些情况下已经有一个加密密码,也许我们需要的只是将它与现有存储的加密密码进行比较。

另外,这会是反模式吗? 任何提示表示赞赏。

如果您不知道密码是否已编码,您可以尝试此操作,但需要使用相同的算法对其进行哈希处理。

   @Override public boolean matches(CharSequence rawPassword, String encodedPassword) {
            if(encodedPassword.equals(rawPassword.toString())
                 return true;

            return encoder.matches(rawPassword, encodedPassword);
        }

您可以创建密码编码器的 noop 实现:

**NoOpPasswordEncoder.getInstance()** 

要处理编码/原始密码,您可以实现自己的:

**AuthenticationEntryPoint**

您可以在其中实现基于某种 header 的逻辑? 您可以在 Spring 安全配置中使用它

http.cors().and().exceptionHandling().authenticationEntryPoint(<yourEntryPoint>)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM