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;
}
}
Aggregations