# integrated-cas3-ssh

# 一、前置条件

# 1、环境信息

IntelliJ IDEA 2019.3.5 (Ultimate Edition)

java version: "1.6.0_65"

Server version: Apache Tomcat/7.0.99

mysql version: 5.7.38

# 二、集成方式及说明

# 1、web.xml

<!-- 注:CASclient相关配置要在 StrutsPrepareFilter 和 StrutsExecuteFilter过滤器里面,
因为使用的是自定义过滤器不使用 StrutsPrepareAndExecuteFilter 过滤器否则cas相关配置会失效。 -->

<!-- CASClient logout登出监听器 -->
<listener>
  <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>

<!-- Struts2的过滤器配置 -->
<filter>
  <filter-name>struts-prepare</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
</filter>
<!-- Struts2过滤器拦截所有的.action请求 -->
<filter-mapping>
  <filter-name>struts-prepare</filter-name>
  <url-pattern>*.action</url-pattern>
</filter-mapping>

<!-- CAS Single Sign Out Filter -->
<filter>
  <filter-name>CAS Single Sign Out Filter</filter-name>
  <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
   <!-- CAS 服务器 URL -->
  <init-param>
    <param-name>casServerUrlPrefix</param-name>
    <param-value>http://127.0.0.1:8000/cas</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CAS Single Sign Out Filter</filter-name>
  <url-pattern>*.action</url-pattern>
</filter-mapping>

<!-- CAS Authentication Filter -->
<filter>
  <filter-name>CAS Authentication Filter</filter-name>
  <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
  <!-- 定义 CAS 服务器登录 URL 的位置。如果设置,这将覆盖 casServerUrlPrefix。-->
  <init-param>
    <param-name>casServerLoginUrl</param-name>
    <param-value>http://127.0.0.1:8000/cas/login</param-value>
  </init-param>
   <!-- client-ssh 客户端 URL -->
  <init-param>
    <param-name>serverName</param-name>
    <param-value>http://127.0.0.1:8081</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CAS Authentication Filter</filter-name>
  <url-pattern>*.action</url-pattern>
</filter-mapping>

<!-- CAS Validation Filter -->
<filter>
  <filter-name>CAS Validation Filter</filter-name>
  <filter-class>org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter</filter-class>
  <!-- CAS 服务器 URL -->
  <init-param>
    <param-name>casServerUrlPrefix</param-name>
    <param-value>http://127.0.0.1:8000/cas</param-value>
  </init-param>
  <!-- client-ssh 客户端 URL -->
  <init-param>
    <param-name>serverName</param-name>
    <param-value>http://127.0.0.1:8081</param-value>
  </init-param>
  <!-- ticket验证后是否重定向到 URL。默认为true。 -->
  <init-param>
    <param-name>redirectAfterValidation</param-name>
    <param-value>true</param-value>
  </init-param>
  <!-- 指定客户端应该使用的编码字符集 -->
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
  <!-- 是否将Assertion存储在session中。如果不使用session,则每个请求都需要ticket。默认为true。 -->
  <init-param>
    <param-name>useSession</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CAS Validation Filter</filter-name>
  <url-pattern>*.action</url-pattern>
</filter-mapping>

<!-- CAS HttpServletRequest Wrapper Filter -->
<filter>
  <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
  <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
  <url-pattern>*.action</url-pattern>
</filter-mapping>

<filter>
  <filter-name>struts-execute</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>struts-execute</filter-name>
  <url-pattern>*.action</url-pattern>
</filter-mapping>
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

# 2、struts.xml

<struts>
	<!--开发模式下,修改 struts.xml 后不需重启Tomcat便可立即生效 -->
	<constant name="struts.devMode" value="true" />
	<!-- 开启动态方法调用权限 -->
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />

	<package name="home" namespace="/home" extends="struts-default,json-default">
    <!-- 跳转需要权限的suser.jsp 页面 -->
		<action name="suser" class="sUserAction" method="suserJsp">
			<result name="success">/WEB-INF/view/suser.jsp</result>
		</action>
    <!-- 从request里获取用户信息 -->
		<action name="getUserPrincipal" class="sUserAction" method="getUserPrincipal">
			<result name="success" type="json">
        <!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
				<param name="root">result</param>
        <!-- 指定是否序列化空的属性 -->
				<param name="excludeNullProperties">true</param>
			</result>
		</action>
    <!-- 根据token获取用户信息 -->
		<action name="getUserInfoDetail" class="sUserAction" method="getUserInfoDetail">
			<result name="success" type="json">
				<param name="root">result</param>
				<param name="excludeNullProperties">true</param>
			</result>
		</action>
    <!-- 根据RefreshToken重新获取 token -->
		<action name="getRefreshToken" class="sUserAction" method="getRefreshToken">
			<result name="success" type="json">
				<param name="root">result</param>
				<param name="excludeNullProperties">true</param>
			</result>
		</action>
    <!-- 登出 重定向到cas service -->
		<action name="logout" class="sUserAction" method="logout">
			<result name="success" type="redirect">http://127.0.0.1:8000/cas/logout?service=${result}</result>
		</action>
	</package>
</struts>
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

# 3、SUserAction.java

@Controller("sUserAction")
@Scope("prototype")
public class SUserAction extends ActionSupport implements ServletRequestAware {

  @Autowired
  private SUserService sUserService;

  //传入参数
  private String id = "1";

  // 存储业务处理结果
  private SUser sUser;
  private String result;
  private HttpServletRequest request;
  
  //...忽略get set 方法
  
  /**
  * 从本地数据库里获取用户信息
  * @return
  */
  public String suserJsp(){
    sUser = sUserService.getUser(id);
    return Action.SUCCESS;
  }
  
  /**
  * 获取request里的用户信息
  * @return
  */
  public String getUserPrincipal(){
    AttributePrincipal userPrincipal = (AttributePrincipal) request.getUserPrincipal();
    this.result = userPrincipal.getAttributes().toString();
    return Action.SUCCESS;
  }
  
  /**
  * 根据token获取用户信息
  * @return
  */
  public String getUserInfoDetail() {
    AttributePrincipal userPrincipal = (AttributePrincipal) request.getUserPrincipal();
    String token = (String) userPrincipal.getAttributes().get("token");
    JSONObject result = SinosoftPlatformApi.getUserInfoDetail("http://127.0.0.1:9100", token, "systemcode1");
    this.result = result.toString();
    return Action.SUCCESS;
  }
  
  /**
  * 根据RefreshToken重新获取 token
  * @return
  */
  public String getRefreshToken(){
    AttributePrincipal userPrincipal = (AttributePrincipal) request.getUserPrincipal();
    String refreshToken = (String) userPrincipal.getAttributes().get("refreshToken");
    JSONObject result = SinosoftPlatformApi.getTokenByRefreshToken("http://127.0.0.1:9100", refreshToken, "systemcode1");
    this.result = result.toString();
    return Action.SUCCESS;
  }
  
  /**
  * 登出
  * @return
  */
  public String logout(){
    HttpSession session = request.getSession(false);
    if (session != null) {
      // 过期会话
      session.invalidate();
    }

    //处理URLEncoder
    try {
      this.result = URLEncoder.encode("http://127.0.0.1:8081", "UTF-8").replace("+", "%20");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return Action.SUCCESS;
  }
  
  @Override
  public void setServletRequest(HttpServletRequest httpServletRequest) {
    this.request = httpServletRequest;
  }
}
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
79
80
81
82
83
84
85

# 4、suser.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
  <head>
    <title>用户</title>
  </head>
  <body>
   用户页面(需要权限)
   <s:property value="sUser.id" />
   <s:property value="sUser.userName" />
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12

# 三、效果展示

# 1、不需要权限index.jsp页面

访问 http://127.0.0.1:8081会跳转到 index.jsp 不需要权限。

image-20220523181207749

# 2、登陆

我们访问 http://127.0.0.1:8081/home/suser.action会跳转到CAS Service登陆页进行登录。

image-20220523181439262

# 3、从本地数据库里获取用户信息

http://127.0.0.1:8081/home/suser.action

登陆成功后,从本地数据库查询用户信息并跳转到suser.jsp页面。

image-20220523181337735

# 4、从获取request里的用户信息

http://127.0.0.1:8081/home/getUserPrincipal.action

要从request获取用户信息。

image-20220523182351876

# 5、根据token获取用户信息

http://127.0.0.1:8081/home/getUserInfoDetail.action

如何获取token及请求planfromApi ,参考【三、关键配置信息】。

image-20220523182925014

# 6、根据RefreshToken重新获取 token

http://127.0.0.1:8081/home/getRefreshToken.action

image-20220523183153846

# 7、登出

http://127.0.0.1:8081/home/logout.action

登出后会跳转到index.jsp页面,若要修改登出后跳转的页面请参考【三、关键配置信息(2、struts.xml 和 3、SUserAction.java 中logout()方法)】,以下是登出成功后效果图。

image-20220523183750597.png

# 四、demo程序

下载地址:client-ssh.zip

依赖jar包:platform-client-common-1.0.0.jar