CAS 之 集成RESTful API
内部邀请码:C8E245J (不写邀请码,没有现金送)
国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为“中国PE第一股”,市值超1000亿元。
原文地址: http://denger.iteye.com/blog/973068
关于CAS的登录验证流程,可以参考“CAS 之 实现用户注册后自动登录”,这里的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 包,分别是:
- 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
这几个jar已经打包在附件中了,另外 restlet.org 的 maven库中也有,需要的话可以去 maven.restlet.org 上找。
另外关于 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即可.
Java代码调用示例:
- 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));
- }
- }
- restlet.zip (457.7 KB)
- 下载次数: 434
CAS 之 集成RESTful API的更多相关文章
- springboot集成swagger2,构建优雅的Restful API
swagger,中文“拽”的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅,而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api,简单优雅 ...
- (转)第十一篇:springboot集成swagger2,构建优雅的Restful API
声明:本部分内容均转自于方志明博友的博客,因为本人很喜欢他的博客,所以一直在学习,转载仅是记录和分享,若也有喜欢的人的话,可以去他的博客首页看:http://blog.csdn.net/forezp/ ...
- (转) SpringBoot非官方教程 | 第十一篇:springboot集成swagger2,构建优雅的Restful API
swagger,中文“拽”的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅,而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api,简单优雅 ...
- springboot集成swagger2构建RESTful API文档
在开发过程中,有时候我们需要不停的测试接口,自测,或者交由测试测试接口,我们需要构建一个文档,都是单独写,太麻烦了,现在使用springboot集成swagger2来构建RESTful API文档,可 ...
- SpringBoot非官方教程 | 第十一篇:springboot集成swagger2,构建优雅的Restful API
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-swagger2/ 本文出自方志朋的博客 swa ...
- 【Tech】CAS RESTful API使用笔记
在被maven,cas,tomcat各种贱人就是矫情的虐了好几天之后,终于跑通了demo,哈哈哈哈哈哈哈~ 在这里详细记录一下,给和我一样连maven都不会的小白一点福利,同时欢迎大神指正. 首先上最 ...
- Spring Boot 集成Swagger2生成RESTful API文档
Swagger2可以在写代码的同时生成对应的RESTful API文档,方便开发人员参考,另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API. 使用Spring Boot可 ...
- 集成swagger2构建Restful API
集成swagger2构建Restful API 在pom.xml中进行版本管理 <swagger.version>2.8.0</swagger.version> 给taosir ...
- Spring Boot 集成 Swagger 生成 RESTful API 文档
原文链接: Spring Boot 集成 Swagger 生成 RESTful API 文档 简介 Swagger 官网是这么描述它的:The Best APIs are Built with Swa ...
随机推荐
- 浅谈HTTP响应拆分攻击
在本文中,我们将探讨何谓HTTP响应拆分以及攻击行为是怎样进行的.一旦彻底理解了其发生原理(该原理往往被人所误解),我们就可以探究如何利用响应拆分执行跨站点脚本(简称XSS).接下来自然就是讨论如果目 ...
- 利用动软代码生成器 自动生成LINQ需要用的数据实体类 (转)
首先先建立一个模板 名称随意 我起的“生成数据实体.cmt” 代码如下: <#@ template language="c#" HostSpecific="True ...
- RxJava学习(一)
注意:文字和图片转载自抛物线博客 参考:http://gank.io/post/560e15be2dca930e00da1083 RxJava 到底是什么 一个词:异步. RxJava 在 GitHu ...
- 如何使用GetManifestResourceStream
在做开发时想要从程序集中加载一个xml文件数据,可是在运行后确取不到值,值始终是null. 代码如下: Stream ss = this.GetType().Assembly.GetManifestR ...
- 【POJ】1054 The Troublesome Frog
题目是非常经典的搜索+剪枝.题意简言之就是,青蛙需要沿着直线踩着踏点通过田地,并且踏点需要至少为3.问哪条路径青蛙踩坏的作物最多.很好的一个条件是青蛙每次移动都是等间距的.题目需要注意将其排序. #i ...
- BZOJ_1625_ [Usaco2007_Dec]_宝石手镯_(01背包)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1625 01背包裸题. p.s.随便点开一道就是水题... 分析 ... #include &l ...
- 在Windows中隐藏用户的方法
这两天新建了一个用户用于共享文件,由于我的电脑只有我一个人用,多了一个用户后在登录界面上觉得挺碍事的,便想把它隐藏起来.找了一下,可以通过如下方式实现: 在注册表编辑器新建项值: HKEY_LOCAL ...
- java 页面url传值中文乱码的解决方法
parent.window.location.href 和 iframe中src的乱码问题.要在这两个url地址中传中文,必须加编码,然后再解码.编码:encodeURI(encodeURI(&quo ...
- 浏览器加载和渲染html的顺序-css渲染效率的探究
1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...
- Sqlite数据库的加密
最近在做一个winform的程序,考虑用Sqlite的数据库,小巧而实用,比Access强多了,不过需要加密,不过free版本没有实现加密,有一些c++的实现:比如:http://www.sqlite ...