Security-applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<sec:http auto-config='true' access-denied-page="/access-denied.html">
<!-- NO RESTRICTIONS -->
<sec:intercept-url pattern="/login.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/*.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- RESTRICTED PAGES -->
<sec:intercept-url pattern="/admin/*.html" access="ROLE_ADMIN" />
<sec:intercept-url pattern="/athlete/*.html" access="ROLE_ADMIN, ROLE_STAFF" />
<sec:form-login login-page="/login.html"
login-processing-url="/loginProcess"
authentication-failure-url="/login.html?login_error=1"
default-target-url="/member" />
<sec:logout logout-success-url="/login.html"/>
</sec:http>
<beans:bean id="customUserDetailsService" class="PATH.TO.CustomUserDetailsService"/>
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="512"/>
</beans:bean>
<sec:authentication-manager>
<sec:authentication-provider user-service-ref="customUserDetailsService">
<sec:password-encoder ref="passwordEncoder">
<sec:salt-source user-property="salt"/>
</sec:password-encoder>
</sec:authentication-provider>
</sec:authentication-manager>
</beans:beans>
public class CustomUserDetails implements UserDetails {
private int userID;
private String username;
private String password;
private Collection<GrantedAuthority> authorities;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
private String salt;
public CustomUserDetails() {
}
public CustomUserDetails(int userID, Collection<GrantedAuthority> authorities, String username, String password, boolean accountNonExpired, boolean accountNonLocked, boolean credentialsNonExpired, boolean enabled, String salt) {
this.userID = userID;
this.authorities = authorities;
this.username = username;
this.password = password;
this.accountNonExpired = accountNonExpired;
this.accountNonLocked = accountNonLocked;
this.credentialsNonExpired = credentialsNonExpired;
this.enabled = enabled;
this.salt = salt;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return authorities;
}
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return accountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return accountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
@Override
public boolean isEnabled() {
return enabled;
}
public String getSalt() {
return salt;
}
public void setAccountNonExpired(boolean accountNonExpired) {
this.accountNonExpired = accountNonExpired;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
public void setAuthorities(Collection<GrantedAuthority> authorities) {
this.authorities = authorities;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
this.credentialsNonExpired = credentialsNonExpired;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
public void setSalt(String salt) {
this.salt = salt;
}
}
public class CustomUserDetailsService implements UserDetailsService {
private User_dao userDao;
@Autowired
public void setUserDao(User_dao userDao) {
this.userDao = userDao;
}
@Override
public CustomUserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
MyUser myUser = new MyUser();
myUser.setUsername(username);
try {
userDao.getUserByUsername(myUser);
} catch (Throwable e) {
}
if (myUser == null) {
throw new UsernameNotFoundException("Username not found", username);
} else {
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
authList.add(new GrantedAuthorityImpl(myUser.getUserRole().getAuthority()));
int userID = myUser.getUserID();
boolean accountNonExpired = true;
boolean accountNonLocked = myUser.isNonLocked();
boolean credentialsNonExpired = true;
boolean enabled = myUser.isEnabled();
String password = "";
String salt = "";
password = new String(myUser.getHash);
salt = new String(myUser.getSalt());
CustomUserDetails user = new CustomUserDetails(userID, authList, username, password, accountNonExpired, accountNonLocked, credentialsNonExpired, enabled, salt);
return user;
}
}
}
public byte[] generateSalt() throws NoSuchAlgorithmException {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[20];
random.nextBytes(salt);
return salt;
}
public byte[] generateHash(byte[] salt, String pass) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.update(salt);
byte[] hash = digest.digest(pass.getBytes());
return hash;
}
byte[] salt = generateSalt();
byte[] hash = generateHash(salt, password);
Which I then store in the db.
我也有同样的问题,但一直没有回答,所以希望这可以在将来节省一些时间:
Spring-Security默认情况下会在比较摘要之前添加大括号。我错过了,旋转了几个小时(哦)。
确保存储(或生成)用花括号括起来的salt值(例如,当Spring说“{salt}”时,它们的真正含义是“打开花括号+您的salt值+关闭花括号”。
问题内容: 我正在建立一个网站,并试图决定如何加密用户密码以将其存储在SQL数据库中。 我意识到使用简单的md5(password)是非常不安全的。我正在考虑使用sha512(password.salt),并且我一直在研究生成有用盐的最佳方法。我阅读了许多文章,指出盐应尽可能地随机以增加哈希值的熵,这似乎是个好主意。但: 您需要将随机盐与哈希一起存储 鉴于攻击者以某种方式可以访问您的哈希密码(并试
我记得读过一个方案,其中检查密码的过程是这样的: 给定数据库中的(哈希、盐)值, 用salt哈希密码以检查哈希, 使用旧哈希作为salt的哈希密码, 在数据库中存储(新哈希,也称为旧哈希) 我找不到原始来源无论如何,我不明白 > < li> 使用旧哈希作为salt的优势是什么(与使用随机salt相反), 这种方案的优点是什么(进一步使彩虹表攻击复杂化?),以及 如果有优势,如何使用PHPass应用
问题内容: 我正在尝试在Java中生成盐,以与用于安全密码存储的哈希算法配合使用。我正在使用以下代码创建随机盐: 这应该生成一个完全安全的,随机生成的盐,以用于我的哈希算法。但是,当我运行代码时,每次都会输出相同的盐…表示生成的盐根本不是随机的。 出于明显的安全性目的,每个用户都需要一个唯一的符号,但是如果我每次创建一个新帐户时都使用此代码,则每个用户都将具有相同的符号,这一开始就破坏了它的用途。
在Ubuntu 12.04上,我创建了几个用户和密码,然后立即用开膛手约翰破解这些密码。一个密码很强,但其他密码都在我的单词列表中。 约翰还在跑,但我已经在大约20分钟内破解了两个。 我读到的每一篇文章都在谈论盐是否为人所知。以此哈希为例: 盐是: 正当我是说,这不是一直都知道吗?所以盐除了防止使用彩虹桌外,真的没有任何作用,对吗? 此外,还有以下帖子: 要用多长时间的时间来暴力处理一个腌制的SH
我正在为Web应用程序制作登录系统。要将密码存储在数据库中,我正在使用sha256加密密码,如下所示: 在数据库中,我存储了用户、用户密码和用于散列和验证用户登录的salt。现在,我正在向用户发送包含您的密码的电子邮件,但是当用户收到电子邮件时,由于存储在sha256加密密码中,用户收到的是一个长字符串,而不是用户应该知道的密码。 我的问题是,我可以通过任何方法向您发送实际的用户密码和非密码加密,
问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe