All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alogic.cas.client.CasAuthz Maven / Gradle / Ivy

package com.alogic.cas.client;

import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.anysoft.webloader.HttpClientTool;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.alogic.auth.Session;
import com.alogic.auth.SessionManager;
import com.alogic.auth.SessionManagerFactory;
import com.alogic.cas.CasConstants;
import com.alogic.cas.client.loader.FromInner;
import com.alogic.load.Loader;
import com.anysoft.util.BaseException;
import com.anysoft.util.Configurable;
import com.anysoft.util.Factory;
import com.anysoft.util.IOTools;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.Settings;
import com.anysoft.util.XMLConfigurable;
import com.anysoft.util.XmlElementProperties;
import com.anysoft.util.XmlTools;
import com.anysoft.util.resource.ResourceFactory;
import com.anysoft.webloader.FilterConfigProperties;

/**
 * 处理CAS的过滤器
 * @author yyduan
 * @since 1.6.11.60 [20180912 duanyy]
 * 
 * @version 1.6.11.61 [20180913 duanyy] 
* - 部分字符串采用常量表达
* * @version 1.6.12.8 [20181121 duanyy]
* - 优化cas客户端处理
*/ public class CasAuthz implements Filter,CasConstants,XMLConfigurable,Configurable{ /** * a logger of slf4j */ protected final static Logger LOG = LoggerFactory.getLogger(CasAuthz.class); /** * 缺省配置文件 */ protected static final String DEFAULT = "java:///conf/alogic.cas.client.xml#App"; /** * 退出登录的请求参数名 */ protected String arguLogout = CasConstants.ARGU_LOGOUT_REQUEST; /** * 缺省的服务id */ protected String dftServerId = "default"; /** * command的前缀 */ protected String cmdPrefix = ""; /** * 内部跳转URL的参数 */ protected String returnURL = CasConstants.ARGU_RETURNURL; /** * 缺省的主页URL */ protected String mainPage = ""; protected Loader loader = null; protected String sessionGroup = "$cas-client"; /** * 正则表达式从CasServer回调路径中匹配from和sessionId */ protected Pattern pattern = Pattern.compile("/cas/(?[\\w|\\-]+)/(?[\\w|\\-]+)"); protected HttpClientTool clientTool = null; @Override public void configure(Properties props) { dftServerId = PropertiesConstants.getString(props, "dftServer",dftServerId); cmdPrefix = PropertiesConstants.getString(props, "cmdPrefix",cmdPrefix); returnURL = PropertiesConstants.getString(props,"auth.para.url",returnURL); mainPage = PropertiesConstants.getString(props,"auth.page.main",mainPage); arguLogout = PropertiesConstants.getString(props, "cas.para.logout",arguLogout); sessionGroup = PropertiesConstants.getString(props, "cas.client.group",sessionGroup); clientTool = Settings.getToolkit(HttpClientTool.class); } @Override public void configure(Element e, Properties p) { Properties props = new XmlElementProperties(e,p); Element elem = XmlTools.getFirstElementByPath(e, "servers"); if (elem != null){ try { Factory> f = new Factory>(); loader = f.newInstance(elem, props, "loader",FromInner.class.getName()); }catch (Exception ex){ LOG.error("Can not create loader with " + XmlTools.node2String(elem)); LOG.error(ExceptionUtils.getStackTrace(ex)); } } configure(props); } @Override public void init(FilterConfig filterConfig) throws ServletException { FilterConfigProperties props = new FilterConfigProperties(filterConfig); String master = PropertiesConstants.getString(props, "cas.client.master", DEFAULT); String secondary = PropertiesConstants.getString(props, "cas.client.secondary", DEFAULT); ResourceFactory rf = Settings.getResourceFactory(); InputStream in = null; try { in = rf.load(master, secondary, null); Document doc = XmlTools.loadFromInputStream(in); if (doc != null){ configure(doc.getDocumentElement(), props); } }catch (Exception ex){ LOG.error("Can not init gateway with file : " + master); }finally{ IOTools.close(in); } } @Override public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { HttpServletRequest httpReq = (HttpServletRequest)request; HttpServletResponse httpResp = (HttpServletResponse)response; SessionManager sm = SessionManagerFactory.getDefault(); Session session = sm.getSession(httpReq,httpResp,true); String cmd = getCommand(httpReq.getContextPath(),httpReq.getRequestURI()); if (StringUtils.isNotEmpty(cmd)){ if (cmd.startsWith("/cas")){ //由cas服务器回调 Matcher matcher = pattern.matcher(cmd); if (matcher.find()){ String serverId = matcher.group("from"); CasServer server = this.getCasServer(serverId); if (server != null){ String logoutRequest = this.getParameter(httpReq,arguLogout, ""); if (StringUtils.isNotEmpty(logoutRequest)){ String sessionId = matcher.group("sessionId"); try { server.doLogoutCallback(httpReq,httpResp,sm,session,sessionId); }catch (BaseException ex){ clientTool.sendError(httpResp,E404,String.format("%s:%s",ex.getCode(),ex.getMessage())); } }else{ try { server.doValidate(httpReq,httpResp,sm,session); //验证通过后,重定向到指定的地址 String redirect = session.hGet(sessionGroup,returnURL,mainPage); if (StringUtils.isNotEmpty(redirect)){ session.hDel(sessionGroup, returnURL); clientTool.sendRedirect(httpResp,redirect); } }catch (BaseException ex){ clientTool.sendError(httpResp,E404,String.format("%s:%s",ex.getCode(),ex.getMessage())); } } return ; }else{ clientTool.sendError(httpResp,E404,"core.e1000:Unsupported cas server,id=" + serverId); return; } }else{ clientTool.sendError(httpResp,E404,"core.e1000:Unsupported command:" + cmd); return ; } } if (cmd.startsWith("/login")){ //由本地地址调用,跳转登录 String serverId = getParameter(httpReq, CasConstants.ARGU_FROM, dftServerId); CasServer server = getCasServer(serverId); if (server == null){ clientTool.sendError(httpResp,E404,"core.e1000:Unsupported cas server,id=" + serverId); return ; } //将请求页面保存在Session中,准备验证之后跳转 String redirectURL = getParameter(httpReq, returnURL, ""); if (StringUtils.isNotEmpty(redirectURL)){ session.hSet(sessionGroup, returnURL, redirectURL, true); } session.hSet(sessionGroup, CasConstants.ARGU_FROM, serverId, true); try { server.doLogin(httpReq,httpResp,sm,session); }catch (BaseException ex){ clientTool.sendError(httpResp,E404,String.format("%s:%s",ex.getCode(),ex.getMessage())); } return ; } if (cmd.startsWith("/logout")){ //由本地地址调用,跳转登出 String serverId = session.hGet(sessionGroup, CasConstants.ARGU_FROM, dftServerId); CasServer server = getCasServer(serverId); if (server == null){ clientTool.sendError(httpResp,E404,"core.e1000:Unsupported cas server,id=" + serverId); return ; } try { server.doLogout(httpReq,httpResp,sm,session); }catch (BaseException ex){ clientTool.sendError(httpResp,E404,String.format("%s:%s",ex.getCode(),ex.getMessage())); } return ; } } if (session.isLoggedIn()){ //已经登录 chain.doFilter(request, response); return ; }else{ String serverId = getParameter(httpReq, CasConstants.ARGU_FROM, dftServerId); CasServer server = getCasServer(serverId); if (server == null){ clientTool.sendError(httpResp,E404,"core.e1000:Unsupported cas server,id=" + serverId); return ; } //将请求页面保存在Session中,准备验证之后跳转 String requestUrl = httpReq.getRequestURI(); String query = httpReq.getQueryString(); if (StringUtils.isNotEmpty(query)){ requestUrl = requestUrl + "?" + query; } session.hSet(sessionGroup, returnURL, requestUrl, true); session.hSet(sessionGroup, CasConstants.ARGU_FROM, serverId, true); try { server.doLogin(httpReq,httpResp,sm,session); }catch (BaseException ex){ clientTool.sendError(httpResp,E404,String.format("%s:%s",ex.getCode(),ex.getMessage())); } return ; } } @Override public void destroy() { } protected CasServer getCasServer(String id){ return loader.load(id, true); } /** * 通过URI计算出当前的command * @param uri URI * @return cmd */ protected String getCommand(String contextPath,String uri){ String prefix = contextPath + this.cmdPrefix; if (uri.startsWith(prefix)){ return uri.substring(prefix.length()); }else{ return ""; } } /** * 从Request中获取指定的参数 * @param request HttpServletRequest * @param id 参数id * @param dftValue 缺省值,当参数不存在时,返回 * @return 参数值,如果参数不存在,返回缺省值 */ protected String getParameter(HttpServletRequest request,String id,String dftValue){ String value = request.getParameter(id); return StringUtils.isEmpty(value)?dftValue:value; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy