簡體   English   中英

Spring Security-使用BCrypt哈希密碼的用戶身份驗證(錯誤的憑證錯誤)

[英]Spring Security - user authentication with BCrypt hashed password (bad credentials error)

注冊新用戶后,數據庫中生成的哈希密碼與為進行身份驗證而輸入的用戶輸入的密碼不匹配。 原始密碼相同,但哈希版本不同。 我想知道如何使這兩個相互匹配以進行正確的身份驗證? 我正在使用Spring 4.3.2.RELEASE和4.2.0.RELEASE來提高安全性。

我也有一個警告:

WARN SpringSecurityCoreVersion:78 - **** You are advised to use Spring 4.3.4.RELEASE or later with this version. You are running: 4.3.0.RELEASE

也許這在某種程度上引起了問題。

config.xml文件:

<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

<security:authentication-manager>
    <security:authentication-provider user-service-ref="userService">
        <security:password-encoder ref="encoder"/>
    </security:authentication-provider>
</security:authentication-manager>

<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="userService" />
    <property name="hideUserNotFoundExceptions" value="false" />
    <property name="passwordEncoder" ref="encoder" />
</bean>

<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
    <constructor-arg>
        <ref bean="daoAuthenticationProvider" />
    </constructor-arg>
</bean>

UserEntity.java:

public void setPassword(String password) {
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    this.password = passwordEncoder.encode(password);
}

UserAuthenticationProviderService.java:

public boolean processUserAuthentication(UserEntity user) {

    try {
        Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        Authentication result = authenticationManager.authenticate(request);
        SecurityContextHolder.getContext().setAuthentication(result);

        return true;
    } catch(AuthenticationException e) {
        FacesContext.getCurrentInstance().addMessage(null, 
                new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "Catched Error!"));

        return false;
    }
}

編輯:解決。

正如肖恩所說,問題在於實體類中的編碼。 將編碼移至用戶創建位置后,一切都會正常運行,因為編碼現在僅在用戶創建過程中出現。 謝謝!

是的,您注意到在通過BCryptEncoder對同一字符串進行2種編碼之后,您將獲得不同的字符串。 但是,Spring Security並不將匹配用於等於。 當您注冊編碼器時,SPring Security將使用來自PasswordEncoder(BCryptEncoder實現此接口)的boolean matches(CharSequence rawPassword, String encodedPassword) encodingPassword)。

如果您對細節感興趣,可以查看BCrypt的實現,它非常簡單:

static boolean equalsNoEarlyReturn(String a, String b) {
        char[] caa = a.toCharArray();
        char[] cab = b.toCharArray();

        if (caa.length != cab.length) {
            return false;
        }

        byte ret = 0;
        for (int i = 0; i < caa.length; i++) {
            ret |= caa[i] ^ cab[i];
        }
        return ret == 0;
    }

暫無
暫無

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

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