环境准备
服务器名称 | 访问地址 |
---|---|
CAS认证服务器 | http://localhost:8080/cas |
CAS单点登录客户端1(可代理访问客户端2) | http://localhost:8088/cas-client |
CAS单点登录客户端2(被代理服务端) | http://localhost:8087/cas-client-be-used-to-proxy |
http://localhost:8088/cas-client/test 实现在客户端1上登录,并访问资源/test。
http://localhost:8088/cas-client/proxyServlet 客户端1在访问资源/proxyServlet的过程中,代理端将访问了客户端2(被代理端)的资源。
1. CAS单点登录服务端配置
对于代理策略的修改,我们将要修改的文件是在cas-server-webapp模块下的\resources\services中的两个文件。首先将Apereo-10000002.json 和HTTPSandIMAPS-10000001.json 都按下面方法修改,两个文件中都有:proxyPolicy的配置信息,都将RefuseRegisteredServiceProxyPolicy改为RegexMatchingRegisteredServiceProxyPolicy,然后也都将配置信息中的authorizedToReleaseProxyGrantingTicket后的false改为true。
备注:
RefuseRegisteredServiceProxyPolicy使用该类作为代理策略时不支持代理。
RegexMatchingRegisteredServiceProxyPolicy支持代理。
*RefuseRegisteredServiceProxyPolicy.java*
public final class RefuseRegisteredServiceProxyPolicy implements RegisteredServiceProxyPolicy {
private static final long serialVersionUID = -5718445151129901484L;
//直接返回false
@Override
public boolean isAllowedToProxy() {
return false;
}
//直接返回false
@Override
public boolean isAllowedProxyCallbackUrl(final URL pgtUrl) {
return false;
}
…… ……
}
*RegexMatchingRegisteredServiceProxyPolicy.java*
public final class RegexMatchingRegisteredServiceProxyPolicy implements RegisteredServiceProxyPolicy {
……
/**
* Instantiates a new Regex matching registered service proxy policy.
* Required for serialization.
*/
protected RegexMatchingRegisteredServiceProxyPolicy() {
this.pattern = null;
}
/**
* Init the policy with the pgt url regex pattern that
* will determine the urls allowed to receive the pgt.
* The matching by default is done in a case insensitive manner.
* @param pgtUrlPattern the pgt url pattern
*/
public RegexMatchingRegisteredServiceProxyPolicy(@NotNull final String pgtUrlPattern) {
this.pattern = Pattern.compile(pgtUrlPattern, Pattern.CASE_INSENSITIVE);
}
/**
* Gets the pattern.
*
* @return the pattern
*/
public Pattern getPattern() {
return this.pattern;
}
//默认直接是允许代理
@Override
public boolean isAllowedToProxy() {
return true;
}
…… ……
//通过请求的pgturl是否满足我们设定的pattern来判断代理回调url
@Override
public boolean isAllowedProxyCallbackUrl(final URL pgtUrl) {
return this.pattern.matcher(pgtUrl.toExternalForm()).find();
}
}
2. CAS单点登录客户端1配置(代理服务端)
CAS单点登录客户端采用简单的servlet进行开发一个web项目工程。
首先是修改我们的web.xml配置文件,增加如下的配置信息。
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://localhost:8080/cas/</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8088</param-value>
</init-param>
<!-- 新增配置部分-->
<init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>
http://localhost:8088/cas-client/proxyCallback
</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/proxyCallback</param-value>
</init-param>
</filter>
注意上面新增部分是在普通模式基础上新增加的配置部分,是用于代理模式下的配置。
在CAS Validation Filter过滤器下新增对应的配置。
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/proxyCallback</url-pattern>
</filter-mapping>
*注意顺序,在代理模式下,这个配置一定要在其他filter-mapping之前。
代理端发起请求,调用被代理端服务的简单servlet代码。
@WebServlet("/proxyServlet")
public class ProxyServlet extends HttpServlet {
......
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String serviceUrl = "http://localhost:8087/cas-client-be-used-to-proxy/test";
Assertion assertion = AssertionHolder.getAssertion();
String proxyTicket = assertion.getPrincipal().getProxyTicketFor(serviceUrl);
//构建请求URL
URL url = new URL(serviceUrl + "?ticket=" + proxyTicket);
HttpURLConnection conn = null;
String responseMessage =null;
try{
conn = (HttpURLConnection) url.openConnection();
int responseCode = conn.getResponseCode();
System.out.println("请求响应码:"+responseCode);
InputStreamReader in = null;
if (false) {
in = new InputStreamReader(conn.getInputStream());
} else {
in = new InputStreamReader(conn.getInputStream(), "utf-8");
}
final StringBuilder builder = new StringBuilder(255);
int byteRead;
while ((byteRead = in.read()) != -1) {
builder.append((char) byteRead);
}
responseMessage=builder.toString();
System.out.println("解析收到信息:"+ responseMessage);
}catch (Exception e) {
e.printStackTrace();
}finally{
if(conn !=null ) {
conn.disconnect();
}
}
//直接在前端输出
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("从"+serviceUrl+"获取的数据:<br><br><br>");
out.println(responseMessage);
}
3. CAS单点登录客户端2配置(被代理服务端)
在完成代理端修改之后,被代理端我们需要实现一个服务用于给代理端获取数据。只要拷贝一下服务端的web项目,修改一下配置。只要实现代理端调用的接口http://localhost:8087/cas-client-be-used-to-proxy/test方法就可以。
但是我们还是要在web.xml中添加acceptAnyProxy 和redirectAfterValidation参数,支持接受代理。
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://localhost:8080/cas/</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8087</param-value>
</init-param>
<!-- 被代理端配置代理相关信息-->
<init-param>
<param-name>acceptAnyProxy</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>false</param-value>
</init-param>
</filter>
至此,代理模式下的环境准备完成,后续章节中会继续分析代理模式下代码是如何进行的。