SSO单点登录基于CAS架构封装 Memcached 实例

Easter79
• 阅读 463

SSO认证中心是CAS整个应用架构的一个极其重要的关键点,必须满足如下两点要求: 1.高可用,不允许程序发生故障。如果认证中心发生故障,整个应用群将无法登录,导致所有服务瘫痪。 2.高并发,因为所有用户的登录请求都需要经过它处理,其承担的处理量往往是相当巨大的。

其中memcached的CAS源码 MemCacheTicketRegistry.java 类如下: /*

  • Licensed to Jasig under one or more contributor license

  • agreements. See the NOTICE file distributed with this work

  • for additional information regarding copyright ownership.

  • Jasig licenses this file to you under the Apache License,

  • Version 2.0 (the "License"); you may not use this file

  • except in compliance with the License. You may obtain a

  • copy of the License at the following location:

  • http://www.apache.org/licenses/LICENSE-2.0

  • Unless required by applicable law or agreed to in writing,

  • software distributed under the License is distributed on an

  • "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

  • KIND, either express or implied. See the License for the

  • specific language governing permissions and limitations

  • under the License. / package org.jasig.cas.ticket.registry; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import net.spy.memcached.AddrUtil; import net.spy.memcached.MemcachedClient; import net.spy.memcached.MemcachedClientIF; import org.jasig.cas.ticket.ServiceTicket; import org.jasig.cas.ticket.Ticket; import org.jasig.cas.ticket.TicketGrantingTicket; import org.springframework.beans.factory.DisposableBean; /*

  • Key-value ticket registry implementation that stores tickets in memcached keyed on the ticket ID.

  • @author Scott Battaglia

  • @author Marvin S. Addison

  • @since 3.3 / public final class MemCacheTicketRegistry extends AbstractDistributedTicketRegistry implements DisposableBean { /* Memcached client. / @NotNull private final MemcachedClientIF client; /*

    • TGT cache entry timeout in seconds. / @Min(0) private final int tgtTimeout; /*

    • ST cache entry timeout in seconds. / @Min(0) private final int stTimeout; /*

    • Creates a new instance that stores tickets in the given memcached hosts.

    • @param hostnames Array of memcached hosts where each element is of the form host:port.

    • @param ticketGrantingTicketTimeOut TGT timeout in seconds.

    • @param serviceTicketTimeOut ST timeout in seconds. / public MemCacheTicketRegistry(final String[] hostnames, final int ticketGrantingTicketTimeOut, final int serviceTicketTimeOut) { try { this.client = new MemcachedClient(AddrUtil.getAddresses(Arrays.asList(hostnames))); } catch (final IOException e) { throw new IllegalArgumentException("Invalid memcached host specification.", e); } this.tgtTimeout = ticketGrantingTicketTimeOut; this.stTimeout = serviceTicketTimeOut; } /*

    • This alternative constructor takes time in milliseconds.

    • It has the timeout parameters in order to create a unique method signature.

    • @param ticketGrantingTicketTimeOut TGT timeout in milliseconds.

    • @param serviceTicketTimeOut ST timeout in milliseconds.

    • @param hostnames Array of memcached hosts where each element is of the form host:port.

    • @see MemCacheTicketRegistry#MemCacheTicketRegistry(String[], int, int)

    • @deprecated This has been deprecated / @Deprecated public MemCacheTicketRegistry(final long ticketGrantingTicketTimeOut, final long serviceTicketTimeOut, final String[] hostnames) { this(hostnames, (int) (ticketGrantingTicketTimeOut / 1000), (int) (serviceTicketTimeOut / 1000)); } /*

    • Creates a new instance using the given memcached client instance, which is presumably configured via

    • net.spy.memcached.spring.MemcachedClientFactoryBean.

    • @param client Memcached client.

    • @param ticketGrantingTicketTimeOut TGT timeout in seconds.

    • @param serviceTicketTimeOut ST timeout in seconds. / public MemCacheTicketRegistry(final MemcachedClientIF client, final int ticketGrantingTicketTimeOut, final int serviceTicketTimeOut) { this.tgtTimeout = ticketGrantingTicketTimeOut; this.stTimeout = serviceTicketTimeOut; this.client = client; } public String getHostnames() { return hostnames; } public void setHostnames(String hostnames) { this.hostnames = hostnames; } public int getTgtTimeout() { return tgtTimeout; } public int getStTimeout() { return stTimeout; } protected void updateTicket(final Ticket ticket) { logger.debug("Updating ticket {}", ticket); try { if (!this.client.replace(ticket.getId(), getTimeout(ticket), ticket).get()) { logger.error("Failed updating {}", ticket); } } catch (final InterruptedException e) { logger.warn("Interrupted while waiting for response to async replace operation for ticket {}. " + "Cannot determine whether update was successful.", ticket); } catch (final Exception e) { logger.error("Failed updating {}", ticket, e); } } public void addTicket(final Ticket ticket) { logger.debug("Adding ticket {}", ticket); try { if (!this.client.add(ticket.getId(), getTimeout(ticket), ticket).get()) { logger.error("Failed adding {}", ticket); } } catch (final InterruptedException e) { logger.warn("Interrupted while waiting for response to async add operation for ticket {}." + "Cannot determine whether add was successful.", ticket); } catch (final Exception e) { logger.error("Failed adding {}", ticket, e); } } public boolean deleteTicket(final String ticketId) { logger.debug("Deleting ticket {}", ticketId); try { return this.client.delete(ticketId).get(); } catch (final Exception e) { logger.error("Failed deleting {}", ticketId, e); } return false; } public Ticket getTicket(final String ticketId) { try { final Ticket t = (Ticket) this.client.get(ticketId); if (t != null) { return getProxiedTicketInstance(t); } } catch (final Exception e) { logger.error("Failed fetching {} ", ticketId, e); } return null; } /*

    • {@inheritDoc}

    • This operation is not supported.

    • @throws UnsupportedOperationException if you try and call this operation. / @Override public Collection getTickets() { throw new UnsupportedOperationException("GetTickets not supported."); } public void destroy() throws Exception { this.client.shutdown(); } /*

    • @param sync set to true, if updates to registry are to be synchronized

    • @deprecated As of version 3.5, this operation has no effect since async writes can cause registry consistency issues. */ @Deprecated public void setSynchronizeUpdatesToRegistry(final boolean sync) {} @Override protected boolean needsCallback() { return true; } private int getTimeout(final Ticket t) { if (t instanceof TicketGrantingTicket) { return this.tgtTimeout; } else if (t instanceof ServiceTicket) { return this.stTimeout; } throw new IllegalArgumentException("Invalid ticket type"); } }

将其 MemCacheTicketRegistry.java 类改为如下代码: /*

  • Licensed to Jasig under one or more contributor license

  • agreements. See the NOTICE file distributed with this work

  • for additional information regarding copyright ownership.

  • Jasig licenses this file to you under the Apache License,

  • Version 2.0 (the "License"); you may not use this file

  • except in compliance with the License. You may obtain a

  • copy of the License at the following location:

  • http://www.apache.org/licenses/LICENSE-2.0

  • Unless required by applicable law or agreed to in writing,

  • software distributed under the License is distributed on an

  • "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

  • KIND, either express or implied. See the License for the

  • specific language governing permissions and limitations

  • under the License. / package org.jasig.cas.ticket.registry; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import net.spy.memcached.AddrUtil; import net.spy.memcached.MemcachedClient; import net.spy.memcached.MemcachedClientIF; import org.jasig.cas.ticket.ServiceTicket; import org.jasig.cas.ticket.Ticket; import org.jasig.cas.ticket.TicketGrantingTicket; import org.springframework.beans.factory.DisposableBean; /*

  • Key-value ticket registry implementation that stores tickets in memcached keyed on the ticket ID.

  • @author Scott Battaglia

  • @author Marvin S. Addison

  • @since 3.3 / public final class MemCacheTicketRegistry extends AbstractDistributedTicketRegistry implements DisposableBean { /* Memcached client. / @NotNull private final MemcachedClientIF client = getClient(); /*

    • TGT cache entry timeout in seconds. / @Min(0) private int tgtTimeout; /*
    • ST cache entry timeout in seconds. */ @Min(0) private int stTimeout;

    private String hostname;

    public MemcachedClient getClient(){ try { return new MemcachedClient(AddrUtil.getAddresses(Arrays.asList(hostname))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } protected void updateTicket(final Ticket ticket) { logger.debug("Updating ticket {}", ticket); try { if (!this.client.replace(ticket.getId(), getTimeout(ticket), ticket).get()) { logger.error("Failed updating {}", ticket); } } catch (final InterruptedException e) { logger.warn("Interrupted while waiting for response to async replace operation for ticket {}. " + "Cannot determine whether update was successful.", ticket); } catch (final Exception e) { logger.error("Failed updating {}", ticket, e); } } public void addTicket(final Ticket ticket) { logger.debug("Adding ticket {}", ticket); try { if (!this.client.add(ticket.getId(), getTimeout(ticket), ticket).get()) { logger.error("Failed adding {}", ticket); } } catch (final InterruptedException e) { logger.warn("Interrupted while waiting for response to async add operation for ticket {}." + "Cannot determine whether add was successful.", ticket); } catch (final Exception e) { logger.error("Failed adding {}", ticket, e); } } public boolean deleteTicket(final String ticketId) { logger.debug("Deleting ticket {}", ticketId); try { return this.client.delete(ticketId).get(); } catch (final Exception e) { logger.error("Failed deleting {}", ticketId, e); } return false; } public Ticket getTicket(final String ticketId) { try { final Ticket t = (Ticket) this.client.get(ticketId); if (t != null) { return getProxiedTicketInstance(t); } } catch (final Exception e) { logger.error("Failed fetching {} ", ticketId, e); } return null; } /**

    • {@inheritDoc}

    • This operation is not supported.

    • @throws UnsupportedOperationException if you try and call this operation. / @Override public Collection getTickets() { throw new UnsupportedOperationException("GetTickets not supported."); } public void destroy() throws Exception { this.client.shutdown(); } /*

    • @param sync set to true, if updates to registry are to be synchronized

    • @deprecated As of version 3.5, this operation has no effect since async writes can cause registry consistency issues. */ @Deprecated public void setSynchronizeUpdatesToRegistry(final boolean sync) {} @Override protected boolean needsCallback() { return true; } private int getTimeout(final Ticket t) { if (t instanceof TicketGrantingTicket) { return this.tgtTimeout; } else if (t instanceof ServiceTicket) { return this.stTimeout; } throw new IllegalArgumentException("Invalid ticket type"); } public int getTgtTimeout() { return tgtTimeout; } public void setTgtTimeout(int tgtTimeout) { this.tgtTimeout = tgtTimeout; } public int getStTimeout() { return stTimeout; } public void setStTimeout(int stTimeout) { this.stTimeout = stTimeout; } public String getHostname() { return hostname; } public void setHostname(String hostname) { this.hostname = hostname; }

} cas单点登录架构 ticket 票据存储方式为 memcached(单节点配置memcached满足cas存储票据),具体ticketRegistry.xml配置如下: 修改cas-server-webapp工程中ticketRegistry.xml文件 内容不全,网站 素文宅 http://www.yoodb.com/article/display/1168

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
2年前
SSO单点登录基于CAS架构封装 Memcached 实例
SSO认证中心是CAS整个应用架构的一个极其重要的关键点,必须满足如下两点要求:1.高可用,不允许程序发生故障。如果认证中心发生故障,整个应用群将无法登录,导致所有服务瘫痪。2.高并发,因为所有用户的登录请求都需要经过它处理,其承担的处理量往往是相当巨大的。其中memcached的CAS源码MemCacheTicketRegistry.java类
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k