CAS 之 集成RESTful API

最近因为公司另一款基于C/S的产品也需要整合到CAS 的 SSO,但是 CAS 本身对于客户端或浏览器而言是基于其COOKIE来存储用户(TGT)Ticket的,所以这时候就需要使用 CAS 的 RestFul API 来进行登录验证,并支持在C/S软件中点击用户头象时打开浏览器并跳转至用户中心,而且这时候在 WEB 上应该是已登录的状态(类似QQ点击自己的头象时,马上就进入到了QQ空间。)

关于CAS的登录验证流程,可以参考“[url=http://denger.iteye.com/blog/805743]CAS 之 实现用户注册后自动登录[/url]”,这里的RESTful登录验证流程与其大致相似,大体流程为:首先客户端提交用户名、密码、及Service三个参数,如果验证成功便返回用户的TGT(Ticket Granting Ticket)至客户端, 然后客户端再根据 TGT 获取用户的 ST(Service Ticket)来进行验证登录。 故名思意,TGT是用于生成一个新的Ticket(ST)的Ticket,而ST则是提供给客户端用于登录的Ticket,两者最大的区别在于,TGT是用户名密码验证成功之后所生成的Ticket,并且会保存在Server中及Cookie中,而ST则必须是是根据TGT来生成,主要用于登录,并且当登录成功之后 ST 则会失效。

CAS本身已经提供了 restlet 的集成包,如果你用的是 maven 的话直接加入,我这里的Cas-server的版本是 3.4.2.1:

<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-integration-restlet</artifactId>
<version>3.4.2.1</version>
<type>jar</type>
</dependency>

然后再在 web.xml 中加入:
<servlet>
<servlet-name>restlet</servlet-name>
<servlet-class>com.noelios.restlet.ext.spring.RestletFrameworkServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>restlet</servlet-name>
<url-pattern>/v1/*</url-pattern>
</servlet-mapping>


因为使用到了 Restlat 框架,所以还需要依赖几个 jar 包,分别是:
[list]
[*] com.noelios.restlet.ext.servlet.jar
[*] com.noelios.restlet.ext.spring-1.1.0.jar
[*] com.noelios.restlet.jar
[*] org.restlet-1.1.10.jar
[*] org.restlet.ext.spring-1.1.10.jar
[/list]
这几个jar已经打包在附件中了,另外 restlet.org 的 maven库中也有,需要的话可以去 [url=maven.restlet.org]maven.restlet.org[/url] 上找。
另外关于 restlet的配置在 cas-server中已经存在在: /WEB-INF/restlet-servlet.xml文件。

配置OK之后直接启动Server,下面来进行简单登录验证的测试:

1. 提交用户名密码及Service 进行登录验证
DengerMacBook:cas-server denger$ curl -i -X  POST -d "username=admin&password=123456&service=http://www.google.com" http://192.168.41.107:8080/member/v1/tickets/

HTTP/1.1 201 Created
Date: Wed, 23 Mar 2011 12:42:52 GMT
Location: http://192.168.41.107:8080/member/v1/tickets/TGT-14-gDOn9hhSYmq3xfeTRNhTAjZgOMdCdyuVNfsuLRs6onNv7fVmmX-cas
Accept-Ranges: bytes
Server: Noelios-Restlet-Engine/1.1.6
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 437

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>201 The request has been fulfilled and resulted in a new resource being created</title></head><body><h1>TGT Created</h1><form action="http://192.168.41.107:8080/member/v1/tickets/TGT-14-gDOn9hhSYmq3xfeTRNhTAjZgOMdCdyuVNfsuLRs6onNv7fVmmX-cas" method="POST">Service:<input type="text" name="service" value=""><br><input type="submit" value="Submit"></form></body></html>

在以上Response信息及 Header中可以看到生成的 TGT,接下来是再重新根据 TGT 获取 ST,将请求的 URI 地址就是以上 Header中的 Location地址。

2. 根据返回的 TGT 来获取 ST
DengerMacBook:cas-server denger$ curl -i  -X POST -d "service=http://www.google.com" http://192.168.41.107:8080/member/v1/tickets/TGT-14-gDOn9hhSYmq3xfeTRNhTAjZgOMdCdyuVNfsuLRs6onNv7fVmmX-cas

HTTP/1.1 200 OK
Date: Wed, 23 Mar 2011 12:48:03 GMT
Accept-Ranges: bytes
Server: Noelios-Restlet-Engine/1.1.6
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 29

ST-2-lJfQyJMMEnNGnKcglf1d-cas

获取成功之后则返回了 ST,这时候对于客户端而言就已经拿到了登录的TIcket, 如果需要在Web中自动登录的话,只需要弹出浏览器,将ST作为 ticket参数传入即可。如,用户中心的后台地址首页是:http://www.google.com.hk/userCenter 则URL为: http://www.google.com.hk/userCenter?ticket=ST-3-9QkpLsFmCEqIXSVvGH9P-cas 并可进行登录。 当然前提是在该Web应用中需要部署cas-client应用。

3. 注销用户
DengerMacBook:cas-server denger$ curl -i  -X DELETE http://192.168.41.107:8080/member/v1/tickets/TGT-14-gDOn9hhSYmq3xfeTRNhTAjZgOMdCdyuVNfsuLRs6onNv7fVmmX-cas

HTTP/1.1 200 OK
Date: Wed, 23 Mar 2011 12:54:28 GMT
Accept-Ranges: bytes
Server: Noelios-Restlet-Engine/1.1.6
Content-Length: 0
注销用户就很简单了,直接 SUBMIT DELETE 删除 TGT即可.

[b]Java代码调用示例:[/b]
package cas;

import java.io.IOException;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;


public final class Client
{
private static final Logger LOG = Logger.getLogger(Client.class.getName());

private Client()
{
// static-only access
}

public static String getTicket(final String server, final String username,
final String password, final String service)
{
notNull(server, "server must not be null");
notNull(username, "username must not be null");
notNull(password, "password must not be null");
notNull(service, "service must not be null");

return getServiceTicket(server, getTicketGrantingTicket(server, username,
password), service);
}

private static String getServiceTicket(final String server,
final String ticketGrantingTicket, final String service)
{
if (ticketGrantingTicket == null)
return null;

final HttpClient client = new HttpClient();

final PostMethod post = new PostMethod(server + "/" + ticketGrantingTicket);

post.setRequestBody(new NameValuePair[] { new NameValuePair("service",
service) });

try
{
client.executeMethod(post);

final String response = post.getResponseBodyAsString();

switch (post.getStatusCode())
{
case 200:
return response;

default:
LOG.warning("Invalid response code (" + post.getStatusCode()
+ ") from CAS server!");
LOG.info("Response (1k): "
+ response.substring(0, Math.min(1024, response.length())));
break;
}
}

catch (final IOException e)
{
LOG.warning(e.getMessage());
}

finally
{
post.releaseConnection();
}

return null;
}

private static String getTicketGrantingTicket(final String server,
final String username, final String password)
{
final HttpClient client = new HttpClient();

final PostMethod post = new PostMethod(server);

post.setRequestBody(new NameValuePair[] {
new NameValuePair("username", username),
new NameValuePair("password", password) });

try
{
client.executeMethod(post);

final String response = post.getResponseBodyAsString();

switch (post.getStatusCode())
{
case 201:
{
final Matcher matcher = Pattern.compile(".*action=\".*/(.*?)\".*")
.matcher(response);

if (matcher.matches())
return matcher.group(1);

LOG
.warning("Successful ticket granting request, but no ticket found!");
LOG.info("Response (1k): "
+ response.substring(0, Math.min(1024, response.length())));
break;
}

default:
LOG.warning("Invalid response code (" + post.getStatusCode()
+ ") from CAS server!");
LOG.info("Response (1k): "
+ response.substring(0, Math.min(1024, response.length())));
break;
}
}

catch (final IOException e)
{
LOG.warning(e.getMessage());
}

finally
{
post.releaseConnection();
}

return null;
}

private static void notNull(final Object object, final String message)
{
if (object == null)
throw new IllegalArgumentException(message);
}

public static void main(final String[] args)
{
final String server = "http://192.168.41.107:8080/member/v1/tickets";
final String username = "admin";
final String password = "111111";
final String service = "http://localhost:8080/service";

LOG.info(getTicket(server, username, password, service));
}
}

参考:[url]https://wiki.jasig.org/display/CASUM/RESTful+API[/url]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
server 地址: http://www.jasig.org/cas/download client 地址: http://www.ja-sig.org/downloads/cas-clients/ 当前最新版本 cas-server-3.4.2 , cas-client-3.1.10 2. 安装 server l 解压 cas-server-3.4.2 ,将 cas-server-3.4.2\modules\cas-server-webapp-3.4.2.war 拷贝到 tomcat 的 webapps 下。 3. 配置 server 3.1. 添加 cas server 依赖的 jar n cas-server-3.4.2\modules\cas-server-support-jdbc-3.4.2.jar 、 cas-server-integration-restlet-3.4.2.jar 拷贝到 D:\server\apache-tomcat-6.0.18\webapps\cas\WEB-INF\lib 目录下。 n 数据库驱动 jar 拷贝到 D:\server\apache-tomcat-6.0.18\webapps\cas\WEB-INF\lib 目录下。 n 到 apache 网站下载下面三个 cas server 依赖 jar 包拷贝到 D:\server\apache-tomcat-6.0.18\webapps\cas\WEB-INF\lib 目录下 Ø http://apache.freelamp.com/commons/collections/binaries/commons-collections-3.2.1-bin.zip Ø http://apache.etoak.com/commons/dbcp/binaries/commons-dbcp-1.4-bin.zip Ø http://apache.etoak.com/commons/pool/binaries/commons-pool-1.5.4-bin.zip n 下载 restlet 相关 http://www.restlet.org/downloads/ , 解压后将下面 jar 拷贝到 D:\server\apache-tomcat-6.0.18\webapps\cas\WEB-INF\lib: ( 它奶奶地这一步骤很折腾 ) com.noelios.restlet.ext.servlet_2.5.jar com.noelios.restlet.ext.spring_2.5.jar com.noelios.restlet.jar org.restlet.ext.spring_2.5.jar org.restlet.jar n 下载 CGlib http://sourceforge.net/projects/cglib/files/ 拷贝到 D:\server\apache-tomcat-6.0.18\webapps\cas\WEB-INF\lib 。 n 下载 ASM/OW2 http://forge.ow2.org/projects/asm/ 拷贝到 D:\server\apache-tomcat-6.0.18\webapps\cas\WEB-INF\lib 。 3.2. 添加数据源

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值