database Spring Security:DB 和 applicationContext 中的密码编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8521251/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Security:password encoding in DB and in applicationContext
提问by sergionni
Have config (applicationContext-security.xml):
有配置(applicationContext-security.xml):
<authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder hash="sha"/>
<jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>
</authentication-manager>
from other side have SQLs from my dataSource(it's JdbcDaoImpl):
从另一边有来自我的 SQL dataSource(它是JdbcDaoImpl):
...
public static final String DEF_USERS_BY_USERNAME_QUERY =
"select username,password,enabled " +
"from users " +
"where username = ?";
...
There is now word about shain this code,so password selected from standard Spring Security userstable not encoded.
sha这段代码现在有字,所以从标准 Spring Securityusers表中选择的密码没有编码。
Perhaps, I should provide some shaattribute for passwordcolumn in my hibernate mapping config here:
也许,我应该在这里sha为password我的休眠映射配置中的列提供一些属性:
<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>
For now password saved to DB as is,but should be encoded.
现在密码按原样保存到数据库,但应该进行编码。
How to friend applicationContextconfig and DB queries to be the same password encoding?
如何使applicationContext配置和数据库查询成为相同的密码编码?
回答by Shaun the Sheep
If you are choosing a hashing system yourself, rather than building an app using an existing database which already contains hashed passwords, then you should make sure your hashing algorithm also uses a salt. Don't just use a plain digest.
如果您自己选择散列系统,而不是使用已经包含散列密码的现有数据库构建应用程序,那么您应该确保您的散列算法也使用盐。不要只使用简单的摘要。
A good choice is bcrypt, which we now support directly in Spring Security 3.1 via the BCryptPasswordEncoder(implemented using jBCrypt). This automatically generates a salt and concatenates it with the hash value in a single String.
一个不错的选择是 bcrypt,我们现在通过BCryptPasswordEncoder(使用jBCrypt实现)在 Spring Security 3.1 中直接支持它。这会自动生成一个盐并将其与单个字符串中的哈希值连接起来。
Some databases have built-in support for hashing (e.g. Postgres). Otherwise, you need to hash the password yourself before passing it to JDBC:
一些数据库内置了对散列的支持(例如Postgres)。否则,您需要在将密码传递给 JDBC 之前自己散列密码:
String password = "plaintextPassword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
That's all you need to do to encode the passwords when you create a user.
这就是您在创建用户时对密码进行编码所需要做的全部工作。
For authentication, you would use something like:
对于身份验证,您将使用以下内容:
<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>
回答by false9striker
A little more explanation on the accepted answer. Hope it helps someone.
关于接受的答案的更多解释。希望它可以帮助某人。
Hash the password yourself before putting it to database:
在将密码放入数据库之前自己散列密码:
String password = "plaintextPassword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
Add BCryptPasswordEncoder bean to your security-config.xml
将 BCryptPasswordEncoder bean 添加到您的 security-config.xml
Add passwordEncoder as a property to Authentication Provider class. Autowire it or provide setter and getter methods.
将 passwordEncoder 作为属性添加到身份验证提供程序类。自动装配它或提供 setter 和 getter 方法。
@AutoWired
private BCryptPasswordEncoder passwordEncoder;
Get the property while you authendicate user for 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>
And in the authenticating class match both passwords
并且在身份验证类中匹配两个密码
new BCryptPasswordEncoder().matches(plainTextPasswdFromUserInput, hashedPasswdFromDb)
回答by falsarella
Using Spring Security 3.1, try this:
使用 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>
What's new: authentication-providerpoints to serviceand servicepoints to datasource.
新增内容:authentication-provider指向service和service指向datasource.
Edit:In Java you will have to encode the password with something like this:
编辑:在 Java 中,您必须使用以下内容对密码进行编码:
DigestUtils.sha(request.getParameter("password"));
Warn:Be careful! Do not mix SHAwith MD5!
警告:小心!不要将SHA与MD5混合使用!
If you set the password-encoderof the authentication-provideras SHA, you need to encode in Java the same way to keep consistent. But if you enconde in Java as MD5, as the sample you found, do not forget to set the hashto "md5". DigestUtilsalso provides md5 encoder:
如果设置password-encoder的authentication-provider是SHA,你需要在Java编码相同的方式保持一致。但是,如果您将 Java 编码为MD5,就像您找到的示例一样,请不要忘记将哈希设置为“md5”。DigestUtils还提供了 md5 编码器:
DigestUtils.md5(request.getParameter("password"));
回答by user2368100
In a simple way can you do something like in applicationContext-security.xml
以一种简单的方式,您可以在 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"/>
In Java
在 Java 中
public static String encodePasswordWithBCrypt(String plainPassword){
return new BCryptPasswordEncoder().encode(plainPassword);
}
Then test it
然后测试一下
System.out.println(encodePasswordWithBCrypt("fsdfd"));
回答by Alireza Fattahi
Just a tip for doing it with annotations
只是使用注释进行操作的提示
@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();
}
}
回答by maoyang
The accepted answer is right. I tested it with spring 3.1and BCryptencode algorithm.
接受的答案是正确的。我用spring 3.1和BCrypt编码算法对其进行了测试。
When create a user.
创建用户时。
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword()));
userDao.save(userEntity);
When the user login, Remember, use the plain password (not hashed). just like:
当用户登录时,请记住,使用普通密码(未散列)。就像:
Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
Here is security-config:
这是安全配置:
<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>
Hope it will help somebody!
希望它会帮助某人!
回答by z0mb1ek
with 3.1.x this mapping doesnt work for auth. Working way is:
对于 3.1.x,此映射不适用于身份验证。工作方式是:
<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>

