由于工作上的要求所以一直在寻找一些符合要求的集成方法,虽然不是自己发现的,但是有些问题经过研究更正。

1、配置web.xml
由于CAS的一个子系统Logout以后其他子系统并没有同步退出,所以这里面加入了,cas官方的集成监听器和过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>Struts Blank</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:spring-mvc.xml
        </param-value>
  </context-param>
  <servlet>
    <servlet-name>UploadHandleServlet</servlet-name>
    <servlet-class>me.gacl.web.controller.UploadHandleServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UploadHandleServlet</servlet-name>
    <url-pattern>/servlet/UploadHandleServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
</web-app>

2、cas_client的pom.xml文件

        <!-- buji pac4j-->
        <dependency>
<groupId>io.buji</groupId>
<artifactId>buji-pac4j</artifactId>
<version>${bujiVersion}</version>
</dependency>
        
        <!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
<exclusions>
<exclusion>
<artifactId>ehcache-core</artifactId>
<groupId>net.sf.ehcache</groupId>
</exclusion>
</exclusions>
</dependency>
        <!-- CAS -->
       <dependency>
            <groupId>org.jasig.cas.client</groupId>
            <artifactId>cas-client-core</artifactId>
            <version>3.5.1</version>
        </dependency>

3、集成重写DefaultCasLogoutHandler和Pac4jRealm两个类
①DefaultCasLogoutHandler

package com.mongodb.util;

import org.pac4j.cas.logout.DefaultCasLogoutHandler;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.context.session.SessionStore;
import org.pac4j.core.store.Store;

import io.buji.pac4j.profile.ShiroProfileManager;

public class ShiroCasLogoutHandler<C extends WebContext> extends DefaultCasLogoutHandler<C> {

public ShiroCasLogoutHandler() {
    }

    public ShiroCasLogoutHandler(final Store<String, Object> store) {
        super(store);
    }

    protected void destroy(final C context, final SessionStore sessionStore, final String channel) {
        // remove profiles
        final ShiroProfileManager manager = new ShiroProfileManager(context);
        manager.logout();
        logger.debug("destroy the user profiles");
        // and optionally the web session
        if (isDestroySession()) {
            logger.debug("destroy the whole session");
            final boolean invalidated = sessionStore.destroySession(context);
            if (!invalidated) {
                logger.error("The session has not been invalidated for {} channel logout", channel);
            }
        }
    }
}

②Pac4jRealm

package com.mongodb.util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.bson.Document;
import org.pac4j.core.profile.CommonProfile;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.buji.pac4j.realm.Pac4jRealm;
import io.buji.pac4j.subject.Pac4jPrincipal;
import io.buji.pac4j.token.Pac4jToken;

public class ShiroCASPac4jRealm extends Pac4jRealm {
    //该方法可以获取到cas服务端的多属性返回的属性
@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        final Pac4jToken token = (Pac4jToken) authenticationToken;
        final List<CommonProfile> profiles = token.getProfiles();

        final Pac4jPrincipal principal = new Pac4jPrincipal(profiles, getPrincipalNameAttribute());
        final PrincipalCollection principalCollection = new SimplePrincipalCollection(principal, getName());
        
        String loginName = principal.getProfile().getId(); 
        Session session = SecurityUtils.getSubject().getSession(true);
session.setAttribute("user", loginName);
        return new SimpleAuthenticationInfo(principalCollection, profiles.hashCode());
    }


@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
      
//获取当前登录输入的用户名,等价于(String) principalCollection.fromRealm(getName()).iterator().next(); 
        Session session = SecurityUtils.getSubject().getSession(); 
        //  Account user = Account.class.cast(session.getAttribute(Const.SESSION_USER));

        final SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(new ArrayList<String>());
        return simpleAuthorizationInfo;
}
}

4、配置shiro-pac4j.properties

##cas服务前缀
sso.cas.server.prefixUrl=http://服务端URL/cas/
##cas服务登录url
sso.cas.server.loginUrl=http://服务端URL/cas/login
##cas客户端回调地址
sso.cas.client.callbackUrl=http://客户端URL/casClient/callback?client_name=msrRim
##cas服务端成功跳转地址
sso.cas.client.successUrl=http://客户端URL/casClient/user2/showshiti
##登出后地址
sso.cas.client.logoutUrl=http://服务端URL/cas/login

5、配置shiro-cas-pac4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:repository="http://www.springframework.org/schema/data/repository"
xmlns:stat="http://www.alibaba.com/schema/stat"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-4.3.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-2.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository-2.1.xsd
http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd">

<!-- Session和Cookie -->
<bean id="sessionIdGenerator"
class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" />
<bean id="sessionIdCookie"
class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sssid" />
<property name="httpOnly" value="false" />
<property name="maxAge" value="1800" />
<property name="path" value="/" />
</bean>
<bean id="sessionDAO"
class="org.apache.shiro.session.mgt.eis.MemorySessionDAO">
<property name="sessionIdGenerator" ref="sessionIdGenerator" />
</bean>
<bean id="sessionValidationScheduler"
class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
<property name="interval" value="1800000" />
</bean>
<!-- Realm -->
<bean id="Pac4jRealm" class="com.mongodb.util.ShiroCASPac4jRealm">
<property name="cachingEnabled" value="false" />
<property name="authenticationCachingEnabled" value="false" />
<property name="authenticationCacheName"
value="authenticationCache" />
<property name="authorizationCachingEnabled" value="false" />
<property name="authorizationCacheName"
value="authorizationCache" />
</bean>
<!-- 可配置多个Realm -->
<bean id="authenticator"
class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="realms">
<list>
<ref bean="Pac4jRealm" />
</list>
</property>
<property name="authenticationStrategy">
<bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"></bean>
</property>
</bean>
<!-- 基于pac4j的Subject工厂 -->
<bean id="pac4jSubjectFactory"
class="io.buji.pac4j.subject.Pac4jSubjectFactory"></bean>
<!-- 安全管理器 -->
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="authenticator" ref="authenticator"></property>
<property name="subjectFactory" ref="pac4jSubjectFactory"></property>
</bean>


<!-- cas服务端 -->
<bean id="casLogoutHandler"
class="com.mongodb.util.ShiroCasLogoutHandler">
<property name="destroySession" value="true"></property>
</bean>
<bean id="casConfig" class="org.pac4j.cas.config.CasConfiguration">
<!-- CAS server登录链接 -->
<property name="loginUrl" value="${sso.cas.server.loginUrl}"></property>
<!-- CAS server服务前缀 -->
<property name="prefixUrl"
value="${sso.cas.server.prefixUrl}"></property>
<!-- 登出处理器,单点登出时所需要的操作在这里实现 -->
<property name="logoutHandler" ref="casLogoutHandler"></property>
</bean>
<!-- 配置cas客户端 -->
<bean id="msrRim" class="org.pac4j.cas.client.CasClient">
<property name="name" value="msrRim"></property>
<constructor-arg ref="casConfig" />
<!-- 客户端回调地址 -->
<property name="callbackUrl"
value="${sso.cas.client.callbackUrl}"></property>
</bean>
<!-- pac4j配置 -->
<bean id="sessionStore"
class="io.buji.pac4j.context.ShiroSessionStore"></bean>
<bean id="authcConfig" class="org.pac4j.core.config.Config">
<constructor-arg ref="msrRim"></constructor-arg>
<property name="sessionStore" ref="sessionStore"></property>
</bean>

<!-- Shiro Filter, 在web.xml中被部署 -->
<bean id="shiroFilter"
class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="filters">
<util:map>
<!-- 配置SecurityFilter,用于拦截受保护的url -->
<entry key="casSecurityFilter">
<bean class="io.buji.pac4j.filter.SecurityFilter">
<property name="config" ref="authcConfig"></property>
<property name="clients" value="msrRim"></property>
</bean>
</entry>
<!-- 回调过滤器,完成ticket认证 -->
<entry key="callback">
<bean class="io.buji.pac4j.filter.CallbackFilter">
<property name="config" ref="authcConfig"></property>
<property name="defaultUrl" value="${sso.cas.client.successUrl}"></property>
</bean>
</entry>
<!-- 登出过滤器 -->
<entry key="logout">
<bean id="logout" class="io.buji.pac4j.filter.LogoutFilter">
<property name="defaultUrl" value="${sso.cas.client.logoutUrl}"></property>
<property name="config" ref="authcConfig"></property>
<property name="centralLogout" value="true"></property>
<property name="localLogout" value="false"></property>
</bean>
</entry>
</util:map>
</property>

<property name="filterChainDefinitions">
<value>
/index =  casSecurityFilter
/callback = callback
/static/** = anon
/logout = logout
/** = authc
</value>
</property>
</bean>

<!-- 生命周期处理 -->
<bean id="lifecycleBeanPostProcessor"
class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

<bean id="annotationProxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
</beans>