Redis-based CAS Cluster

Source: Internet
Author: User

Single Sign-On (SSO) is a basic requirement for complex application systems. Yale CAS is a common open source solution. CAS Certification Center, based on its special functions, will naturally become the core of the entire application system. All application system authentication work will be requested to CAS for completion. Therefore, the CAS server is the key node of the entire application. If CAS fails, all systems will be paralyzed. At the same time, CAS must have sufficient load capacity to respond to all authentication requests. Using Server Load balancer and cluster technology, CAs can not only overcome single point of failure (spof), but also distribute authentication requests to multiple CAS servers, effectively reducing the request pressure on a single CAS server. The following will be based on cas
3.4.5 to discuss CAS clusters.

The working principle of CAS is mainly implemented based on the ticket (ticket) (refer to the basic principles of CAS ). CAS tickets are stored in the ticketregistry. Therefore, to implement CAS cluster, multiple CAS must share all the ticket and use the unified ticketregistry. In the default CAS implementation, ticketregistry is implemented in the memory. Different CAS servers have their own separate ticketregistry. Therefore, distributed clusters are not supported. However, CAS provides a distributed ticketregistry-supported interface org. JASIG. Cas. Ticket. Registry. abstractdistributedticketregistry. We can implement this interface to share multiple CAS servers with ticketregistry to implement CAS clusters.

In addition, compared with the new CAS version, springwebflow is used as the authentication process, while webflow uses session to store process-related information. Therefore, to implement CAS clusters, we need to share sessions of different servers.

We use the memory database redis to implement ticketregistry, so that multiple CAS servers share the same ticketregistry. In the same way, we store sessions in redis to share sessions. The following describes how to use redis to implement ticketregistry. We use Java to call the Jedis interface to operate redis. The Code is as follows:

 

[HTML]
View plaincopy
  1. Import java. Io. bytearrayinputstream;
  2. Import java. Io. bytearrayoutputstream;
  3. Import java. Io. objectinputstream;
  4. Import java. Io. objectoutputstream;
  5. Import java. util. collection;
  6. Import org. JASIG. Cas. Ticket. ticket;
  7. Import org. JASIG. Cas. Ticket. ticketgrantingticket;
  8. Import org. JASIG. Cas. Ticket. Registry. abstractdistributedticketregistry;
  9. Import redis. Clients. Jedis. Jedis;
  10. Import redis. Clients. Jedis. jedispool;
  11. Import redis. Clients. Jedis. jedispoolconfig;
  12. /*
  13. * Ticketregistry using redis, to solve CAS cluster.
  14. *
  15. * @ Author ZL
  16. *
  17. */
  18. Public class redisticketregistry extends actdistributedticketregistry {
  19. Private Static int redisdatabasenum;
  20. Private Static string hosts;
  21. Private Static int port;
  22. Private Static int st_time; // st maximum idle time
  23. Private Static int tgt_time; // maximum idle time of TGT
  24. Private Static jedispool cachepool;
  25. Static {
  26. Redisdatabasenum = propertiesconfigutil. getpropertyint ("redis_database_num ");
  27. Hosts = propertiesconfigutil. getproperty ("hosts ");
  28. Port = propertiesconfigutil. getpropertyint ("Port ");
  29. St_time = propertiesconfigutil. getpropertyint ("st_time ");
  30. Tgt_time = propertiesconfigutil. getpropertyint ("tgt_time ");
  31. Cachepool = new jedispool (New jedispoolconfig (), hosts, Port );
  32. }
  33. Public void addticket (Ticket ){
  34. Jedis = cachepool. getresource ();
  35. Jedis. Select (redisdatabasenum );
  36. Int seconds = 0;
  37. String key = ticket. GETID ();
  38. If (ticket instanceof ticketgrantingticket ){
  39. // Key = (ticketgrantingticket) Ticket). getauthentication (). getprincipal (). GETID ();
  40. Seconds = tgt_time/1000;
  41. } Else {
  42. Second = st_time/1000;
  43. }
  44. Bytearrayoutputstream Bos = new bytearrayoutputstream ();
  45. Objectoutputstream OOS = NULL;
  46. Try {
  47. Oos = new objectoutputstream (BOS );
  48. Oos. writeobject (ticket );
  49. } Catch (exception e ){
  50. Log. Error ("adding ticket to redis error .");
  51. } Finally {
  52. Try {
  53. If (null! = OOS) OOS. Close ();
  54. } Catch (exception e ){
  55. Log. Error ("Oos closing error when adding ticket to redis .");
  56. }
  57. }
  58. Jedis. Set (key. getbytes (), Bos. tobytearray ());
  59. Jedis. expire (key. getbytes (), seconds );
  60. Cachepool. returnresource (Jedis );
  61. }
  62. Public ticket getticket (final string ticketid ){
  63. Return getproxiedticketinstance (getrawticket (ticketid ));
  64. }
  65. Private ticket getrawticket (final string ticketid ){
  66. If (null = ticketid) return NULL;
  67. Jedis = cachepool. getresource ();
  68. Jedis. Select (redisdatabasenum );
  69. Ticket = NULL;
  70. Bytearrayinputstream BAIS = new bytearrayinputstream (Jedis. Get (ticketid. getbytes ()));
  71. Objectinputstream OIS = NULL;
  72. Try {
  73. Ois = new objectinputstream (BAIS );
  74. Ticket = (ticket) Ois. readobject ();
  75. } Catch (exception e ){
  76. Log. Error ("getting ticket to redis error .");
  77. } Finally {
  78. Try {
  79. If (null! = OIS) Ois. Close ();
  80. } Catch (exception e ){
  81. Log. Error ("OIS closing error when getting ticket to redis .");
  82. }
  83. }
  84. Cachepool. returnresource (Jedis );
  85. Return ticket;
  86. }
  87. Public Boolean deleteticket (final string ticketid ){
  88. If (ticketid = NULL ){
  89. Return false;
  90. }
  91. Jedis = cachepool. getresource ();
  92. Jedis. Select (redisdatabasenum );
  93. Jedis. Del (ticketid. getbytes ());
  94. Cachepool. returnresource (Jedis );
  95. Return true;
  96. }
  97. Public Collection <ticket> gettickets (){
  98. Throw new unsupportedoperationexception ("gettickets not supported .");
  99. }
  100. Protected Boolean needscallback (){
  101. Return false;
  102. }
  103. Protected void updateticket (final Ticket ){
  104. Addticket (ticket );
  105. }
  106. }

In the ticketregistry. xml configuration file, we specify the ticketregistry implementation class as the preceding implementation. Modify the following class values.

[HTML]
View plaincopy
  1. <! -- Ticket registry -->
  2. <Bean id = "ticketregistry" class = "org. JASIG. Cas. util. redisticketregistry"/>
  3. <! -- <Bean id = "ticketregistry" class = "org. JASIG. Cas. Ticket. Registry. defaultticketregistry"/>
  4. -->

Because the expire function of redis is used, comment out the following code:

[HTML]
View plaincopy
  1. <! -- Ticket registry cleaner -->
  2. Lt ;! -- <Bean id = "ticketregistrycleaner" class = "org. JASIG. Cas. Ticket. Registry. Support. defaultticketregistrycleaner"
  3. P: ticketregistry-ref = "ticketregistry"/>
  4. <Bean id = "jobdetailticketregistrycleaner" class = "org. springframework. Scheduling. Quartz. methodinvokingjobdetailfactorybean"
  5. P: targetobject-ref = "ticketregistrycleaner"
  6. P: targetmethod = "clean"/>
  7. <Bean id = "triggerjobdetailticketregistrycleaner" class = "org. springframework. Scheduling. Quartz. simpletriggerbean"
  8. P: jobdetail-ref = "jobdetailticketregistrycleaner"
  9. P: startdelay= "20000"
  10. P: repeatinterval = "5000000" type = "codeph" text = "/codeph"/> -->

With the preceding Implementation of ticketregistry, multiple CAS servers can share the same ticketregistry. For how to share sessions, we can directly integrate them using the ready-made third-party tool tomcat-redis-session-manager. Configure Server Load balancer for front-end web servers (such as nginx) and forward the authentication request distribution to the following CAS servers to achieve load balancing and fault tolerance.

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.