Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 当重新检查密码时,无法使Bcrypt哈希生效_Spring_Spring Security Oauth2 - Fatal编程技术网

Spring 当重新检查密码时,无法使Bcrypt哈希生效

Spring 当重新检查密码时,无法使Bcrypt哈希生效,spring,spring-security-oauth2,Spring,Spring Security Oauth2,我使用Bcrypt散列密码,并根据Spring文档使用Random。我使用的是SpringSecurity 3.2.5.0版本 我有以下OAuth2安全配置: <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema

我使用Bcrypt散列密码,并根据Spring文档使用Random。我使用的是SpringSecurity 3.2.5.0版本

我有以下OAuth2安全配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:oauth2="http://www.springframework.org/schema/security/oauth2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

    <beans:bean id="userService" class="com.nando.api.service.DefaultUserService" />
    <beans:bean id="webServiceClientService"
        class="com.nando.api.service.DefaultWebServiceClientService" />
    <beans:bean id="clientDetailsUserService"
        class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
        <beans:constructor-arg ref="webServiceClientService" />
    </beans:bean>

    <beans:bean id="sessionRegistry"
        class="org.springframework.security.core.session.SessionRegistryImpl" />

    <beans:bean id="webSecurityExpressionHandler"
        class="org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler" />
    <beans:bean id="methodSecurityExpressionHandler"
        class="org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler" />

    <beans:bean id="passwordEncoder"
        class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

    <beans:bean id="tokenStore"
        class="com.nando.api.service.DefaultAccessTokenService" />

    <beans:bean id="oauthRequestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
        <!-- TODO arguments here -->
        <beans:constructor-arg name="clientDetailsService" ref="webServiceClientService" />
        <!-- <beans:property name="securityContextAccessor" ref="oauthRequestFactory" /> -->
    </beans:bean>

    <beans:bean id="userApprovalHandler"
        class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
        <beans:property name="tokenStore" ref="tokenStore" />
        <!-- TODO here -->
        <beans:property name="requestFactory" ref="oauthRequestFactory" />
    </beans:bean>

    <beans:bean id="oauthAccessDeniedHandler"
        class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

    <beans:bean id="oauthAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint" />

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

    <authentication-manager id="oauthClientAuthenticationManager">
        <authentication-provider user-service-ref="clientDetailsUserService">
            <password-encoder ref="passwordEncoder" />
        </authentication-provider>
    </authentication-manager>

    <oauth2:authorization-server
        token-services-ref="tokenStore" client-details-service-ref="webServiceClientService"
        user-approval-page="oauth/authorize" error-page="oauth/error">
        <oauth2:authorization-code />
    </oauth2:authorization-server>

    <beans:bean id="nonceServices"
        class="com.nando.api.service.DefaultOAuthNonceService" />
    <beans:bean id="resourceServerFilter"
        class="com.nando.api.filters.OAuthSigningTokenAuthenticationFilter">
        <beans:property name="authenticationEntryPoint" ref="oauthAuthenticationEntryPoint" />
        <beans:property name="nonceServices" ref="nonceServices" />
        <beans:property name="tokenStore" ref="tokenStore" />
        <beans:property name="resourceId" value="nando" />
    </beans:bean>

    <global-method-security pre-post-annotations="enabled"
        order="0" proxy-target-class="true">
        <expression-handler ref="methodSecurityExpressionHandler" />
    </global-method-security>

    <http security="none" pattern="/resource/**" />
    <http security="none" pattern="/favicon.ico" />

    <http use-expressions="true" create-session="stateless"
        authentication-manager-ref="oauthClientAuthenticationManager"
        entry-point-ref="oauthAuthenticationEntryPoint" pattern="/oauth/token">
        <intercept-url pattern="/oauth/token" access="hasAuthority('OAUTH_CLIENT')" />
        <http-basic />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
        <expression-handler ref="webSecurityExpressionHandler" />
    </http>

    <http use-expressions="true" create-session="stateless"
        entry-point-ref="oauthAuthenticationEntryPoint" pattern="/services/**">
        <intercept-url pattern="/services/**"
            access="hasAuthority('USE_WEB_SERVICES')" />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
        <expression-handler ref="webSecurityExpressionHandler" />
    </http>

    <http use-expressions="true">
        <intercept-url pattern="/session/list"
            access="hasAuthority('VIEW_USER_SESSIONS')" />
        <intercept-url pattern="/oauth/**"
            access="hasAuthority('USE_WEB_SERVICES')" />
        <intercept-url pattern="/login/**" access="permitAll()" />
        <intercept-url pattern="/login" access="permitAll()" />
        <intercept-url pattern="/logout" access="permitAll()" />
        <intercept-url pattern="/**" access="isFullyAuthenticated()" />
        <form-login default-target-url="/ticket/list" login-page="/login"
            login-processing-url="/login/submit" authentication-failure-url="/login?loginFailed"
            username-parameter="username" password-parameter="password" />
        <logout logout-url="/logout" logout-success-url="/login?loggedOut"
            delete-cookies="JSESSIONID" invalidate-session="true" />
        <session-management invalid-session-url="/login"
            session-fixation-protection="changeSessionId">
            <concurrency-control error-if-maximum-exceeded="true"
                max-sessions="1" session-registry-ref="sessionRegistry" />
        </session-management>
        <csrf />
        <expression-handler ref="webSecurityExpressionHandler" />
    </http>

</beans:beans>
其中:

private static final SecureRandom RANDOM;

    static {
        try {
            RANDOM = SecureRandom.getInstanceStrong();
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e);
        }
    }
private static final int HASHING_ROUNDS = 10;
密码经过哈希处理并正确生成。它被正确地保存在数据库中,并被正确地检索。但是当它被检查时,呈现的密码不会被散列,因此比较失败

首先,this.saltSource为null,因为我没有定义盐bean。我认为这是随机的,盐是老办法

现在,当查看调试器时:

if (this.saltSource != null) {
            salt = this.saltSource.getSalt(userDetails);
        }

        if (authentication.getCredentials() == null) {
            logger.debug("Authentication failed: no credentials provided");

            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
        }

        String presentedPassword = authentication.getCredentials().toString();

        if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {
            logger.debug("Authentication failed: password does not match stored value");

            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
        }
presentedPassword没有散列,salt为空。所以!passwordEncoder.isPasswordValiduserDetails.getPassword、presentedPassword、salt测试检查失败


如果我使用的是随机盐,我如何才能让它起作用?我遗漏了什么?

在我看来很好,isPasswordValid检查应该会调用到您的密码编码器中。我不太清楚你认为哪里出了问题。你是说你的密码编码器从未被调用?您如何确保密码正确存储?什么是转换器?你的UserDetails是如何从你创建的UserPrincipal中获取密码的?由于你有许多具有not pattern属性的blocs,因此只会使用第一个blocs…@SergeBallesta只有一个没有模式最后一个oneNow我也有同样的问题,在我切换到使用UserDetailsPrice of Spring之前,我使用的是JDBC,它可以正常工作,但我对Spring数据库模式不满意,所以我使用自定义方式检索UserEntity!
if (this.saltSource != null) {
            salt = this.saltSource.getSalt(userDetails);
        }

        if (authentication.getCredentials() == null) {
            logger.debug("Authentication failed: no credentials provided");

            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
        }

        String presentedPassword = authentication.getCredentials().toString();

        if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {
            logger.debug("Authentication failed: password does not match stored value");

            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
        }