【问题标题】:Spring security with password encoding and salting带有密码编码和加盐的 Spring 安全性
【发布时间】:2016-04-06 04:30:32
【问题描述】:

我正在尝试使用 SHA 散列和加盐对具有 spring-security 的用户进行身份验证。我在用户表中添加了额外的字段以获取额外的盐,并使用此盐自定义 UserDetails,但每当我尝试登录时,它都会引发错误的凭据异常。

我的CustomJdbcDaoImpl 班级是:

public class CustomJdbcDaoImpl extends JdbcDaoImpl implements IChangePassword {

    private Logger logger = LoggerFactory.getLogger(CustomJdbcDaoImpl.class);
    

    @Override
    protected UserDetails createUserDetails(String username,UserDetails userFromUserQuery,
            List<GrantedAuthority> combinedAuthorities){
        String returnUsername = userFromUserQuery.getUsername();
        if(!isUsernameBasedPrimaryKey()){
            returnUsername = username;
        }
        logger.info("inside @class CustomJdbcDaoImpl @method createUserDetails USER DETAILS ARE: "+userFromUserQuery.getPassword()+"authritieds: "+combinedAuthorities);
        return new SaltedUser(returnUsername, 
                userFromUserQuery.getPassword(),
                userFromUserQuery.isEnabled(), 
                true,
                true, 
                true, 
                combinedAuthorities,
                ((SaltedUser)userFromUserQuery).getSalt());
         

    }

    @Override
    protected List<UserDetails> loadUsersByUsername(String username) {
        return getJdbcTemplate()
                .query(getUsersByUsernameQuery(), 
                        new String[] {username}, 
                        new RowMapper<UserDetails>() {
                    public SaltedUser mapRow(ResultSet rs, int rowNum) throws SQLException {
                        String username = rs.getString(1);
                        String password = rs.getString(2);
                        boolean enabled = rs.getBoolean(3);
                        String salt = rs.getString(4);
                        SaltedUser saltedUser = new SaltedUser(username, password, enabled,
                                true, 
                                true,
                                true,
                                AuthorityUtils.NO_AUTHORITIES, 
                                salt);
                        logger.info("inside @class @method loadUsersByUsername salted password  is: "+saltedUser.getPassword());
                        return saltedUser;
                    }
                    

                });
    }

    @Override
    public void changePassword(String username, String password) {
        getJdbcTemplate().
        update("update users set password = ? where username = ?",password,username);
        
    }

}

每次用盐更改密码我的DatabasePasswordSecurerBean 类是

public class DatabasePasswordSecurerBean extends JdbcDaoSupport {
    
        @Autowired
        private  PasswordEncoder passwordEncoder;
        
        @Autowired
        private SaltSource saltSource;
            
        @Autowired
        private UserDetailsService userDetailsService;
        
        private Logger logger = LoggerFactory.getLogger(DatabasePasswordSecurerBean.class);
        
        public void secureDatabase(){
            logger.info("inside @class DatabasePasswordSecurerBean  @method secureDatabase entry...");
            getJdbcTemplate().query("select username,password from users",new RowCallbackHandler(){
    
                @Override
                public void processRow(ResultSet rs) throws SQLException {
                   String username = rs.getString(1);
                   String password = rs.getString(2);
                   
                   UserDetails user = userDetailsService.loadUserByUsername(username);
                   String encodedPassword = passwordEncoder.encodePassword(password,saltSource.getSalt(user));
                   getJdbcTemplate().update("update users set password = ? where username = ?",
                          encodedPassword,username);
                  
                 logger.info("@class DatabasePasswordSecurerBean  @method secureDatabase updating password for user: "+username + "to: "+encodedPassword);
                }
                  
                
            });
            
        }
        
    }

 security.xml configurations are 

    
   

     <http auto-config="true">
          <intercept-url pattern="/*" access="ROLE_USER" />
        </http>
        
        <authentication-manager alias="authenticationManager">
                <authentication-provider user-service-ref="jdbcUserService">
                  <password-encoder ref="passwordEncoder" >
                    <salt-source ref="saltSource" />
                  </password-encoder>
                  
                  
                  
                </authentication-provider>
        </authentication-manager>
        
            
        </beans:beans>
    
     

我的 application.xml 是

<!-- Simple implementation of the standard JDBC DataSource interface,
                configuring the plain old JDBC DriverManager via bean properties -->
           <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="${db.driverClassName}" />
              <property name="url" value="${db.connection.url}" />
              <property name="username" value="${db.connection.username}" />
              <property name="password" value="${db.connection.password}" />
           </bean>
                                                                                 
           <bean id="jdbcUserService" class="com.petCart.springsecurity.security.CustomJdbcDaoImpl">
              <property name="dataSource" ref="dataSource" />
              <property name="enableGroups" value="true"></property>
              <property name="enableAuthorities" value="false"></property>
              <property name="usersByUsernameQuery">
                    <value>
                       select username,password,enabled,salt from users where username = ?
                    </value>
              </property>
              <property name="groupAuthoritiesByUsernameQuery">
                    <value>
                       select r.roleid,r.role_name,p.permissionname from roles r
                       join userrole ur on ur.roleid = r.roleid
                       join users u on u.id = ur.userid 
                       join rolepermission rp on r.roleid = rp.roleid 
                       join permissions p on p.permissionid = rp.permissionid
                       where u.username = ?
                    </value>
              </property>
          </bean>
          
          <!-- password encoder -->
           <bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" id="passwordEncoder"/>
           <bean class="com.petCart.springsecurity.security.DatabasePasswordSecurerBean"  init-method="secureDatabase" depends-on="dataSource">
                <property name="dataSource" ref="dataSource" />
           </bean>
           <bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
               <property name="userPropertyToUse" value="username" />
           </bean>
    
       

【问题讨论】:

  • 我真的把我的假期和所有这些东西混为一谈,请有人帮助我......
  • 可能不是您期望的答案,但是您为什么不使用 Spring Security 已经提供的 BCrypt 呢?它比SHA强,还包含salt,一切由你管理,你只需要调用密码编码器。

标签: spring spring-security salt


【解决方案1】:

尝试改变

<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
   <property name="userPropertyToUse" value="username" />
</bean>

<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
   <property name="userPropertyToUse" value="salt" />
</bean>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-23
    • 2012-07-05
    • 2014-12-31
    • 1970-01-01
    • 2011-12-06
    • 2016-07-28
    • 2010-09-28
    相关资源
    最近更新 更多