gpt4 book ai didi

java - 在 Spring Security 中使用自定义异常

转载 作者:搜寻专家 更新时间:2023-10-31 19:56:59 25 4
gpt4 key购买 nike

我创建了一个自定义 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 检查:

  1. 用户名已注册(存在于数据库中)
  2. 用户已经确认了他的邮箱
  3. 如果用户尚未确认他的电子邮件,请检查他是否仍处于宽限期(这是我们在允许用户访问网站的同时给用户确认他们的电子邮件的几天)
  4. 如果用户没有确认电子邮件并且他不在宽限期内,则抛出安全异常以指示这些状态并拒绝身份验证

问题是并非所有这些异常都在堆栈中向上抛出到 Controller ,因此似乎不可能将登录问题通知用户。

使用 UserDetails 方法,如 isEnabled()(和类似方法)是不可能的,因为我们不同用户帐户状态的语义完全不同。

这是使用自定义异常构建自定义安全性的正确方法吗?我应该实现其他方法来完成这项工作吗?

最佳答案

为了结束之前提出的问题,让我解释一下我们做了什么。正如我对之前的回复所评论的那样,在 UserDetails 对象中使用提供的方法是不可行的,因为您无法使用给定的方法捕获所有登录失败语义。在我们的例子中,这些语义仍然非常有限,但在其他情况下,它可以随着时间的推移无限扩展以表达不同的用户情况。异常方法最终是最好的方法。最终代码如下所示

    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 BadCredentialsException("Password incorrect");
}
}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 does not exist");
}
}else{
throw new AuthenticationCredentialsNotFoundException("No credentials found in context");
}
return user;
}

所有异常都是 spring 安全异常堆栈的一部分。也就是说,那些自定义异常继承自某些现有异常。然后,在您的安全 Controller 中,您应该检查安全异常并按需要处理它们。例如重定向到不同的页面。

希望这对您有所帮助!

关于java - 在 Spring Security 中使用自定义异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12035133/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com