我的问题类似于如何在 Spring 安全性中限制登录尝试?
问题是在遵循最近高票答案之后 https://stackoverflow.com/a/35294221/1278112
以下代码是我的方法。
@Component
public class AuthenticationEventListener {
@Autowired
private UserDetailsManager userDetailsManager;
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationEventListener.class);
Set<RequestLimitRule> rules = Collections.singleton(RequestLimitRule.of(10, TimeUnit.MINUTES, 3)); // 3 request per 10 minute, per key
RequestRateLimiter limiter = new InMemorySlidingWindowRequestRateLimiter(rules);
@EventListener
public void authenticationSuccess(AuthenticationSuccessEvent event) {
String username = (String) event.getAuthentication().getName();
if (!limiter.overLimitWhenIncremented(username)) {
limiter.resetLimit(username);
}
}
@EventListener
public void authenticationFailed(AuthenticationFailureBadCredentialsEvent event) {
String username = (String) event.getAuthentication().getPrincipal();
boolean reachLimit = limiter.overLimitWhenIncremented(username);
if (reachLimit) {
User user = (User) userDetailsManager.loadUserByUsername(username);
//User is security.core.userdetails.User
user = (User) User.builder().username(user.getUsername()).accountExpired(!user.isAccountNonExpired())
.accountLocked(true).disabled(!user.isEnabled()).password(user.getPassword())
.authorities(user.getAuthorities()).build();
userDetailsManager.updateUser(user);
}
}
}
它会抛出 UserNameNotFoundException
而不是 LockedException
,发现 InMemoryUserDetailsManager
默认@Autowired,假设它没有用户信息。
由于用户信息存储在数据库中,因此尝试使用 JdbcUserDetailsManager
替换 InMemoryUserDetailsManager
,但它允许在故障转移限制器后尝试登录。
在检查了JdbcUserDetailsManager的源代码后,我发现其中的updateUser()
不会跟踪AccountNonLock
属性。
@Ron Winch on Spring Security的答案:按名称注销,锁定或禁用用户
您还需要知道如何锁定帐户。Spring 安全性提供了一种支持锁定帐户的机制。
您可以使用 UserDetailsManager 实现来更新 UserDetails,以返回 false 表示 isAccountNonLocked。然后,Spring Security的DaoAuthenticationProvider将利用preAuthenticationChecks来确保帐户不会被锁定。
如果您编写了自己的 UserDetailsService,则内置的 UserDetailsManager 实现将不起作用,因此您需要更新您的用户模型,以便自定义 UserDetailsService 创建一个 UserDetailsService,该 UserDetailsService 返回 false 表示 isAccountNonLocked。
因此,使用自定义用户详细信息管理器
实现来更新用户详细信息
。它将更改记录数据库。但同样,当故障转移限制器时,它什么也不做。
搜索后,Spring Security 中的答案:LockedException 被抛出而不是 BadCredentialsException,为什么?指
默认预身份验证检查:检查锁定...
到达 spring 安全参考后发现有一个 DaoAuthenticationProvider
。
我是否必须以某种方式配置才能使其与自定义用户详细信息管理器
一起使用?
还是有其他更好的途径来解决它?
提前谢谢。
@Ron 绞盘说得很对
您可以使用 UserDetailsManager 实现来更新 UserDetails,以返回 false 表示 isAccountNonLocked。然后,Spring Security的DaoAuthenticationProvider将利用preAuthenticationChecks来确保帐户不会被锁定。
但是,InMemoryUserDetailsManager和JdbcUserDetailsManager
不适合我。
所以我实现了UserDetailsService
而不是UserDetailsManager
如果您编写了自己的 UserDetailsService,则内置的 UserDetailsManager 实现将不起作用,因此您需要更新您的用户模型,以便自定义 UserDetailsService 创建一个 UserDetailsService,该 UserDetailsService 返回 false 表示 isAccountNonLocked。
并通过 AuthenticationManagerBuilder 将其注入 AuthenticationManager
。
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(NoOpPasswordEncoder.getInstance());
....
}
UserDetailsServiceImpl的相关部分.java
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
....
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//the custom implemetation
}
}
我有一个烧瓶API,我使用烧瓶SQLAlChemy来处理SQLite数据库。我有一个存储日志条目的表,我想将最大行数限制为n。因为插入也是使用原始SQL从烧瓶之外的另一个脚本进行的,所以我创建了一个触发器来检查行数,如果行数高于n,则删除最旧的行数: 此触发器按预期工作,但我正在努力使用烧瓶-sqlalChemy设置它。如何设置触发器/执行原始SQL使用烧瓶sqlalChemy?SQL只需要在db
问题内容: 我想按用户ID显示数据库中的记录。这意味着工作人员必须输入工作人员ID和密码并提出新项目的请求,该请求将保存在数据库中。 该请求工作正常,但是在request.php页面之后,我想显示该工作人员在receive.php中订购的项目。我该怎么办?这是定义表的SQL: 这是receive.php的PHP代码: 我真的希望有人可以检查我的代码。提前致谢。 问题答案: 您可以通过设置会话来做到
问题内容: 我需要连续监视数据库行以检查更改(更新)。如果其他来源进行了某些更改或更新,则应在我的应用程序上触发该事件(我正在使用WCF)。有什么办法可以连续监听数据库行中的更改吗? 我可能拥有更多事件来监视同一表中的不同行。在性能方面有什么问题。我正在使用C#Web服务监视SQL Server后端。 问题答案: 不久前,我有一个非常相似的要求,我使用CLR SP将数据推送到消息队列中来解决了这个
问题内容: 在JavaScript中,删除使用bind()添加为事件侦听器的函数的最佳方法是什么? 例 我能想到的唯一方法是跟踪添加了bind的每个侦听器。 上面的示例使用此方法: 有没有更好的方法可以做到这一点? 问题答案: 尽管@machineghost所说的是正确的,但事件的添加和删除方式相同,但等式中缺少的部分是: 调用后会创建一个新的函数引用! 因此,要添加或删除它,请将引用分配给变量:
我正在尝试构建一个使用数据库的应用程序,允许用户以管理员或员工身份登录 管理员几乎没有选项: 添加新员工, 列出所有员工和 为选定员工添加待办事项 受雇者 登录时显示待办事项 我遇到的第一个问题是: 我应该为所有记录(员工)只创建一个表吗 第二个问题是,我不知道如何为成功登录的用户显示项目列表。如何访问登录用户的数据?
问题内容: 我有一个SQL Server 2008数据库和一个asp.net前端。 当用户当前正在编辑记录但不确定哪种是最好的方法时,我想实现一个锁定。 我的想法是为记录创建一列,并在用户拉出该记录时将其设置为true,这意味着所有其他用户都具有只读访问权限,直到第一个用户完成编辑为止。 但是,如果会话超时并且他/她从不保存/更新记录,该记录将保留为,表示其他人无法对其进行编辑,对吗? 如何实现某
当我尝试通过运行Laravel 4的网站发送电子邮件时,我会收到这个异常: 预期响应代码为250,但收到代码“535”,消息“535-5.7.8用户名和密码不被接受。有关详细信息,请访问535 5.7.8http://support.google.com/mail/bin/answer.py?answer=14257wd7sm12843789wjc。36-gsmtp“ 这是我的邮件配置: 我第一次
myadapter.java