本文简单实现在spring框架下对apache shiro与jasig-cas 整合 实现单点登录多点注销统一权限管理平台,功能简单,主要大致讲讲入门配置。
一、环境:
1、后台框架:spring3.2+struts2+hibernate4+apache-shiro1.2.1+jasig-cas3.4.1(具体相关依赖包请自行上官网下载);
2、数据库:mysql5.x;
3、servlet容器:tomcat6;
二、首先CAS服务器搭建
1、官网下载cassever包,解压后将modules文件夹里的 cas-server-webapp-*.war 复制到 tomcat webapps文件夹下;
2、启动tomcat,输入相同的用户名和密码登录,将提示登录成功,这个cas默认的认证方式,刷新页面将回到登录页面;
3、修改cas默认的认证方式: 做web开发,我们一般用数据库用户密码方式认证:
a、修改web-inf下的deployerConfigContext.xml,注释掉默认的验证:
- <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
- <bean id="casdataSource" name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" >
- <value>com.mysql.jdbc.Driver</value>
- </property>
- <property name="url">
- <value><![CDATA[jdbc:mysql://localhost:3306/cas?useUnicode=true&characterEncoding=UTF-8]]></value>
- </property>
- <property name="username" >
- <value>root</value>
- </property>
- <property name="password" >
- <value>root</value>
- </property>
- </bean>
- <bean id="QueryDatabaseAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
- <property name="dataSource" ref="casdataSource"></property>
- <property name="sql" value="select USER_PWD from T_USER where USER_NAME=?"></property>
- </bean>
a、修改deployerConfigContext.xml,
- <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
- p:httpClient-ref="httpClient" p:requireSecure="false"/><!-- require 属性为true 开启ssl -->
- <bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
- p:cookieSecure="false"
- p:cookieMaxAge="-1"
- p:cookieName="CASTGC"
- p:cookiePath="/cas" />
- <!-- 使用http协议: cookieSecure 为false -->
- </beans>
以上,完成使用jdb数据源http协议的简单cas server端配置,可以启动tomcat 输入地址查看,这时候认证将需要与数据库里的用户信息匹配还能认证成功!
三、客户端client1配置
client1 相关其他配置就不详讲了,主要讲述spring与shiro与cas的相关配置
1、首先引入客户端所需jar包:spring相关jar包,shiro jar包,cas client jar包(下载cas client modules 下会有cas-client-core-.jar)
2、web.xml 相关配置
加载相关配置文件与监听
- <context-param>
- <description>相关配置文件加载</description>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:spring*.xml</param-value>
- </context-param>
- <!-- 相关监听加载 -->
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <listener>
- <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
- </listener>
- <listener>
- <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
- </listener>
- <listener>
- <listener-class>com.areo.kongtan.listener.SessionListenerHandler</listener-class>
- </listener>
- <filter>
- <description>
- shrio权限过滤,DelegatingFilterProxy 作用是自动到 spring 容器查找名字为 shiroFilter(filter-name)的 bean并把所有 Filter 的操作委托给它
- </description>
- <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>
- </filter-mapping>
以上完成client端的web配置 下一篇讲client端spring整合相关配置
spring相关主要配置文件
1、位于classpath路径下的spring-shirocas-web.xml
- <!-- 缓存管理器 ehcache 的配置 -->
- <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
- </bean>
ehcache.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <ehcache name="shirocache">
- <diskStore path="java.io.tmpdir"/>
- <!-- 登录记录缓存 锁定10分钟 -->
- <cache name="passwordRetryCache"
- maxEntriesLocalHeap="2000"
- eternal="false"
- timeToIdleSeconds="3600"
- timeToLiveSeconds="0"
- overflowToDisk="false"
- statistics="true">
- </cache>
- <cache name="authorizationCache"
- maxEntriesLocalHeap="2000"
- eternal="false"
- timeToIdleSeconds="3600"
- timeToLiveSeconds="0"
- overflowToDisk="false"
- statistics="true">
- </cache>
- <cache name="authenticationCache"
- maxEntriesLocalHeap="2000"
- eternal="false"
- timeToIdleSeconds="3600"
- timeToLiveSeconds="0"
- overflowToDisk="false"
- statistics="true">
- </cache>
- <cache name="shiro-activeSessionCache"
- maxEntriesLocalHeap="2000"
- eternal="false"
- timeToIdleSeconds="3600"
- timeToLiveSeconds="0"
- overflowToDisk="false"
- statistics="true">
- </cache>
- </ehcache>
- bean id="casRealm" class="com.test.client1.shiro.MyCasRealm">
- <property name="cachingEnabled" value="true" />
- <property name="authenticationCachingEnabled" value="true" />
- <property name="authenticationCacheName" value="authenticationCache" />
- <property name="authorizationCachingEnabled" value="true" />
- <property name="authorizationCacheName" value="authorizationCache" />
- <property name="casServerUrlPrefix" value="http://localhost:8080/cas" /> <!--该地址为cas server地址
- <property name="casService" value="http://localhost:8080/client1/shiro-cas" /> <!-- 该地址为client1 的访问地址+ 下面配置的cas filter -->
- </bean>
MyCasRelam.java 内容
- import org.apache.shiro.authz.AuthorizationInfo;
- import org.apache.shiro.cas.CasRealm;
- import org.apache.shiro.subject.PrincipalCollection;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- public class MyCasRealm extends CasRealm{
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- String username = (String)principals.getPrimaryPrincipal(); //从这里可以从cas server获得认证通过的用户名,得到后我们可以根据用户名进行具体的授权
- //也可以从 Subject subject = SecurityUtils.getSubject();
- <span style="white-space:pre"> </span>//return (String)subject.getPrincipals().asList().get(0); 中取得,因为已经整合后 cas 交给了 shiro-cas
- /* PermissionService service = (PermissionService)SpringContextUtil.getBean("PermissionService");
- List<String> codes = service.findPermissionCodeByUsername(username);
- if(codes != null && codes.size() > 0){
- SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
- for (String str : codes)
- {
- authorizationInfo.addStringPermission(str);
- // info.addRole(role);
- }
- return authorizationInfo;
- }*/
- return null;
- }
- }
shirocas-web.xml配置 重要
- <!-- Shiro的Web过滤器 -->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager" />
- <property name="loginUrl"
- value="http://localhost:8080/cas/login?service=http://localhost:8080/client1/shiro-cas" /> <!--访问client1 时,如果未通过cas认证将会跳转到认证中心,通过得跳转到下面配置的successUrl 里的地址 -->
- <property name="successUrl" value="http://localhost:8080/client1/index.jsp" />
- <property name="filters">
- <util:map>
- <entry key="authc" value-ref="formAuthenticationFilter" />
- <entry key="cas" value-ref="casFilter" />
- </util:map>
- </property>
- <property name="filterChainDefinitions">
- <value>
- /casFailure.jsp = anon
- /shiro-cas* = cas
- /images/** = anon
- /css/** = anon
- /js/** = anon
- /static/** = anon
- /logout = logout
- /** = authc
- </value>
- </property>
- </bean>
- <!-- 会话ID生成器 -->
- <bean id="sessionIdGenerator"
- class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" />
- <!-- 会话Cookie模板 -->
- <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
- <constructor-arg value="sid" />
- <property name="httpOnly" value="true" />
- <property name="maxAge" value="-1" />
- </bean>
- <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
- <constructor-arg value="rememberMe" />
- <property name="httpOnly" value="true" />
- <property name="maxAge" value="2592000" /><!-- 30天 -->
- </bean>
- <!-- rememberMe管理器 如需要记住功能 可删掉相关配置<span style="white-space:pre">
- lt;/span> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
- <!-- rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)-->
- <property name="cipherKey"
- value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
- <property name="cookie" ref="rememberMeCookie" />
- </bean>
- <!-- 会话DAO -->
- <bean id="sessionDAO"
- class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
- <property name="activeSessionsCacheName" value="shiro-activeSessionCache" />
- <property name="sessionIdGenerator" ref="sessionIdGenerator" />
- </bean>
- <!-- 会话验证调度器 -->
- <bean id="sessionValidationScheduler"
- class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
- <property name="sessionValidationInterval" value="1800000" />
- <property name="sessionManager" ref="sessionManager" />
- </bean>
- <!-- 会话管理器 -->
- <bean id="sessionManager"
- class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
- <property name="globalSessionTimeout" value="1800000" />
- <property name="deleteInvalidSessions" value="true" />
- <property name="sessionValidationSchedulerEnabled" value="true" />
- <property name="sessionValidationScheduler" ref="sessionValidationScheduler" />
- <property name="sessionDAO" ref="sessionDAO" />
- <property name="sessionIdCookieEnabled" value="true" />
- <property name="sessionIdCookie" ref="sessionIdCookie" />
- </bean>
- <bean id="casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory" />
- <!-- 安全管理器 -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="casRealm" />
- <property name="sessionManager" ref="sessionManager" />
- <property name="cacheManager" ref="cacheManager" />
- <property name="rememberMeManager" ref="rememberMeManager" />
- <property name="subjectFactory" ref="casSubjectFactory" />
- </bean>
- <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
- <bean
- class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
- <property name="staticMethod"
- value="org.apache.shiro.SecurityUtils.setSecurityManager" />
- <property name="arguments" ref="securityManager" />
- </bean>
- <bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
- <property name="failureUrl" value="/casFailure.jsp" />
- </bean>
- <pre name="code" class="html"><bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
- <property name="failureUrl" value="/casFailure.jsp" />
- </bean>
- <bean id="formAuthenticationFilter"
- class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter" />
- <!-- Shiro生命周期处理器-->
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
以上基本完成 在spring下 shiro与cas的整合
启动tomcat,访问 client1 将会跳转到cas认证中心,认证通过将自动跳转的 client1的首页! 多个client 与上类似!