簡體   English   中英

如何在Spring-Security中創建條件AuthenticationProvider?

[英]How to create conditional AuthenticationProvider in Spring-Security?

到目前為止,我已將用戶名和加密的密碼存儲在數據庫中。

我的自定義UserDetailsService從數據庫中查找用戶。 密碼以加密方式存儲,因此在此處應用BCryptPasswordEncoder

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }
}

問題:現在,我必須添加一個附加身份驗證源,該身份驗證源提供未加密的密碼(對此我無能為力 )。 因此,如果在我的數據庫中找不到通過身份驗證的用戶,我想使用未加密的密碼檢查其他源。 但是,在那些情況下如何禁用BCrypt編碼器?

您可以如下配置多個身份驗證提供程序。 依次對每個身份驗證提供程序進行測試,成功的一個首先提供身份驗證的數據,其余的將被跳過。 類似的用例以類似的方式實現,您必須首先通過數據庫進行身份驗證,然后以類似的方式處理LDAP服務器(反之亦然)。

@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authenticationProviderWithEncryptedUser);
    auth.authenticationProvider(authenticationProviderWithNonEncryptedUser);

}

幾天前我也遇到了這個問題,我的舊系統數據在MD5加密,但是新系統在BCrypt保存了密碼

為處理此問題,我編寫了一些自定義代碼,並使用AuthenticationProvider代替了UserDetailsService

在這里,我會剪裁代碼為您提供幫助

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    LoginDao loginDao;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        List<GrantedAuthority> grantList = new ArrayList<>();
        String name = authentication.getName();
        String password = ((String) authentication.getCredentials()).trim();
        try {
            UserModel user = loginDao.getUser(name);
            if (user != null) {
                if (passwordEncoder().matches(password, user.getLoginPass())) {
                //  System.out.println("------Good new & Strong password -----");
                    GrantedAuthority authority = new SimpleGrantedAuthority(user.getAuthotype().toString());
                    grantList.add(authority);
                }else if (password.equals(user.getLoginPass())) {//here i have md5 checker service , i remove it for your help 
                //  System.out.println("------old password! should be change it-----"); 
                    GrantedAuthority authority = new SimpleGrantedAuthority(user.getAuthotype().toString());
                    grantList.add(authority);
                }else {
                    throw new BadCredentialsException("Please enter a valid username and password.");
                }
                    return new UsernamePasswordAuthenticationToken(user, password, grantList);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BadCredentialsException("Please enter a valid username and password.");
        }
        throw new BadCredentialsException("Please enter a valid username and password.");
    }

    @Override
    public boolean supports(Class<? extends Object> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }

}

並更改您的SecurityConfiguration類代碼

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }

根據當前文檔( https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/password/DelegatingPasswordEncoder.html ),我只需要刪除我的二傳手Spring中的.passwordEncoder()依賴於新的默認密碼委派功能。

然后在我的所有密碼前加上{bcrypt}作為數據庫密碼,並在{noop}加上新的純文本密碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM