因爲項目需求要實現單點登出須要在網上找了N久終於實現單點登出。php
使用cas-server-core-3.3.3.jar(CAS Server 3.3.3)html
使用cas-client-core-3.1.3.jar(CAS Client 3.1.3)java
項目結合CAS SpringSecurity SSHweb
普通項目(沒有結合Spring Security)的能夠在web.xml中加入以下代碼spring
- <filter>
- <filter-name>CAS Single Sign Out Filter</filter-name>
- <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
- </filter>
-
- <filter-mapping>
- <filter-name>CAS Single Sign Out Filter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <listener>
- <listener-class>
- org.jasig.cas.client.session.SingleSignOutHttpSessionListener
- </listener-class>
- </listener>
在咱們的項目中因爲結合了SpringSecurity 能夠將filter加入到spring Security過濾鏈中,也能夠直接向上面的同樣加入web.xml中apache
首先在web.xml中加入監聽器。服務器
- <listener>
- <listener-class>
- org.jasig.cas.client.session.SingleSignOutHttpSessionListener
- </listener-class>
- </listener>
而後把filter加入到spring Security過濾鏈中session
- <b:bean id="casSingleSignOutFilter" class="check.SingleSignOutFilter">
- <custom-filter before="CAS_PROCESSING_FILTER"/>
- </b:bean>
注意上面的class="check.SingleSignOutFilter"是我自定義的filter(因爲CAS3.1.3定義的SingleSignOutFilter在某種意思上沒有起到做用)詳情請見http://www.javaeye.com/topic/546785app
本身定義一個類oop
- package check;
-
- import java.io.IOException;
- import java.util.Enumeration;
-
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpSession;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.jasig.cas.client.session.HashMapBackedSessionMappingStorage;
- import org.jasig.cas.client.session.SessionMappingStorage;
- import org.jasig.cas.client.util.AbstractConfigurationFilter;
- import org.jasig.cas.client.util.CommonUtils;
- import org.jasig.cas.client.util.XmlUtils;
-
- public final class SingleSignOutFilter extends AbstractConfigurationFilter
- {
- private String artifactParameterName;
- private static SessionMappingStorage SESSION_MAPPING_STORAGE = new HashMapBackedSessionMappingStorage();
- private static Log log = LogFactory.getLog(SingleSignOutFilter.class);
-
- public SingleSignOutFilter()
- {
- this.artifactParameterName = "ticket";
- }
-
- public void init(FilterConfig filterConfig)
- throws ServletException
- {
- setArtifactParameterName(getPropertyFromInitParams(filterConfig, "artifactParameterName", "ticket"));
- init();
- }
-
- public void init() {
- CommonUtils.assertNotNull(this.artifactParameterName, "artifactParameterName cannot be null.");
- CommonUtils.assertNotNull(SESSION_MAPPING_STORAGE, "sessionMappingStorage cannote be null.");
- }
-
- public void setArtifactParameterName(String artifactParameterName) {
- this.artifactParameterName = artifactParameterName;
- }
-
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- final HttpServletRequest request = (HttpServletRequest) servletRequest;
- final String logoutRequest = CommonUtils.safeGetParameter(request, "logoutRequest");
- Enumeration ff = request.getParameterNames();
- String a = request.getQueryString();
- if (CommonUtils.isNotBlank(logoutRequest)) {
- final String sessionIdentifier = XmlUtils.getTextForElement(logoutRequest, "SessionIndex");
-
- if (CommonUtils.isNotBlank(sessionIdentifier)) {
- final HttpSession session = SESSION_MAPPING_STORAGE.removeSessionByMappingId(sessionIdentifier);
-
- if (session != null) {
- String sessionID = session.getId();
- try {
- session.invalidate();
- } catch (final IllegalStateException e) {
-
- }
- }
- }
- }
-
- else{
- final String artifact = CommonUtils.safeGetParameter(request, this.artifactParameterName);
- final HttpSession session = request.getSession(false);
-
- if (CommonUtils.isNotBlank(artifact) && session!=null) {
- try {
- SESSION_MAPPING_STORAGE.removeBySessionById(session.getId());
- } catch (final Exception e) {
-
- }
- SESSION_MAPPING_STORAGE.addSessionById(artifact, session);
- }
- }
-
- filterChain.doFilter(servletRequest, servletResponse);
- }
-
- public void setSessionMappingStorage(SessionMappingStorage storage) {
- SESSION_MAPPING_STORAGE = storage;
- }
-
- public static SessionMappingStorage getSessionMappingStorage() {
- return SESSION_MAPPING_STORAGE;
- }
-
- public void destroy()
- {
- }
- }
完成。
這樣便可實現單點登出。(全部java應用的單點退出)
1)這樣實現的效果是在登出的時候CAS Server 分發給各個客戶端讓各個客戶端都登出,這個得讓FIlter來獲取,例子:一個index頁面有兩個連接一個指向java應用,一個指向php應用在 java應用加filter 後能作出相應的動做退出動做,而對於php本身沒加任何filter就沒有退出。因此也得寫個filter。
2)因爲咱們點擊退出的時候請求CAS Server 然後Server分發任務讓每一個應用退出的消息,java程序經過filter來執行退出。PHP提供了一個phpCAS::handleLogoutRequests()來檢驗服務器發來的信息,
具體咱們能夠把這個代碼放在phpbb3/include/function.php中的點擊事件裏面代碼以下:
- if(!$admin && CAS_ENABLE){
-
- phpCAS::client(CAS_VERSION_2_0, CAS_SERVER_HOSTNAME, CAS_SERVER_PORT, CAS_SERVER_APP_NAME);
- phpCAS::setNoCasServerValidation();
-
- phpCAS::handleLogoutRequests();
- phpCAS::forceAuthentication();
原文出自:http://blog.csdn.net/lishuangzhe7047/article/details/38587151