美文网首页
CAS内外网都能访问配置说明

CAS内外网都能访问配置说明

作者: BetterFuture | 来源:发表于2016-11-25 13:38 被阅读2049次

    由于项目需要,需要内外网都能同时访问,原本的不能符合要求,只能着手修改,以下是 修改步骤。我用的是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");
         }
     
     
    }
    

    4.新增工具类: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 block
                e.printStackTrace();
            }
            return map;
        }
    }
    

    5.所属的两个配置文件
    cas-service.properties文件:

    #cas服务端的内网和外网
    cas.inCasServer=http://10.206.20.52:8982/cas
    cas.outCasServer=http://218.6.169.98:18982/cas
    
    #客户端的内网和外网
    cas.inClient=http://10.206.20.52:8982/tickets
    cas.outClient=http://218.6.169.98:18982/tickets
    
    #服务端的内网和外网
    cas.inCasServerTicket=http://10.206.20.52:8982/cas
    cas.outCasServerTicket=http://218.6.169.98:18982/cas
    

    segment.properties文件:

    #网段
    segment_1 =10.0.0.0-10.255.255.255
    segment_2 =172.16.0.0-172.31.255.255
    segment_3 =192.168.0.0-192.168.255.255
    segment_4 =172.10.0.0-172.31.255.255
    

    6.做好以上工作开始修改源码,首先修改AuthenticationFilte ,添加静态属性
    public static final String CONST_CAS_GATEWAY = "const_cas_gateway";
    然后找到方法:doFilter 方法内容修改为:

    public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException
      {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        HttpSession session = request.getSession(false);
        String ticket = request.getParameter(getArtifactParameterName());
        Assertion assertion = session != null ? 
          (Assertion)session.getAttribute("_const_cas_assertion_") : null;
        boolean wasGatewayed = (session != null) && 
          (session.getAttribute("_const_cas_gateway_") != null);
        
        String isToLogout = request.getParameter("isToLogout");
        if ((CommonUtils.isBlank(ticket)) && (assertion == null) && (!wasGatewayed) && 
          (!"1".equals(isToLogout)))
        {
          this.logger.debug("noticket and no assertion found");
          if (this.gateway)
          {
            this.logger.debug("settinggateway attribute in session");
            request.getSession(true).setAttribute("_const_cas_gateway_", "yes");
          }
        //修改部分
          String serviceUrl = constructServiceUrl(request, response, 
            "auth");
          
          Map<String, String> config = CustomConfigUtil.getCustomConfig(
            request.getServletContext(), request);
          this.casServerLoginUrl = ((String)config.get("casServerTicketUrl")).toString();
          setCasServerLoginUrl(((String)config.get("casServerTicketUrl")).toString());
          String urlToRedirectTo = CommonUtils.constructRedirectUrl(
            this.casServerLoginUrl, getServiceParameterName(), 
            serviceUrl, this.renew, this.gateway);
          if (this.logger.isDebugEnabled()) {
            this.logger.debug("redirectingto \"" + urlToRedirectTo + "\"");
          }
          response.sendRedirect(urlToRedirectTo);
          return;
        }
        if (session != null)
        {
          this.logger.debug("removinggateway attribute from session");
          session.setAttribute("_const_cas_gateway_", null);
        }
        filterChain.doFilter(request, response);
      }
    

    7.修改后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”
    很多地方写的不是很好,配置文件那些有的都直接到里面固定了,有些还需要优化 不过总体来说 是可以实现了内网和外网的通用访问。

    具体项目和说明示例可下载:
    http://pan.baidu.com/s/1sklXCK1

    相关文章

      网友评论

          本文标题:CAS内外网都能访问配置说明

          本文链接:https://www.haomeiwen.com/subject/uqaipttx.html