You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
7.9 KiB

package com.fr.plugin.fg.auth.filter;
import com.fr.data.NetworkHelper;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.web.utils.WebUtils;
import edu.yale.its.tp.cas.client.ProxyTicketValidator;
import edu.yale.its.tp.cas.client.Util;
import edu.yale.its.tp.cas.client.filter.CASFilterRequestWrapper;
import org.xml.sax.SAXException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Properties;
import java.util.StringTokenizer;
public class CasYaleFilter extends AbstractGlobalRequestFilterProvider {
public static final String CAS_FILTER_USER = "edu.yale.its.tp.cas.client.filter.user";
public static String IGNORE_URL;
private String casLogin;
private String casValidate;
private String casAuthorizedProxy;
private String casServiceUrl;
private String casRenew;
private String casServerName;
private boolean wrapRequest;
private Properties properties = new Properties();
@Override
public String filterName() {
return "cas";
}
@Override
public String[] urlPatterns() {
return new String[]{ "/*"};
}
@Override
public void init(FilterConfig filterConfig) {
try {
properties.load(ResourceIOUtils.read("/resources/fgAuth.properties"));
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getLocalizedMessage(), e);
}
this.casLogin = properties.getProperty("loginUrl");
this.casValidate = properties.getProperty("validateUrl");
this.casServerName = properties.getProperty("serverName");
this.IGNORE_URL = properties.getProperty("ignoreUrl"); // 逗号分隔
FineLoggerFactory.getLogger().debug("IGNORE_URL: {}", IGNORE_URL);
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
try {
if (isIgnoreRequest(request)) {
filterChain.doFilter(request, response);
return;
}
if (this.wrapRequest) {
request = new CASFilterRequestWrapper((HttpServletRequest)request);
}
HttpSession var4 = ((HttpServletRequest)request).getSession();
if (var4 != null && var4.getAttribute("edu.yale.its.tp.cas.client.filter.user") != null) {
filterChain.doFilter((ServletRequest)request, response);
} else {
String var5 = ((ServletRequest)request).getParameter("ticket");
if (var5 != null && !var5.equals("")) {
String var6 = this.getAuthenticatedUser((HttpServletRequest)request);
if (var6 == null) {
throw new ServletException("Unexpected CAS authentication error");
} else {
if (var4 != null) {
var4.setAttribute("edu.yale.its.tp.cas.client.filter.user", var6);
}
filterChain.doFilter((ServletRequest)request, response);
}
} else if (this.casLogin == null) {
throw new ServletException("When CASFilter protects pages that do not receive a 'ticket' parameter, it needs a edu.yale.its.tp.cas.client.filter.loginUrl filter parameter");
} else {
((HttpServletResponse)response).sendRedirect(this.casLogin + "?service=" + this.getService((HttpServletRequest)request) + (this.casRenew != null && !this.casRenew.equals("") ? "&renew=" + this.casRenew : ""));
}
}
} catch (ServletException e) {
FineLoggerFactory.getLogger().error(e.getLocalizedMessage(), e);
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getLocalizedMessage(), e);
}
}
private String getAuthenticatedUser(HttpServletRequest request) throws ServletException {
ProxyTicketValidator var2 = null;
String var4;
try {
var2 = new ProxyTicketValidator();
var2.setCasValidateUrl(this.casValidate);
var2.setServiceTicket(request.getParameter("ticket"));
var2.setService(this.getService(request));
var2.setRenew(Boolean.valueOf(this.casRenew));
var2.validate();
if (!var2.isAuthenticationSuccesful()) {
throw new ServletException("CAS authentication error: " + var2.getErrorCode() + ": " + var2.getErrorMessage());
} else {
if (var2.getProxyList().size() != 0) {
if (this.casAuthorizedProxy == null) {
throw new ServletException("this page does not accept proxied tickets");
}
boolean var3 = false;
var4 = (String)var2.getProxyList().get(0);
StringTokenizer var5 = new StringTokenizer(this.casAuthorizedProxy);
while(var5.hasMoreTokens()) {
if (var4.equals(var5.nextToken())) {
var3 = true;
break;
}
}
if (!var3) {
throw new ServletException("unauthorized top-level proxy: '" + var2.getProxyList().get(0) + "'");
}
}
return var2.getUser();
}
} catch (SAXException var6) {
var4 = "";
if (var2 != null) {
var4 = var2.getResponse();
}
throw new ServletException(var6 + " " + var4);
} catch (ParserConfigurationException var7) {
throw new ServletException(var7);
} catch (IOException var8) {
throw new ServletException(var8);
}
}
private String getService(HttpServletRequest request) throws ServletException {
if (this.casServerName == null && this.casServiceUrl == null) {
throw new ServletException("need one of the following configuration parameters: edu.yale.its.tp.cas.client.filter.serviceUrl or edu.yale.its.tp.cas.client.filter.serverName");
} else {
return this.casServiceUrl != null ? URLEncoder.encode(this.casServiceUrl) : Util.getService(request, this.casServerName);
}
}
@Override
public void destroy() {
}
public static boolean isIgnoreRequest(HttpServletRequest request) {
if (request.getRequestURI().contains("remote") ||
isMobile(request) ||
StringUtils.isNotBlank(WebUtils.getHTTPRequestParameter(request, "format"))) {
return true;
}
String[] ignores = IGNORE_URL.split(",");
FineLoggerFactory.getLogger().info("isIgnoreRequest uri: {}", request.getRequestURI());
for (String ignore:ignores) {
if (request.getRequestURI().contains(ignore)) {
return true;
}
}
return false;
}
public static boolean isMobile(HttpServletRequest req) {
String[] mobileArray = {"iPhone", "iPad", "android", "windows phone", "xiaomi"};
String userAgent = req.getHeader("user-agent");
if (userAgent != null && userAgent.toUpperCase().contains("MOBILE")) {
for(String mobile : mobileArray) {
if(userAgent.toUpperCase().contains(mobile.toUpperCase())) {
return true;
}
}
}
return NetworkHelper.getDevice(req).isMobile();
}
}