CAS单点登录开源框架解读(十三)--CAS单点登录代理模式之代理端验证获取用户身份过程
代理模式访问过程分两步实现代理过程:1、用户先访问CAS单点登录代理端(也就是上一章节中客户端1)的地址url1:http://localhost:8088/cas-client/test,此地址就是用于普通的单点登录。2、再访问CAS单点登录代理端地址url2:http://localhost:8088/cas-client/proxyServlet在上一章节中我们知道在url的...
代理模式访问过程
分两步实现代理过程:
1、用户先访问CAS单点登录代理端(也就是上一章节中客户端1)的地址
url1:http:// localhost:8088/cas-client/test,此地址就是用于普通的单点登录。
2、再访问CAS单点登录代理端地址
url2:http:// localhost:8088/cas-client/proxyServlet
在上一章节中我们知道在url的请求下到servlet中要访问被代理端(也就是上一章节客户端2)的接口: http:// localhost:8087/cas-client-be-used-to-proxy/test
1. 代理端获取用户身份信息之调用ticketValidator.validate
CAS单点登录客户端向CAS单点登录服务端发送验证请求,与普通模式比较,在“调用第3个filter”之前一样,在此不赘述,我们将直接从“调用ticketValidator.validate校验ticket”开始进行代码的分析和解读。
public abstract class AbstractUrlBasedTicketValidator implements TicketValidator {
public final Assertion validate(final String ticket, final String service) throws TicketValidationException {
final String validationUrl = constructValidationUrl(ticket, service);
logger.debug("Constructing validation url: {}", validationUrl);
try {
logger.debug("Retrieving response from server.");
final String serverResponse = retrieveResponseFromServer(new URL(validationUrl), ticket);
......
调用constructValidationUrl()与普通模式比,请求的url会增加pgtUrl=xxx, 调用retrieveResponseFromServer(),与普通模式过程一样,但是请求的URL和普通模式不同。
后面分别分析constructValidationUrl()和retrieveResponseFromServer()
2. 代理端获取用户身份信息之调用constructValidationUrl
在ticketValidator.validate里调用constructValidationUrl
*AbstractUrlBasedTicketValidator.java*
public abstract class AbstractUrlBasedTicketValidator implements TicketValidator {
protected final String constructValidationUrl(final String ticket, final String serviceUrl) {
final Map<String, String> urlParameters = new HashMap<String, String>();
logger.debug("Placing URL parameters in map.");
urlParameters.put("ticket", ticket);
urlParameters.put("service", serviceUrl);
if (this.renew) {
urlParameters.put("renew", "true");
}
logger.debug("Calling template URL attribute map.");
//添加key="pgtUrl",value="http://localhost:8088/cas_client/proxyCallback"
populateUrlAttributeMap(urlParameters);
logger.debug("Loading custom parameters from configuration.");
if (this.customParameters != null) {
urlParameters.putAll(this.customParameters);
}
//值为"serviceValidate"
final String suffix = getUrlSuffix();
final StringBuilder buffer = new StringBuilder(urlParameters.size() * 10 + this.casServerUrlPrefix.length()
+ suffix.length() + 1);
int i = 0;
buffer.append(this.casServerUrlPrefix);
if (!this.casServerUrlPrefix.endsWith("/")) {
buffer.append("/");
}
buffer.append(suffix);
//构建请求url,带上参数
for (Map.Entry<String, String> entry : urlParameters.entrySet()) {
final String key = entry.getKey();
final String value = entry.getValue();
if (value != null) {
buffer.append(i++ == 0 ? "?" : "&");
buffer.append(key);
buffer.append("=");
final String encodedValue = encodeUrl(value);
buffer.append(encodedValue);
}
}
return buffer.toString();
}
构建成功的url值为:
http:// localhost:8080/cas/serviceValidate?pgtUrl=http%3A%2F%2Flocalhost%3A8088%2Fcas_client%2FproxyCallback&ticket=ST-7-4cq5kQ55wC9SeHOBDdTU-cas01.example.org&service=http%3A%2F%2Flocalhost%3A8088%2Fcas_client%2Ftest%3Bjsessionid%3DBE30CE36139A115A8B28998B54460A9F
下面我们再来看看populateUrlAttributeMap()和getUrlSuffix()的代码
*Cas20ServiceTicketValidator.java*
public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTicketValidator {
protected final void populateUrlAttributeMap(final Map<String, String> urlParameters) {
urlParameters.put("pgtUrl", this.proxyCallbackUrl);
}
protected String getUrlSuffix() {
return "serviceValidate";
}
大家一看就能明白。
3. 代理端获取用户身份信息之调用retrieveResponseFromServer访问CAS服务器
前面章节有分析这个代码,大家看一下请求的url和返回结果吧。
*CommonUtils.java*
public final class CommonUtils {
public static String getResponseFromServer(final URL constructedUrl, final HttpURLConnectionFactory factory, final String encoding) {
HttpURLConnection conn = null;
InputStreamReader in = null;
try {
conn = factory.buildHttpURLConnection(constructedUrl.openConnection());
if (CommonUtils.isEmpty(encoding)) {
in = new InputStreamReader(conn.getInputStream());
} else {
in = new InputStreamReader(conn.getInputStream(), encoding);
}
final StringBuilder builder = new StringBuilder(255);
int byteRead;
while ((byteRead = in.read()) != -1) {
builder.append((char) byteRead);
}
return builder.toString();
} catch ......
}
这里代理端的请求地址为:
http:// localhost:8080/cas/serviceValidate?pgtUrl=http%3A%2F%2Flocalhost%3A8088%2Fcas_client%2FproxyCallback&ticket=ST-7-4cq5kQ55wC9SeHOBDdTU-cas01.example.org&service=http%3A%2F%2Flocalhost%3A8088%2Fcas_client%2Ftest%3Bjsessionid%3DBE30CE36139A115A8B28998B54460A9F
CAS单点登录服务端返回值(后面接着分析服务端过程)为:
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>casuser</cas:user>
<cas:proxyGrantingTicket>PGTIOU-3-dnQIfy74cI6NFpOBcggURbUrX1pbhal2hrnKGPZgvIrVXQiXQb-cas01.example.org</cas:proxyGrantingTicket>
</cas:authenticationSuccess>
</cas:serviceResponse>
到此,在代理模式下,我们从CAS单点登录服务端获取到了用户信息,以及PGTIOU的值,那么后续我们将解析,CAS单点登录服务端是如何在代理模式下工作的。
更多推荐
所有评论(0)