標籤:
由於項目需要,需要內外網都能同時訪問,原本的不能符合要求,只能著手修改,以下是修改步驟。我用的是cas-client-core-3.3.3.jar的用戶端版本
1.獲得cas-client-core-3.3.3.jar的源碼。
2.新增工具類CustomConfigUtil,我把工具類放在org.jasig.cas.client.util下。
代碼為:
package org.jasig.cas.client.util;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;public class CustomConfigUtil {/** * @Description 擷取屬性檔案中的屬性資訊 * @return */public static Map<String, String> getCustomConfig(final ServletContext servletContext,final HttpServletRequest request) {Map<String, String> map = new HashMap<String, String>();Map<String, String> map2 = HttpConnectionUtil.getServiceUrlMap();//讀取設定檔Map<String, String> segmentMap = PropertiesUtil.readProperties(CustomConfigUtil.class.getResource("/").getPath() + "segment.properties");boolean falg = false;for (String key : segmentMap.keySet()) {//判斷是否屬於某個網段falg = HttpConnectionUtil.ipIsValid(segmentMap.get(key), request.getRemoteAddr());if(falg){break;}}// 判斷請求是從外網訪問還是從內網訪問if (falg) {//client用戶端地址map.put("client", map2.get("cas.inClient"));//cas伺服器位址map.put("casServerTicketUrl", map2.get("cas.inCasServer"));//cas伺服器位址map.put("casServerTicket", map2.get("cas.inCasServerTicket"));} else {//client用戶端地址map.put("client", map2.get("cas.outClient"));//cas伺服器位址map.put("casServerTicketUrl", map2.get("cas.outCasServer"));//cas伺服器位址boolean flag = HttpConnectionUtil.isConnection(map2.get("cas.outCasServerTicket"));if(flag){map.put("casServerTicket", map2.get("cas.outCasServerTicket"));}else{map.put("casServerTicket", map2.get("cas.inCasServerTicket"));}}return map;}}
3.新增工具類HttpConnectionUtil 代碼如下
package org.jasig.cas.client.util;import java.net.HttpURLConnection;import java.net.URL;import java.util.Map;public class HttpConnectionUtil {/** * 測試網路是否能串連通暢 * * @param serviceURL * @return */public static boolean isConnection(String serviceURL) {try {URL url = new URL(serviceURL);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(2000);// 2秒則逾時conn.setReadTimeout(2000);int state = conn.getResponseCode();if (state == 200) {return true;}} catch (Exception e) {return false;}return false;}public static boolean ipIsValid(String ipSection, String ip) { if (ipSection == null) throw new NullPointerException("IP段不可為空!"); if (ip == null) throw new NullPointerException("IP不可為空!"); ipSection = ipSection.trim(); ip = ip.trim(); final String REGX_IP = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; final String REGX_IPB = REGX_IP + "\\-" + REGX_IP; if (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP)) return false; int idx = ipSection.indexOf(‘-‘); String[] sips = ipSection.substring(0, idx).split("\\."); String[] sipe = ipSection.substring(idx + 1).split("\\."); String[] sipt = ip.split("\\."); long ips = 0L, ipe = 0L, ipt = 0L; for (int i = 0; i < 4; ++i) { ips = ips << 8 | Integer.parseInt(sips[i]); ipe = ipe << 8 | Integer.parseInt(sipe[i]); ipt = ipt << 8 | Integer.parseInt(sipt[i]); } if (ips > ipe) { long t = ips; ips = ipe; ipe = t; } return ips <= ipt && ipt <= ipe; }public static void main(String[] args) {if (ipIsValid("127.0.0.1-127.0.0.1", "127.0.0.1")) {System.out.println("ip屬於該網段");} else{System.out.println("ip不屬於該網段");}} /** * 擷取設定檔資訊 * * @return */ public static Map<String, String> getServiceUrlMap() { return PropertiesUtil.readProperties(HttpConnectionUtil.class .getResource("/").getPath() + "cas-service.properties"); }}
5.新增工具類:PropertiesUtil:
package org.jasig.cas.client.util;import java.io.FileInputStream;import java.io.IOException;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import java.util.Properties;public class PropertiesUtil {public static Map<String, String> readProperties(String path) {Map<String, String> map = new HashMap<String, String>();try {Properties props = new Properties();//System.out.println(path);props.load(new FileInputStream(path));Enumeration<?> enum1 = props.propertyNames();while(enum1.hasMoreElements()) { String strKey = (String) enum1.nextElement(); String strValue = props.getProperty(strKey); map.put(strKey, strValue);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return map;}}
6.所屬的兩個設定檔
cas-service.properties檔案:
#cas服務端的內網和外網cas.inCasServer=http://10.206.20.52:8982/cascas.outCasServer=http://218.6.169.98:18982/cas#用戶端的內網和外網cas.inClient=http://10.206.20.52:8982/ticketscas.outClient=http://218.6.169.98:18982/tickets#服務端的內網和外網cas.inCasServerTicket=http://10.206.20.52:8982/cascas.outCasServerTicket=http://218.6.169.98:18982/cas
segment.properties檔案:
#網段segment_1 =10.0.0.0-10.255.255.255segment_2 =172.16.0.0-172.31.255.255segment_3 =192.168.0.0-192.168.255.255segment_4 =172.10.0.0-172.31.255.255
7.做好以上工作開始修改源碼,首先修改AuthenticationFilte ,添加靜態屬性
public static final String CONST_CAS_GATEWAY = "_const_cas_gateway_";
然後找到方法:doFilter 方法內容修改為:
final HttpServletRequest request = (HttpServletRequest) servletRequest;final HttpServletResponse response = (HttpServletResponse) servletResponse;final HttpSession session = request.getSession(false);final String ticket = request.getParameter(getArtifactParameterName());final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;final boolean wasGatewayed = session != null&& session.getAttribute(CONST_CAS_GATEWAY) != null;// 判斷是否為登出的url參數中帶有isToLogout=1參數的url均認為是系統登出的urlString isToLogout = request.getParameter("isToLogout");if (CommonUtils.isBlank(ticket) && assertion == null && !wasGatewayed&& !("1".equals(isToLogout))) {logger.debug("noticket and no assertion found");if (this.gateway) {logger.debug("settinggateway attribute in session");request.getSession(true).setAttribute(CONST_CAS_GATEWAY, "yes");}final String serviceUrl = constructServiceUrl(request, response,"auth");// 從設定檔中取出cas伺服器的登陸地址Map<String, String> config = CustomConfigUtil.getCustomConfig(request.getServletContext(), request);this.casServerLoginUrl = config.get("authServerUrl").toString();final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(),serviceUrl, this.renew, this.gateway);if (logger.isDebugEnabled()) {logger.debug("redirectingto \"" + urlToRedirectTo + "\"");}response.sendRedirect(urlToRedirectTo);return;}if (session != null) {logger.debug("removinggateway attribute from session");session.setAttribute(CONST_CAS_GATEWAY, null);}filterChain.doFilter(request, response);
8.修改後constructServiceUrl報錯 因為之前該方法只有兩個參數 現在修改為3個 找到改方法的類AbstractCasFilter
源碼在113行那樣constructServiceUrl重載該方法:
protected final String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response,final String type) { //從設定檔中取出cas伺服器的登陸地址 Map<String,String> config = CustomConfigUtil.getCustomConfig(request.getServletContext(),request); if("auth".equals(type)){ this.serverName = config.get("client").toString(); this.service = config.get("client").toString(); }else if("validation".equals(type)){ this.serverName = config.get("casServerTicket").toString(); this.service = config.get("client").toString();}
注意 該方法調用的地方還有幾個 需要全部都修改為重載的方法 可以先不忙重載, 先在原方法修改 看到源碼報錯的地方修改後在做調整,其他地方調整後傳人蔘數為:“validation”
如此便實現了內網和外網的通用訪問。
CAS內外網都能訪問配置說明