gpt4 book ai didi

rest - 如何防止无限重试 - Apache Shiro RESTful 服务

转载 作者:行者123 更新时间:2023-11-28 23:16:04 24 4
gpt4 key购买 nike

目标
我正在使用 RESTEasy 框架设置 RESTful web 服务。为了安全起见,我使用 Apache Shiro。我希望我的 api 停止接受请求或使登录过多的人超时。

问题
每当我使用浏览器 (chrome) 访问某个 URL 时,我都可以尝试无限次登录。允许这样做似乎是一个非常糟糕的主意。作为一种措施,我已确保记住登录尝试次数,用户在 3 次后无法登录。但是,通过暴力攻击,您仍然可以阻止所有用户登录。我想要一个更通用的解决方案。

Shiro.ini

[main]
# We store users and passwords inside the realm.
myRealm = com.myproject.shiro.DatabaseRealm
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $cacheManager

[urls]
/api/version = anon
/api/** = authcBasic

数据库领域

public class DatabaseRealm extends AuthorizingRealm {

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// No clue what to do with this functin. I only use authentication and not authorization, so probably just nothing.
return null;
}

/**
* Check if the user inputted is valid. The user can login if holds:
* 1. Password is correct. (if not, nrOfLogonAttempts++)
* 2. LogonUser.nrOfLogonAttemps is less than 3
* 3. LogonUser.dateEndValid is null or >= today.
* @param authenticationToken Token with basic information.
* @return SimpleAuthenticationInfo
* @throws AuthenticationException Whenever the user cannot login.
*/
@SuppressWarnings("ConstantConditions")
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws UnknownAccountException, IncorrectCredentialsException, LockedAccountException, ExpiredCredentialsException {
// Connect with the database.
DbContext context = null;
try {
context = DbContextUtil.getContextFromTomcat();
// Lookup user in the database.
LogonUserMyDao logonUserMyDao = new LogonUserMyDao(context);
LogonuserPojo logonuserPojo = logonUserMyDao.fetchOneByUsername(((UsernamePasswordToken) authenticationToken).getUsername());
if (logonuserPojo == null) {
throw new UnknownAccountException("Could not find user.");
}

// Check password
String plainTextPassword = new String(((UsernamePasswordToken) authenticationToken).getPassword());
if (!BCryptUtil.checkPassword(plainTextPassword, logonuserPojo.getPassword())) {
// We will note this event.
logonuserPojo.setNroflogonattempts(logonuserPojo.getNroflogonattempts() + 1);
logonUserMyDao.update(logonuserPojo);
context.commit();
throw new IncorrectCredentialsException("Incorrect password.");
}

// Check nrOfLogonAttempts
if (logonuserPojo.getNroflogonattempts() >= 2) {
throw new LockedAccountException("Cannot login anymore.");
}

// Check date
if (logonuserPojo.getDateendvalid() != null && DateTimeUtil.isBeforeToday(logonuserPojo.getDateendvalid())) {
throw new ExpiredCredentialsException("Account is expired.");
}

// User is valid, so return some info.
return new SimpleAuthenticationInfo(logonuserPojo.getUsername(), plainTextPassword, getClass().getName());
} catch (SQLException e) {
MyLogger.logError("Could not connect to user database.", e);
throw new AuthenticationException("Could not connect to databse.");
} finally {
if (context != null) {
try {
context.getConnection().close();
} catch (SQLException e) {
MyLogger.logError("Could not close connection", e);
}
}
}
}
}

最佳答案

您是否正在寻找更通用的 DDOS 保护?根据您的应用程序的运行位置(例如 AWS Shield),有几个选项可供选择。

您还可以通过以下方式阻止连接到达您的数据库:https://github.com/iTransformers/ddos-servlet-filter (但是,这仍然需要在您的应用程序中处理请求)

在 Shiro 方面,计算你的尝试次数是个不错的主意,但你需要注意用户管理方面的事情(用户如何解锁,支持请求?等 30 分钟?)而不是记录失败,您可能只想记录/审核所有尝试(当然不包括实际密码)。无论选择调用支持还是 n 分钟窗口,这都可能有助于提供一些支持背景或简单查询。

关于rest - 如何防止无限重试 - Apache Shiro RESTful 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49199020/

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