Spring Security:数据库和applicationContext中的密码编码

有configuration(applicationContext-security.xml):

<authentication-manager alias="authenticationManager"> <authentication-provider> <password-encoder hash="sha"/> <jdbc-user-service data-source-ref="dataSource"/> </authentication-provider> </authentication-manager> 

从另一端有SQL从我的dataSource (这是JdbcDaoImpl ):

 ... public static final String DEF_USERS_BY_USERNAME_QUERY = "select username,password,enabled " + "from users " + "where username = ?"; ... 

现在在这个代码中有关于sha字,所以从标准Spring Security users表中select的密码不是编码的。

也许,我应该在我的hibernate映射configuration中为password列提供一些sha属性:

 <class name="model.UserDetails" table="users"> <id name="id"> <generator class="increment"/> </id> <property name="username" column="username"/> <property name="password" column="password"/> <property name="enabled" column="enabled"/> <property name="mail" column="mail"/> <property name="city" column="city"/> <property name="confirmed" column="confirmed"/> <property name="confirmationCode" column="confirmation_code"/> <set name="authorities" cascade="all" inverse="true"> <key column="id" not-null="true"/> <one-to-many class="model.Authority"/> </set> </class> 

现在密码保存到数据库,但应该编码。

如何将friendContextconfiguration和DB查询的朋友进行相同的密码编码?

如果您自己select哈希系统,而不是使用已经包含哈希密码的现有数据库构build应用程序,那么您应该确保哈希algorithm也使用盐。 不要只使用简单的摘要。

一个好的select是bcrypt,我们现在通过BCryptPasswordEncoder直接在Spring Security 3.1中BCryptPasswordEncoder (使用jBCrypt实现)。 这会自动生成一个salt,并将其与单个String中的散列值连接起来。

有些数据库内置了对散列的支持(例如Postgres )。 否则,在将它传递给JDBC之前,您需要自己散列密码:

 String password = "plaintextPassword"; PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String hashedPassword = passwordEncoder.encode(password); 

这就是您创build用户时需要对密码进行编码的全部内容。

对于身份validation,您可以使用类似于:

 <bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="yourJdbcUserService" /> <property name="passwordEncoder" ref="encoder" /> </bean> 

多一点接受答案的解释。 希望它可以帮助别人。

把它放到数据库之前自己散列密码:

 String password = "plaintextPassword"; PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String hashedPassword = passwordEncoder.encode(password); 

将BCryptPasswordEncoder bean添加到您的security-config.xml中

将passwordEncoder作为属性添加到Authentication Provider类。 Autowire它或提供setter和getter方法。

 @AutoWired private BCryptPasswordEncoder passwordEncoder; 

在authentication用户login时获取财产

 <bean id="dbAuthenticationProvider" class="mypackage.auth.spring.DBAuthenticationProvider" > <property name="dataSource" ref="routingDataSource"></property> <property name="passwordEncoder" ref="encoder" /> <property name="passwordQuery" value="select password as password from tbl where username=:username"> </property> </bean> 

并在authentication类匹配两个密码

  new BCryptPasswordEncoder().matches(plainTextPasswdFromUserInput, hashedPasswdFromDb) 

以一种简单的方式,你可以在applicationContext-security.xml中做类似的事情

 <authentication-manager alias="authenticationManager"> <authentication-provider> <password-encoder ref="encoder"/> <jdbc-user-service data-source-ref="dataSource" users-by-username-query=" select username,password, enabled from principal where username=?" authorities-by-username-query=" select p.username, a.authority from principal p, authority a where p.id = a.principal_id and p.username=?" /> </authentication-provider> </authentication-manager> <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> 

在Java中

 public static String encodePasswordWithBCrypt(String plainPassword){ return new BCryptPasswordEncoder().encode(plainPassword); } 

然后testing它

 System.out.println(encodePasswordWithBCrypt("fsdfd")); 

使用Spring Security 3.1,试试这个:

 <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="service"> <password-encoder hash="sha"/> <jdbc-user-service data-source-ref="dataSource"/> </authentication-provider> </authentication-manager> <beans:bean id="dataSource" ...> ... </beans:bean> <beans:bean id="service" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <beans:property name="dataSource" ref="dataSource"/> ... </beans:bean> 

什么是新的: authentication-provider指向serviceservice指向datasource

编辑:在Java中,你将不得不编码的密码是这样的:

 DigestUtils.sha(request.getParameter("password")); 

警告:小心! 不要将SHAMD5混合!

如果将authentication-providerpassword-encoder设置为SHA ,则需要使用Java编码以保持一致。 但是,如果您将Java作为MD5引用,那么您不要忘记将哈希设置为“md5”。 DigestUtils还提供了md5编码器:

 DigestUtils.md5(request.getParameter("password")); 

接受的答案是正确的。 我用spring 3.1BCrypt编码algorithmtesting了它。

创build用户时。

 PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword())); userDao.save(userEntity); 

当用户login时,请记住,使用明文密码( 不散列 )。 就像:

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

这里是安全configuration:

  <bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <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> 

希望它会帮助别人!

只是一个小贴士做注释

 @Configuration @EnableWebSecurity @PropertySource("classpath://configs.properties") public class SecurityContextConfig extends WebSecurityConfigurerAdapter { @Autowired @Qualifier("userDetailsService") private UserDetailsService userDetailsService; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder()); } @Bean(name = "passwordEncoder") public PasswordEncoder getPasswordEncoder(){ return new BCryptPasswordEncoder(); } } 

与3.1.x这个映射不适用于身份validation。 工作方式是:

 <beans:bean id='bCryptPasswordEncoder' class='org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder'></beans:bean> <authentication-manager> <authentication-provider user-service-ref="userDetailsService"> <password-encoder ref="bCryptPasswordEncoder"/> </authentication-provider> </authentication-manager>