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
指向service
和service
指向datasource
。
编辑:在Java中,你将不得不编码的密码是这样的:
DigestUtils.sha(request.getParameter("password"));
警告:小心! 不要将SHA与MD5混合!
如果将authentication-provider
的password-encoder
设置为SHA ,则需要使用Java编码以保持一致。 但是,如果您将Java作为MD5引用,那么您不要忘记将哈希设置为“md5”。 DigestUtils还提供了md5编码器:
DigestUtils.md5(request.getParameter("password"));
接受的答案是正确的。 我用spring 3.1和BCrypt编码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>