• CAS 之 集成RESTful API


    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html
    内部邀请码:C8E245J (不写邀请码,没有现金送)
    国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为“中国PE第一股”,市值超1000亿元。 
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------

    原文地址: http://denger.iteye.com/blog/973068

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

         关于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: 
    Xml代码  收藏代码
    1. <dependency>  
    2.     <groupId>org.jasig.cas</groupId>  
    3.     <artifactId>cas-server-integration-restlet</artifactId>  
    4.     <version>3.4.2.1</version>  
    5.     <type>jar</type>  
    6. </dependency>  

         然后再在 web.xml 中加入: 
    Xml代码  收藏代码
    1. <servlet>  
    2.         <servlet-name>restlet</servlet-name>  
    3.         <servlet-class>com.noelios.restlet.ext.spring.RestletFrameworkServlet</servlet-class>  
    4.         <load-on-startup>1</load-on-startup>  
    5.     </servlet>  
    6.   
    7.     <servlet-mapping>  
    8.         <servlet-name>restlet</servlet-name>  
    9.         <url-pattern>/v1/*</url-pattern>  
    10.     </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 进行登录验证 
          
    Shell代码  收藏代码
    1. 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/  
    2.   
    3. HTTP/1.1 201 Created  
    4. Date: Wed, 23 Mar 2011 12:42:52 GMT  
    5. Location: http://192.168.41.107:8080/member/v1/tickets/TGT-14-gDOn9hhSYmq3xfeTRNhTAjZgOMdCdyuVNfsuLRs6onNv7fVmmX-cas  
    6. Accept-Ranges: bytes  
    7. Server: Noelios-Restlet-Engine/1.1.6  
    8. Content-Type: text/html;charset=ISO-8859-1  
    9. Content-Length: 437  
    10.   
    11. <!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 
       
    Shell代码  收藏代码
    1. 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  
    2.   
    3. HTTP/1.1 200 OK  
    4. Date: Wed, 23 Mar 2011 12:48:03 GMT  
    5. Accept-Ranges: bytes  
    6. Server: Noelios-Restlet-Engine/1.1.6  
    7. Content-Type: text/plain;charset=ISO-8859-1  
    8. Content-Length: 29  
    9.   
    10. 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. 注销用户 
      
    Shell代码  收藏代码
    1. DengerMacBook:cas-server denger$ curl -i  -X DELETE http://192.168.41.107:8080/member/v1/tickets/TGT-14-gDOn9hhSYmq3xfeTRNhTAjZgOMdCdyuVNfsuLRs6onNv7fVmmX-cas  
    2.   
    3. HTTP/1.1 200 OK  
    4. Date: Wed, 23 Mar 2011 12:54:28 GMT  
    5. Accept-Ranges: bytes  
    6. Server: Noelios-Restlet-Engine/1.1.6  
    7. Content-Length: 0  
      注销用户就很简单了,直接 SUBMIT DELETE 删除 TGT即可. 

      Java代码调用示例: 
    Java代码  收藏代码
    1. package cas;  
    2.   
    3. import java.io.IOException;  
    4. import java.util.logging.Logger;  
    5. import java.util.regex.Matcher;  
    6. import java.util.regex.Pattern;  
    7.   
    8. import org.apache.commons.httpclient.HttpClient;  
    9. import org.apache.commons.httpclient.NameValuePair;  
    10. import org.apache.commons.httpclient.methods.PostMethod;  
    11.   
    12.   
    13. public final class Client  
    14. {  
    15.   private static final Logger LOG = Logger.getLogger(Client.class.getName());  
    16.   
    17.   private Client()  
    18.   {  
    19.     // static-only access  
    20.   }  
    21.   
    22.   public static String getTicket(final String server, final String username,  
    23.       final String password, final String service)  
    24.   {  
    25.     notNull(server, "server must not be null");  
    26.     notNull(username, "username must not be null");  
    27.     notNull(password, "password must not be null");  
    28.     notNull(service, "service must not be null");  
    29.   
    30.     return getServiceTicket(server, getTicketGrantingTicket(server, username,  
    31.         password), service);  
    32.   }  
    33.   
    34.   private static String getServiceTicket(final String server,  
    35.       final String ticketGrantingTicket, final String service)  
    36.   {  
    37.     if (ticketGrantingTicket == null)  
    38.       return null;  
    39.   
    40.     final HttpClient client = new HttpClient();  
    41.   
    42.     final PostMethod post = new PostMethod(server + "/" + ticketGrantingTicket);  
    43.   
    44.     post.setRequestBody(new NameValuePair[] { new NameValuePair("service",  
    45.         service) });  
    46.   
    47.     try  
    48.     {  
    49.       client.executeMethod(post);  
    50.   
    51.       final String response = post.getResponseBodyAsString();  
    52.   
    53.       switch (post.getStatusCode())  
    54.       {  
    55.         case 200:  
    56.           return response;  
    57.   
    58.         default:  
    59.           LOG.warning("Invalid response code (" + post.getStatusCode()  
    60.               + ") from CAS server!");  
    61.           LOG.info("Response (1k): "  
    62.               + response.substring(0, Math.min(1024, response.length())));  
    63.           break;  
    64.       }  
    65.     }  
    66.   
    67.     catch (final IOException e)  
    68.     {  
    69.       LOG.warning(e.getMessage());  
    70.     }  
    71.   
    72.     finally  
    73.     {  
    74.       post.releaseConnection();  
    75.     }  
    76.   
    77.     return null;  
    78.   }  
    79.   
    80.   private static String getTicketGrantingTicket(final String server,  
    81.       final String username, final String password)  
    82.   {  
    83.     final HttpClient client = new HttpClient();  
    84.   
    85.     final PostMethod post = new PostMethod(server);  
    86.   
    87.     post.setRequestBody(new NameValuePair[] {  
    88.         new NameValuePair("username", username),  
    89.         new NameValuePair("password", password) });  
    90.   
    91.     try  
    92.     {  
    93.       client.executeMethod(post);  
    94.   
    95.       final String response = post.getResponseBodyAsString();  
    96.   
    97.       switch (post.getStatusCode())  
    98.       {  
    99.         case 201:  
    100.         {  
    101.           final Matcher matcher = Pattern.compile(".*action=".*/(.*?)".*")  
    102.               .matcher(response);  
    103.   
    104.           if (matcher.matches())  
    105.             return matcher.group(1);  
    106.   
    107.           LOG  
    108.               .warning("Successful ticket granting request, but no ticket found!");  
    109.           LOG.info("Response (1k): "  
    110.               + response.substring(0, Math.min(1024, response.length())));  
    111.           break;  
    112.         }  
    113.   
    114.         default:  
    115.           LOG.warning("Invalid response code (" + post.getStatusCode()  
    116.               + ") from CAS server!");  
    117.           LOG.info("Response (1k): "  
    118.               + response.substring(0, Math.min(1024, response.length())));  
    119.           break;  
    120.       }  
    121.     }  
    122.   
    123.     catch (final IOException e)  
    124.     {  
    125.       LOG.warning(e.getMessage());  
    126.     }  
    127.   
    128.     finally  
    129.     {  
    130.       post.releaseConnection();  
    131.     }  
    132.   
    133.     return null;  
    134.   }  
    135.   
    136.   private static void notNull(final Object object, final String message)  
    137.   {  
    138.     if (object == null)  
    139.       throw new IllegalArgumentException(message);  
    140.   }  
    141.   
    142.   public static void main(final String[] args)  
    143.   {  
    144.     final String server = "http://192.168.41.107:8080/member/v1/tickets";  
    145.     final String username = "admin";  
    146.     final String password = "111111";  
    147.     final String service = "http://localhost:8080/service";  
    148.   
    149.     LOG.info(getTicket(server, username, password, service));  
    150.   }  
    151. }  

       参考:https://wiki.jasig.org/display/CASUM/RESTful+API
     
  • 相关阅读:
    【字符编码】Java编码格式探秘
    【集合框架】JDK1.8源码分析之Collections && Arrays(十)
    【面试】shuffle函数的实现
    关于Jquery中ajax方法data参数用法的总结
    关于BootStrap下图标的显示问题
    dajngo权限管理
    Django下TemplateDoesNotExist 异常的解决方法:
    ubuntu安装有道
    python manage.py shell之后的一些错误:
    fat32转ntfs ,Win7系统提示对于目标文件系统文件过大解决教程
  • 原文地址:https://www.cnblogs.com/AloneSword/p/3321780.html
Copyright © 2020-2023  润新知