一般项目绝大数都是部署于某一个网络,要吗在内网,要不在外网,部署在内网的目前很多都通过VPN进行内网的访问。但对于一些项目是部署在内网,然后通过网络路由映射方式进行外网的访问,一般情况如果是通过自己开发的登陆此问题不需要进行任何改动,而当您使用了通用的CAS统一认证服务时,由于WEB应用工程中web.xml配置的CAS地址是固定的,而不是一个动态的地址,当将WEB应用服务器例如TOMCAT端口映射外网后,在访问应用时会自动根据在web.xml文件中去配置对应的CAS地址,而此时的地址只能是内网使用,外网自然无法找到,则无法登陆,而由于项目的本身需要,必须要同时内外网都能访问,而应用已使用了CAS再来变更带来一些不便,同时CAS统一认证方面安全性还是较为有优势的,根据这一情况,前期进行了大量的咨询,都没能找得很好的解决办法,对于公司内部也无人能够解决,后通过百度搜索到了大量信息,并进行了测试,发现很多都无法满足自己的需要,后在无意中发现CNBlogs的一位作者名为BetterFuture的在自己博文中对CAS内外网功能的一个介绍,但由于没有进行全部的解说和一些代码的问题,并未能成功解决,后联系上了作者,并在其指导下完成自己的项目内网外功能,在此本人根据自己项目的情况进行了一次总结,以便于帮助更多的人;本案例以CAS-Client-3.2.1为例进行说明,对应的服务端为CAS-Server-3.5.2,目前客户端最新的为CAS-Client-3.3.3,对应CAS-Server-4.0以上,其不同版本源码虽有所改变,但此方法仍适用,可以直接用于CAS-Client-3.3.3版本。

第一步,首先要先下载cas-client-3.2.1-release.zip源文件,使用压缩软件打开,其中cas-client-core即为cas-client-core-3.2.1.jar的源代码,其下载地址为:http://developer.jasig.org/cas-clients/

第二步,将解压的cas-client-core目录导入到Eclipse或MyEclipse工程中,建立JavaProject,生成.project和.classpath文件,即可开始源代码的修改工作,目前这些源代码工程都是使用Maven来构建的,关于Maven不在本文范畴故而不再赘述!

第三步,修改源代码,新增工具类,以实现内外网的访问,当完成上述导入后,在Eclipse或MyEclipse中的目录结构应如下:

第四步,在org.jasig.cas.client.util下继续新增工具类PropertiesUtil代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

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();

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) {

e.printStackTrace();

}

return map;

}

}

第五步,在org.jasig.cas.client.util下继续新增工具类HttpConnectionUtil代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

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");

}

第六步,在org.jasig.cas.client.util下继续新增工具类CustomConfigUtil,代码为:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

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;

}

}

第七步,完成上述源代码的增加工具类后,开始修改CAS中的源代码了,首先修改AuthenticationFilte ,添加静态属性:

public static final String CONST_CAS_GATEWAY = "_const_cas_gateway_";

然后找到方法:doFilter方法内容修改为:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

public final void doFilter(final ServletRequest servletRequest,final ServletResponse servletResponse,final FilterChain filterChain)throws IOException, ServletException {

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;

boolean wasGatewayed = (session !=null) && (session.getAttribute(CONST_CAS_GATEWAY) !=null);

/**以下部分为主要修改内容,具体可参照进行修改**/

if ((CommonUtils.isBlank(ticket)) && (assertion ==null) && (!wasGatewayed)){

this.log.debug("noticket and no assertion found");

if (this.gateway){

this.log.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.log.isDebugEnabled()){

this.log.debug("redirectingto \"" + urlToRedirectTo +"\"");

}

final String modifiedServiceUrl;

log.debug("no ticket and no assertion found");

if (this.gateway) {

log.debug("setting gateway attribute in session");

modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);

} else {

modifiedServiceUrl = serviceUrl;

}

if (log.isDebugEnabled()){

log.debug("Constructed service url: " + modifiedServiceUrl);

}

response.sendRedirect(urlToRedirectTo);

return;

}

if (session !=null){

this.log.debug("removinggateway attribute from session");

session.setAttribute(CONST_CAS_GATEWAY,null);

}

filterChain.doFilter(request, response);

}

第八步,由于修改了constructServiceUrl这个方法,增加了一个参数,由原来该方法只有两个参数 现在修改为3个,需要找到该方法的类AbstractCasFilter(源代码的第 113或114行中的constructServiceUrl方法)进行修改重载该方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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();

}

return CommonUtils.constructServiceUrl(request, response,this.service,this.serverName,this.artifactParameterName,this.encodeServiceUrl);

}

第九步,由于该方法在其他几处也有调用,故而需要对其他调用的地方进行一一修改,但其他调用处最后Type的参数都统一修改成“validation”,“auth”仅上述AuthenticationFilte方法中的doFilter中使用,具体涉及到的类分别为:AbstractTicketValidationFilter中doFilter方法第169和184行constructServiceUrl方法的调用,增加“validation”参数即可,同时测试类CasFilterTests中也需要进行修改,参数同样为“validation”,具体代码如下:

constructServiceUrl(request, response,"validation")

到此已完成了CAS-Client-core源代码的修改.

第十步,完成上述源代码的增加与修改后,进行编译打成cas-client-core- 3.2.1.jar包,分别放置于cas工程以及调用cas的其他WEB应用工程中,同时需要在调用cas的WEB应用工程中增加两个配置文件(放置于web-inf/classes目录下),分别为: cas-service.properties与segment.properties。

1、cas-service.properties配置文件内容如下:

#cas服务端的内网和外网

cas.inCasServer=http://内网ip地址/cas

cas.outCasServer=http://外网ip地址/cas

#调用cas的其他WEB应用的内网和外网

cas.inClient=http://内网ip地址/tickets

cas.outClient=http://外网ip地址/tickets

#cas服务端的内网和外网(casTicket)

cas.inCasServerTicket=http://内网ip地址/cas

cas.outCasServerTicket=http://外网ip地址/cas

2、segment.properties配置文件内容如下:

#网段

segment_1 =内网网段区间1

segment_2 =内网网段区间2

segment_3 =内网网段区间3

segment_4 =内网网段区间4

注:此处网段只需要配置内网的限制IP,也就是出现在此配置文件中的内网IP才可以访问,外网无须配置;另WEB.xml配置的cas服务地址将不再有效,处于失效状态,而是通过这两个配置文件进行读取,但web.xml配置的信息依然需要保留。

CAS 3.2.1内外网映射问题的解决办法相关推荐

  1. docker网络问题解决办法“大全”:关于宿主机访问不了docker容器中web服务,或者容器内访问不了外网的问题的解决办法

    docker网络问题解决办法"大全":关于宿主机访问不了docker容器中web服务,或者容器内访问不了外网的问题的解决办法 参考文章: (1)docker网络问题解决办法&quo ...

  2. mbp网速很慢_mac网速慢的解决办法_mac上网速度极其慢如何处理-win7之家

    由于各种品牌电脑的不断涌现,有的用户开始使用上了mac电脑,这是不同于微软系统电脑的存在,因此操作过程中难免会有一些不懂的情况,例如有用户的mac电脑运行起来网速总是特别的慢,那么mac上网速度极其慢 ...

  3. Mac遇到浏览器能上网,大部分软件无法上网,恢复后共享网络给手机又上不了网的情况及解决办法

    Mac遇到浏览器能上网,大部分软件无法上网,恢复后共享网络给手机上不了网的情况及解决办法 一.问题描述: ​ 某一天在用腾讯QQ的时候,突然无法收到别人发的图片(一直显示重新加载),自己的表情包也发不 ...

  4. 百度网盘下载慢解决办法,最新.浏览器下载速度突破方法

    百度网盘下载慢解决办法,最新.浏览器下载速度突破方法 参考文章: (1)百度网盘下载慢解决办法,最新.浏览器下载速度突破方法 (2)https://www.cnblogs.com/MyOceansWe ...

  5. 断网安装是什么意思_ARP攻击是什么意思 受到ARP断网攻击的详细解决办法图解...

    在局域网中尤其是公司或者网络服务器所在的局域网,经常容易遭受到一些ARP断网攻击.另外一些电脑用户的电脑也时候会遭受APR攻击.很多电脑爱好者朋友都不知道ARP攻击是什么意思?以下小编为大家简单介绍下 ...

  6. 虚拟机ping主机和外网ping不通的解决办法

    配置拷贝的centos的虚拟机[详细版] 由于自己虚拟机配置的不完全,部分功能实现不出来,所以拷贝了完全配置好的同学的虚拟机,但需要修改部分的参数才能正常使用,此文章参考老师所提供的办法和部分文章所提 ...

  7. Linux下双线双ip访问内网服务器之另类解决办法

    一直被双线访问内网服务器的路由问题困扰,也在网上找了不少资料,但有些方法比较复杂,对我这种懒人来说实在懒得去看去测试.最接近的方法是iptables+iproute2,但我比较杯具的木有测试成功... ...

  8. docker网络问题解决办法“大全”:宿主机访问不了docker容器中web服务,容器内访问不了外网的问题的解决办法...

    ubuntu kylin 15 安装docker后 ,启动包含web应用的容器,在宿主机上死活访问不了web服务.后来发现进入容器后,安装不了软件,访问不了外网.因此网上查原因,有大神说让重建dock ...

  9. 国内up300.net网盘无法使用的解决办法

    因为要给日本客户传送文件,那边又访问不了百度网盘,邮箱也不够大,所以只能通过日本的网盘来发. (公司穷买不起日本专线...捂脸) 但是在up300.net选了文件,点了"文件传送" ...

最新文章

  1. python判断语句if...elif...else、if嵌套、三目运算符
  2. openpyxl读取excel_初识openpyxl--读取excel数据(二)
  3. 输入列号得到excel对应的字母列
  4. 用掘金-Markdown 官方语法总结大全
  5. 剑指OFFER之字符串的排列(九度OJ1369)
  6. 为什么电脑不能打字_为什么不能用电脑验光仪测出来的度数直接配眼镜?
  7. PHP操作Mongodb API 及使用类 封装好的MongoDB操作类
  8. SQLException:The server time zone value is unrecognized
  9. 【Flink】Flink 与数据库的集成最佳实践 【视频笔记】
  10. C++安全方向(三):3.7 使用openssl_evp接口完成SHA3和国密SM3
  11. python virtualenv
  12. 《IT经理世界》:中国软件业开始起飞
  13. MongoDb 聚合报错
  14. opencv鼠标回调函数实现ROI区域像素值相同化
  15. java指定一个具体日期
  16. 2018.12.25|区块链技术头条
  17. 37--8位级联加法器,并行加法器
  18. smb协议讲解_SMB/CIFS协议解析一概述
  19. 学习残差神经网络(ResNet)
  20. 金蝶kis迷你版操作大全

热门文章

  1. alien工具的快速安装及使用方法
  2. 系统基于 php 开发,基于PHP技术的计算机基础考试系统的开发
  3. 解决MySQL insert出现Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘xxx‘ at row 1
  4. 极度未知(HyperX)家族小配列大制作60%键盘——起源60游戏键盘
  5. bpmnxml导入mysql_Activiti6简明教程
  6. php 魔术方法是什么,php魔术方法有哪些
  7. Neutron概念认识
  8. 渗透测试-后渗透-痕迹清理
  9. SharePoint 集成OWA实战教程-杨建宇(霖雨)-专题视频课程
  10. 圆通开放平台电子面单下单接口,适用于第三方系统对接