欢迎使用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
原创粉丝点击