欢迎使用CSDN-markdown编辑器
来源:互联网 发布:mysql怎么删除库 编辑:程序博客网 时间:2024/06/08 17:30
CAS限制密码输入错误次数
用户错误登录限制简而言之就是限制单个用户单位时间内登录系统的错误次数。当用户在单位时间内登录系统的次数达到上限,就对这个用户采取相应的措施。
对于单节点CAS情况下,用户登录限制有两个方法:一是按IP地址限制,另一个通过IP地址+用户名组合限制。 对于多节点CAS情况下,只能结Inspektr的审计功能来限制用户登录。
首先配置了限制用户登录的拦截器。当一个用户在单位时间内登录的错误次数达到设定的上限,则再次登录cas服务器,则直接会被拦截。则该用户只有等待,随着时间的推移用户错误登录的频率低于一个值时或者错误记录被系统清理之后便可登录。
CAS提供限制相关的类
AbstractThrottledSubmissionHandlerInterceptorAdapter
public final boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object o) throws Exception { // we only care about post because that's the only instance where we can get anything useful besides IP address. if (!"POST".equals(request.getMethod())) { return true; } if (exceedsThreshold(request)) { recordThrottle(request); request.setAttribute(WebUtils.CAS_ACCESS_DENIED_REASON, "screen.blocked.message"); response.sendError(HttpStatus.SC_FORBIDDEN, "Access Denied for user [" + request.getParameter(usernameParameter) + "] from IP Address [" + request.getRemoteAddr() + ']'); return false; } return true; } public final void postHandle(final HttpServletRequest request, final HttpServletResponse response,final Object o, final ModelAndView modelAndView) throws Exception { if (!"POST".equals(request.getMethod())) { return; } final RequestContext context = (RequestContext) request.getAttribute("flowRequestContext"); if (context == null || context.getCurrentEvent() == null) { return; } // User successfully authenticated if (SUCCESSFUL_AUTHENTICATION_EVENT.equals(context.getCurrentEvent().getId())) { return; } // User submitted invalid credentials, so we update the invalid login count recordSubmissionFailure(request); }
AbstractInMemoryThrottledSubmissionHandlerInterceptorAdapter
@Override protected final boolean exceedsThreshold(final HttpServletRequest request) { final Date last = this.ipMap.get(constructKey(request)); if (last == null) { return false; } return submissionRate(new Date(), last) > getThresholdRate(); } @Override protected final void recordSubmissionFailure(final HttpServletRequest request) { this.ipMap.put(constructKey(request), new Date()); } /** * This class relies on an external configuration to clean it up. It ignores the threshold data in the parent class. */ public final void decrementCounts() { final Set<Map.Entry<String, Date>> keys = this.ipMap.entrySet(); logger.debug("Decrementing counts for throttler. Starting key count: {}", keys.size()); final Date now = new Date(); for (final Iterator<Map.Entry<String, Date>> iter = keys.iterator(); iter.hasNext();) { final Map.Entry<String, Date> entry = iter.next(); if (submissionRate(now, entry.getValue()) < getThresholdRate()) { logger.trace("Removing entry for key {}", entry.getKey()); iter.remove(); } } logger.debug("Done decrementing count for throttler."); } /** * Schedule throttle job. */ @PostConstruct public void scheduleThrottleJob() { try { if (shouldScheduleCleanerJob()) { logger.info("Preparing to schedule throttle job"); final JobDetail job = JobBuilder.newJob(this.getClass()) .withIdentity(this.getClass().getSimpleName().concat(UUID.randomUUID().toString())) .build(); final Trigger trigger = TriggerBuilder.newTrigger() .withIdentity(this.getClass().getSimpleName().concat(UUID.randomUUID().toString())) .startAt(new Date(System.currentTimeMillis() + this.startDelay)) .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInMilliseconds(this.refreshInterval) .repeatForever()).build(); logger.debug("Scheduling {} job", this.getClass().getName()); scheduler.scheduleJob(job, trigger); logger.info("{} will clean tickets every {} seconds", this.getClass().getSimpleName(), TimeUnit.MILLISECONDS.toSeconds(this.refreshInterval)); } } catch (final Exception e){ logger.warn(e.getMessage(), e); } } @Override public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException { SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); try { logger.info("Beginning audit cleanup..."); decrementCounts(); } catch (final Exception e) { logger.error(e.getMessage(), e); } }
DispatcherServlet
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); mappedHandler.applyPostHandle(processedRequest, response, mv); }
可以看出,CAS提供的限制相关类,是利用SpringMVC拦截器完成。
0 0
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 入行IT类的第一篇...初学Java感想
- [机器学习笔记]Note13--异常检测
- curl模拟post请求
- 数据结构之线段树
- 正则表达简单入门知识
- 欢迎使用CSDN-markdown编辑器
- 使用JNI进行Java与C/C++语言混合编程(1)--在Java中调用C/C++本地库
- YUV与RGB格式转换
- 轮子
- EventBus使用详解(二)——EventBus使用进阶
- shiro框架简单配置信息
- Python(基本输入输出)
- LeetCode:357. Count Numbers with Unique Digits
- POJ 1611 The Suspects