Search in sources :

Example 1 with Resource

use of j.app.permission.Resource in project JFramework by gugumall.

the class DomainLimit method doFilter.

/*
	 * (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
public void doFilter(ServletRequest _request, ServletResponse _response, FilterChain chain) throws IOException, ServletException {
    waitWhileLoading();
    HttpServletRequest request = (HttpServletRequest) _request;
    HttpServletResponse response = (HttpServletResponse) _response;
    String ip = JHttp.getRemoteIp(request);
    String currentUrl = SysUtil.getRequestURL(request, "sso");
    String requestURL = request.getRequestURL().toString();
    requestURL = requestURL.replaceFirst(":" + request.getRemotePort(), "");
    if (JUtilString.getTokens(JUtilString.getHost(requestURL), ".").length < 2) {
        log.log("ip " + ip + " 非法URL - " + requestURL, Logger.LEVEL_ERROR);
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }
    if (!requestURL.matches(JUtilString.RegExpHttpUrl)) {
        log.log("ip " + ip + " 非法URL - " + requestURL, Logger.LEVEL_ERROR);
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }
    try {
        HttpSession session = request.getSession(true);
        User user = SSOClient.getCurrentUser(session);
        long now = SysUtil.getNow();
        String url = request.getRequestURL().toString();
        String urlWithoutDomain = url.substring(url.indexOf("/", 10));
        String uri = request.getRequestURI();
        String domain = JUtilString.getHost(url);
        String userAgent = request.getHeader("User-Agent");
        if (userAgent == null)
            userAgent = "";
        String referer = request.getHeader("Referer");
        String method = request.getMethod();
        if (method == null)
            method = "POST";
        String contentType = request.getContentType();
        if (contentType == null)
            contentType = "";
        int contentLength = request.getContentLength();
        // ///////////////////////////////////////安全控制////////////////////////////////////
        if (!Onlines.pass(domain, urlWithoutDomain)) {
            // 域名限制
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
        if (black(ip)) {
            // 黑IP
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
        if (blackRegion(ip)) {
            // 黑地区
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
        boolean credible = credible(request);
        if (!credible) {
            // 被禁止的搜索引擎
            if (userAgent != null) {
                userAgent = userAgent.toLowerCase();
                for (int i = 0; i < forbiddenSpiders.length; i++) {
                    if (forbiddenSpiders[i].startsWith("EQUALS")) {
                        if (forbiddenSpiders[i].substring(6).equalsIgnoreCase(userAgent)) {
                            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                            return;
                        }
                    } else if (userAgent.indexOf(forbiddenSpiders[i]) > -1) {
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                        return;
                    }
                }
            }
            // 被禁止的搜索引擎  end
            // 每个ip会话数
            int sessionsOfIp = sessionsPerIp(ip);
            if (sessionsOfIp > maxSessionsPerIp) {
                if (handler != null) {
                    handler.onManySessionsOnIp(ip);
                }
                log.log("ip " + ip + " 上共有  " + sessionsOfIp + " 个会话,超出限制 " + maxSessionsPerIp, Logger.LEVEL_WARNING);
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
            }
            // 是否允许通过
            if (handler != null && !handler.canPass(session, request)) {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
            }
        }
        boolean ignore = false;
        if (ignoredIps != null && JUtilString.contain(ignoredIps, ip)) {
            ignore = true;
        }
        if (!ignore && Permission.hasValidPassport(request)) {
            ignore = true;
        }
        boolean ignoreUrl = false;
        if (!ignore && ignoredUrls != null) {
            for (int i = 0; i < ignoredUrls.length; i++) {
                if (JUtilString.match(uri, ignoredUrls[i], "*") > -1) {
                    ignore = true;
                    ignoreUrl = true;
                    break;
                }
            }
        }
        if (!ignoreUrl) {
            // 文件上传是否允许
            if (contentType.indexOf("boundary") > -1) {
                if (user == null) {
                    // 未登录
                    boolean allowed = false;
                    for (int i = 0; i < fileUploadAllowedUrls.length; i++) {
                        if (JUtilString.match(uri, fileUploadAllowedUrls[i], "*") > -1) {
                            allowed = true;
                            break;
                        }
                    }
                    if (!allowed) {
                        log.log("ip " + ip + " 未登录, 试图上传文件(" + uri + ") ,大小 " + contentLength + " ,已被禁止.", -1);
                        // response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                        // SysUtil.forward(request,response, Constants.RESPONSE_FILE_NOT_LOGIN);
                        SysUtil.outHttpResponse(response, "-login");
                        return;
                    }
                }
                if (contentLength < 0 || contentLength > maxUploadSize * 1024) {
                    log.log("ip " + ip + " 试图上传文件 (" + uri + "),大小 " + contentLength + " 超过 " + (maxUploadSize * 1024) + "(" + maxUploadSize + "K),已被禁止.", -1);
                    // response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    // SysUtil.forward(request,response, Constants.RESPONSE_FILE_MAX_UPLOAD_SIZE);
                    SysUtil.outHttpResponse(response, "-max-upload-size-" + maxUploadSize);
                    return;
                }
            } else if (user == null && "POST".equalsIgnoreCase(method) && contentLength > maxPostSize * 1024 && !Permission.hasValidPassport(request)) {
                log.log("ip " + ip + " 发起POST请求(" + uri + ") ,大小 " + contentLength + " 超过 " + (maxPostSize * 1024) + "(" + maxPostSize + "K),已被禁止.", -1);
                // response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                // SysUtil.forward(request,response, Constants.RESPONSE_FILE_MAX_POST_SIZE);
                SysUtil.outHttpResponse(response, "-max-post-size-" + maxPostSize);
                return;
            }
        }
        if (!credible && !ignoreUrl) {
            // 频繁访问
            RequestCount count = (RequestCount) counts.get(ip);
            if (count == null) {
                // log.log("开始监测ip "+ip+" 的频繁访问.", -1);
                count = new RequestCount();
                count.firstRequestTime = now;
                count.latestRequestTime = now;
                count.requests = 1;
                counts.put(ip, count);
            } else {
                if (now - count.latestRequestTime >= SSOConfig.getOnlineActiveTime() * 1000) {
                    // 状态为离线了,重新计时
                    count.firstRequestTime = now;
                    count.latestRequestTime = now;
                    count.requests = 1;
                } else {
                    count.latestRequestTime = now;
                    count.requests++;
                }
                counts.put(ip, count);
            }
            double minutes = Math.ceil((double) (count.latestRequestTime - count.firstRequestTime) / (double) 60000);
            if (minutes < 1)
                minutes = 1;
            double requestsPerMinute = Double.parseDouble(JUtilMath.formatPrint(count.requests / minutes, 3));
            if (requestsPerMinute > maxRequestsPerMinutes) {
                log.log("ip " + ip + " 共在线 " + minutes + " 分钟,请求  " + count.requests + " 次,平均每分钟 " + requestsPerMinute + " 次,超出限制 " + maxRequestsPerMinutes, Logger.LEVEL_WARNING);
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
            }
        // 频繁访问 END
        }
        // ///////////////////////////////////////安全控制 end////////////////////////////////////
        // ///////////////////////////////////////权限处理////////////////////////////////////
        Client client = SSOConfig.getSsoClientByIdOrUrl(SysConfig.getSysId());
        // log.log("requestURL:"+requestURL+",client:"+client,-1);
        if (client == null) {
            // 如果不是在sso.xml中指定的域名,禁止任何操作
            return;
        }
        // 设置session超时时间,单位秒
        if (SSOConfig.getSessionTimeout() > 0) {
            session.setMaxInactiveInterval(SSOConfig.getSessionTimeout());
        }
        // 持有通行证,不进行权限认证和SSO相关操作
        if (Permission.hasValidPassport(request)) {
            chain.doFilter(_request, _response);
            return;
        }
        String loginFrom = request.getParameter(Constants.SSO_LOGIN_FROM_SYS_ID);
        if (loginFrom != null) {
            String ssoPutLoginStatus = request.getParameter(Constants.SSO_PUT_LOGIN_STATUS);
            String globalSessionId = SysUtil.getHttpParameter(request, Constants.SSO_GLOBAL_SESSION_ID);
            // log.log("login from direct "+globalSessionId, -1);
            // String back=SysUtil.getHttpParameter(request,Constants.SSO_BACK_URL);
            String loginPage = SysUtil.getHttpParameter(request, Constants.SSO_LOGIN_PAGE);
            // }
            if (loginPage != null) {
                try {
                    loginPage = JUtilString.decodeURI(loginPage, SysConfig.sysEncoding);
                } catch (Exception e) {
                }
            } else {
                loginPage = client.getLoginPage();
            }
            if (!verifySsoLogin(client, request)) {
                SysUtil.redirect(request, response, loginPage);
                return;
            }
            LoginStatus loginStatus = SSOClient.findLoginStatusOfSessionId(globalSessionId);
            if (loginStatus == null) {
                // log.log("Login Status is not found.", -1);
                if ("true".equalsIgnoreCase(ssoPutLoginStatus)) {
                    SysUtil.redirect(request, response, SysUtil.getRequestURLBase(request) + Constants.SSO_GET_LOGIN_STATUS_RESULT + "?ok=0");
                } else {
                    SysUtil.redirect(request, response, loginPage);
                }
                return;
            } else {
                // 已经登录,加载用户信息
                // 加载用户信息
                user = User.loadUser(session, request, loginStatus.getUserId());
                if (user != null) {
                    // 加载用户信息成功
                    loginStatus.setSession(session);
                    // 确认登录
                    loginStatus.login();
                    loginStatus.setUpdateTime(SysUtil.getNow());
                    loginStatus.setLoginFromDomain(SysUtil.getHttpDomain(request));
                    loginStatus.setUserAgent(request.getHeader("User-Agent"));
                    SSOClient.refreshLoginStatus(loginStatus);
                    SSOClient.saveUserInformation(session, loginStatus, user);
                    if ("true".equalsIgnoreCase(ssoPutLoginStatus)) {
                        SysUtil.redirect(request, response, SysUtil.getRequestURLBase(request) + Constants.SSO_GET_LOGIN_STATUS_RESULT + "?ok=1");
                    } else {
                        SysUtil.redirect(request, response, currentUrl);
                    }
                    return;
                } else {
                    log.log("已经登录,但加载用户信息失败 - " + globalSessionId + "," + loginStatus.getUserId() + "," + loginStatus.getUserIp(), -1);
                    if ("true".equalsIgnoreCase(ssoPutLoginStatus)) {
                        SysUtil.redirect(request, response, SysUtil.getRequestURLBase(request) + Constants.SSO_GET_LOGIN_STATUS_RESULT + "?ok=0");
                    } else {
                        SysUtil.redirect(request, response, loginPage);
                    }
                    return;
                }
            }
        }
        // 保存在session中的单点登录信息
        LoginStatus loginStatus = SSOClient.getLoginStatus(session);
        // 更新用户最近活动时间
        if (loginStatus != null) {
            loginStatus.update();
            SSOClient.setLoginStatus(session, loginStatus);
            SSOClient.updater.addKey(loginStatus);
        }
        if (user != null) {
            SSOClient.setCurrentUser(session, user);
        }
        // 查询登录状态
        String ssoGetLoginStatus = request.getParameter(Constants.SSO_GET_LOGIN_STATUS);
        if ("true".equalsIgnoreCase(ssoGetLoginStatus)) {
            if (user != null && loginStatus != null && loginStatus.getStat() == LoginStatus.STAT_VISITED) {
                SysUtil.redirect(request, response, Constants.SSO_GET_LOGIN_STATUS_RESULT + "?ok=1");
                return;
            } else {
                String redirect = SSOConfig.getSsoServer() + "ssoserver" + Handlers.getActionPathPattern();
                redirect += "?" + Handlers.getHandler("/ssoserver").getRequestBy() + "=ssoquery";
                redirect += "&" + Constants.SSO_CLIENT + "=" + client.getUrlDefault();
                if (currentUrl.indexOf("?") < 0) {
                    redirect += "&" + Constants.SSO_BACK_URL + "=" + JUtilString.encodeURI(currentUrl + "?" + Constants.SSO_PUT_LOGIN_STATUS + "=true", SysConfig.sysEncoding);
                    redirect += "&" + Constants.SSO_LOGIN_PAGE + "=" + JUtilString.encodeURI(SysUtil.getRequestURLBase(request) + Constants.SSO_GET_LOGIN_STATUS_RESULT + "?ok=0", SysConfig.sysEncoding);
                } else {
                    redirect += "&" + Constants.SSO_BACK_URL + "=" + JUtilString.encodeURI(currentUrl + "&" + Constants.SSO_PUT_LOGIN_STATUS + "=true", SysConfig.sysEncoding);
                    redirect += "&" + Constants.SSO_LOGIN_PAGE + "=" + JUtilString.encodeURI(SysUtil.getRequestURLBase(request) + Constants.SSO_GET_LOGIN_STATUS_RESULT + "?ok=0", SysConfig.sysEncoding);
                }
                SysUtil.redirect(request, response, redirect);
                return;
            }
        }
        // 查询登录状态 end
        // 是否是需要认证的资源
        Resource res = Permission.permission(request, user);
        // 如果需要认证
        if (res != null) {
            if (loginStatus == null || loginStatus.getStat() == LoginStatus.STAT_CREATE || user == null) {
                // 如果未登录
                String redirect = SSOConfig.getSsoServer() + "ssoserver" + Handlers.getActionPathPattern();
                redirect += "?" + Handlers.getHandler("/ssoserver").getRequestBy() + "=ssoquery";
                redirect += "&" + Constants.SSO_CLIENT + "=" + client.getUrlDefault();
                redirect += "&" + Constants.SSO_BACK_URL + "=" + JUtilString.encodeURI(currentUrl, SysConfig.sysEncoding);
                if (res != null && res.getLoginPage() != null) {
                    redirect += "&" + Constants.SSO_LOGIN_PAGE + "=" + JUtilString.encodeURI(res.getLoginPage(), SysConfig.sysEncoding);
                }
                SysUtil.redirect(request, response, redirect);
                return;
            } else {
                // 否则是权限不够
                String noPermissionPage = "";
                if (res.getNoPermissionPage() != null) {
                    noPermissionPage = res.getNoPermissionPage();
                } else {
                    noPermissionPage = Permission.getNoPermissionPage();
                }
                if (noPermissionPage.indexOf("?") > 0) {
                    noPermissionPage += "&" + Constants.SSO_BACK_URL + "=" + URLEncoder.encode(currentUrl, SysConfig.sysEncoding);
                } else {
                    noPermissionPage += "?" + Constants.SSO_BACK_URL + "=" + URLEncoder.encode(currentUrl, SysConfig.sysEncoding);
                }
                if (currentUrl.indexOf(Constants.SSO_INFO_GETTER) < 0 && currentUrl.indexOf(Constants.SSO_INFO_GETTER_LOGIN) < 0) {
                    log.log("试图访问没有权限的资源:" + res + "," + user.getUserId() + "," + currentUrl, Logger.LEVEL_FATAL);
                    SysUtil.redirect(request, response, noPermissionPage);
                } else {
                    SysUtil.outHttpResponse(response, "<script>try{if(top.onSsoInfoGot) top.onSsoInfoGot();}catch(e){}</script>");
                }
                return;
            }
        }
        // ///////////////////////////////////////权限处理  end////////////////////////////////////
        // ///////////////////////////////////////兼容性处理////////////////////////////////////
        String compatibleResource = SysConfig.getCssCompatibleResource(uri, SysConfig.getUserAgentType(request));
        // log.log("uri:"+uri+",SysConfig.getUserAgentType(request):"+SysConfig.getUserAgentType(request)+","+compatibleResource, -1);
        if (compatibleResource != null) {
            SysUtil.forwardI18N(request, response, compatibleResource);
            return;
        }
        // ///////////////////////////////////////在线用户处理////////////////////////////////////
        if (!ignore) {
            if ("POST".equalsIgnoreCase(method)) {
                uri = method + " " + contentType + " " + contentLength + " " + SysUtil.getRequestURL(request);
            } else {
                uri = method + " " + contentType + " " + SysUtil.getRequestURL(request);
            }
            Online online = find(session);
            if (online != null) {
                if (online.getUser() == null && user != null) {
                    LoginStatus status = (LoginStatus) session.getAttribute(Constants.SSO_STAT_CLIENT);
                    if (status != null) {
                        online.setGlobalSessionId(status.getGlobalSessionId());
                    }
                    online.setUid(user.getUserId());
                    online.setUname(user.getUserName());
                    online.setUser(user);
                    if (handler != null) {
                        handler.onLogin(online, user, session, request);
                    }
                } else if (online.getUser() != null && user == null) {
                    online.removeUser();
                    online.setUid(null);
                    online.setUname(null);
                    if (handler != null) {
                        handler.onLogout(online, user, session, request);
                    }
                }
                online.setCurrentIp(ip);
                online.setCurrentSysId(SysConfig.getSysId());
                online.setCurrentMachineId(SysConfig.getMachineID());
                online.setCurrentSessionId(session.getId());
                online.setCurrentUrl(uri);
                online.update();
                update(online);
            } else {
                online = new Online();
                if (handler != null) {
                    handler.onInit(online, user, session, request);
                }
                if (user != null) {
                    LoginStatus status = (LoginStatus) session.getAttribute(Constants.SSO_STAT_CLIENT);
                    if (status != null) {
                        online.setGlobalSessionId(status.getGlobalSessionId());
                    }
                    online.setUid(user.getUserId());
                    online.setUname(user.getUserName());
                    online.setUser(user);
                    if (handler != null) {
                        handler.onLogin(online, user, session, request);
                    }
                }
                if (referer == null)
                    referer = "";
                if (userAgent == null)
                    userAgent = "";
                online.setCurrentIp(ip);
                online.setCurrentSysId(SysConfig.getSysId());
                online.setCurrentMachineId(SysConfig.getMachineID());
                online.setCurrentSessionId(session.getId());
                online.setCurrentReferer(referer);
                online.setCurrentUserAgent(userAgent);
                online.setCurrentUrl(uri);
                update(online);
            }
            if (handler != null) {
                handler.doFilter(_request, _response, chain);
            } else {
                chain.doFilter(_request, _response);
            }
        } else {
            if (handler != null) {
                handler.doFilter(_request, _response, chain);
            } else {
                chain.doFilter(_request, _response);
            }
        }
    // ///////////////////////////////////////在线用户处理 end////////////////////////////////////
    } catch (Exception e) {
        log.log("errors on url \r\n" + requestURL + "\r\n" + currentUrl, Logger.LEVEL_ERROR);
        log.log(e, Logger.LEVEL_ERROR);
        SysUtil.redirect(request, response, SysConfig.errorPage);
        return;
    }
}
Also used : User(j.app.sso.User) HttpSession(javax.servlet.http.HttpSession) Resource(j.app.permission.Resource) HttpServletResponse(javax.servlet.http.HttpServletResponse) JUtilString(j.util.JUtilString) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) HttpServletRequest(javax.servlet.http.HttpServletRequest) LoginStatus(j.app.sso.LoginStatus) SSOClient(j.app.sso.SSOClient) Client(j.app.sso.Client)

Aggregations

Resource (j.app.permission.Resource)1 Client (j.app.sso.Client)1 LoginStatus (j.app.sso.LoginStatus)1 SSOClient (j.app.sso.SSOClient)1 User (j.app.sso.User)1 JUtilString (j.util.JUtilString)1 IOException (java.io.IOException)1 ServletException (javax.servlet.ServletException)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 HttpSession (javax.servlet.http.HttpSession)1