【发布时间】:2012-08-15 15:13:06
【问题描述】:
我创建了一个自定义AuthenticationProvider 来执行自定义安全检查。我还创建了继承自AccountStatusException 的自定义异常,以通知用户状态问题,例如当用户在特定时间段内未验证其帐户时。我的UserDetails 也是自定义实现。
这是我执行的安全检查的代码。与案例无关的代码已被省略。
public class SsoAuthenticationProvider implements AuthenticationProvider {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String) authentication.getPrincipal();
User user = null;
if (username != null) {
user = getUserRepository().findByUserName(username);
if (user != null) {
if (user.getEnabled() != 0) {
if ((user.getUserDetail().getConfirmed() != 0)
|| ((new Date().getTime() - user.getUserDetail().getRequestDate().getTime()) / (1000 * 60 * 60 * 24)) <= getUnconfirmedDays()) {
if (getPasswordEncoder().isPasswordValid(user.getPassword(),
(String) authentication.getCredentials(), user)) {
user.authenticated = true;
user.getAuthorities();
}
} else {
throw new UserNotConfirmedAndTimeExceeded(
"User has not been cofirmed in the established time period");
}
} else {
throw new DisabledException("User is disabled");
}
} else {
throw new BadCredentialsException("User or password incorrect");
}
} else {
throw new AuthenticationCredentialsNotFoundException("No credentials found in context");
}
return user;
}
}
SsoAuthenticationProvider 检查:
- 用户名已注册(数据库中存在)
- 用户已确认他的电子邮件
- 如果用户尚未确认他的电子邮件,请检查他是否仍处于宽限期(这是我们给用户确认电子邮件的几天,同时让他们访问网站)
- 如果用户尚未确认电子邮件并且他不在宽限期内,则抛出安全异常以指示这些状态并拒绝身份验证
问题在于,并非所有这些异常都会在堆栈中向上抛出到控制器,因此似乎无法通知用户有关登录问题。
使用UserDetails 等isEnabled()(和类似的)方法是不可能的,因为我们不同用户帐户状态的语义完全不同。
这是使用自定义异常构建自定义安全性的正确方法吗?我应该实施其他方法来完成这项工作吗?
【问题讨论】:
-
这行得通,但我绝对不喜欢 if-else 链:D
标签: java spring-security