cas+tomcat+shiro实现单点登录-4-Apache Shiro 集成Cas作为cas client端实现
目录
4.Apache Shiro 集成Cas作为cas client端实现
Apache Shiro 集成Cas作为cas client端实现
第一步、添加maven依赖
<!-- shiro依赖包 --> <!-- <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>${shiro.version}</version> </dependency> --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> <!-- shiro-cas集成依赖包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-cas</artifactId> <version>${shiro.version}</version> </dependency>
第二步、添加spring-shiro.xml配置文件
<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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd" default-lazy-init="true"> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- 设定角色的登录链接,这里为cas登录页面的链接可配置回调地址 --> <property name="loginUrl" value="http://192.168.20.248:8080/cas/login?service=http://127.0.0.1:8080/nhmz/shiro-cas" /> <property name="successUrl" value="/index.htm"></property> <property name="filters"> <util:map> <entry key="casFilter" value-ref="casFilter" /> <entry key="logout" value-ref="logout" /> </util:map> </property> <property name="filterChainDefinitions"> <value> /shiro-cas=casFilter /logout.htm=logout /login.htm=authc /xzqh/**=authc /tjfx/**=authc /gxfw/**=authc /xtsz/**=authc /region/**=authc /shareApi/**=authc /**=anon </value> </property> </bean> <!-- shiro-cas登录过滤器 --> <bean id="casFilter" class="org.apache.shiro.cas.CasFilter"> <!-- 配置验证错误时的失败页面 ,这里配置为登录页面 --> <property name="failureUrl" value="http://192.168.20.248:8080/cas/login?service=http://127.0.0.1:8080/nhmz/shiro-cas" /> </bean> <!-- 退出登录过滤器 --> <bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter"> <property name="redirectUrl" value="http://192.168.20.248:8080/cas/logout?service=http://127.0.0.1:8080/nhmz/index.htm" /> </bean>
<!-- 自定义casRealm --> <bean id="casRealm" class="com.ld.nhmz.shiro.MzCasRealm"> <!-- <property name="defaultRoles" value="ROLE_USER" /> --> <!-- 配置cas服务器地址 --> <property name="casServerUrlPrefix" value="http://192.168.20.248:8080/cas" /> <!-- 客户端的回调地址设置,必须和上面的shiro-cas过滤器casFilter拦截的地址一致 --> <property name="casService" value="http://127.0.0.1:8080/nhmz/shiro-cas" /> </bean> <!--缓存机制 --> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" /> </bean> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="casRealm" /> <property name="subjectFactory" ref="casSubjectFactory" /> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- 如果要实现cas的remember me的功能,需要用到下面这个bean,并设置到securityManager的subjectFactory中 --> <bean id="casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory" /> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager" /> <property name="arguments" ref="securityManager" /> </bean> </beans>
这里由于前端的每一个操作shiro都会做登录和权限认证,所以上面配置添加了缓存机制
所以在classpath目录下还要添加缓存而配置文件ehcache-shiro.xml,配置如下:
<?xml version="1.1" encoding="UTF-8"?> <ehcache name="shirocache"> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <!-- <cache name="diskCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> --> <cache name="passwordRetryCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" > </cache> <cache name="authorizationCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="0" overflowToDisk="false" > </cache> <cache name="authenticationCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="0" overflowToDisk="false" > </cache> <cache name="shiro-activeSessionCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="0" overflowToDisk="false" > </cache> </ehcache>
第三步、添加<bean id="casRealm" class="com.ld.nhmz.shiro.MzCasRealm">配置的自定义实现类
package com.ld.nhmz.shiro; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.cas.CasRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import com.ld.nhmz.ebo.SusRoleEntity; import com.ld.nhmz.ebo.SusUserEntity; import com.ld.nhmz.service.SusRolePermissionService; import com.ld.nhmz.service.SusRoleService; import com.ld.nhmz.service.SusUserService; //@Service @SuppressWarnings("deprecation") @Transactional(value = "nhmzTM") public class MzCasRealm extends CasRealm { @Autowired private SusUserService userService; @Autowired private SusRolePermissionService rolePermissionService; @Autowired private SusRoleService roleService; /** * 授权访问控制,用于对用户进行的操作进行人证授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); SusUserEntity user = userService.findByUsername(username); if (user != null) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); // 设置用户的角色 String roleId = userService.getRoleIdFromUserId(user.getId()); SusRoleEntity roleEntity = roleService.getRole(roleId); if (null != roleEntity) authorizationInfo.addRole(roleEntity.getRolecode()); // 设置用户对应的角色的权限集合 List<String> permissons; try { permissons = rolePermissionService.getPermissionIds2(roleId); for (String permission : permissons) { authorizationInfo.addStringPermission(permission); } } catch (Exception e) { e.printStackTrace(); } return authorizationInfo; } return null; } /** * 验证用户身份 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { return super.doGetAuthenticationInfo(token); } @Override public void clearCachedAuthorizationInfo(PrincipalCollection principals) { super.clearCachedAuthorizationInfo(principals); } @Override public void clearCachedAuthenticationInfo(PrincipalCollection principals) { super.clearCachedAuthenticationInfo(principals); } @Override public void clearCache(PrincipalCollection principals) { super.clearCache(principals); } public void clearAllCachedAuthorizationInfo() { getAuthorizationCache().clear(); } public void clearAllCachedAuthenticationInfo() { getAuthenticationCache().clear(); } public void clearAllCachedKickoutInfo() { } public void clearAllCache() { clearAllCachedAuthenticationInfo(); clearAllCachedAuthorizationInfo(); clearAllCachedKickoutInfo(); } }
第四步、将spring-shiro.xml配置文件导入到spring的配置文件中,注意配置文件间的相对路径
第五步、web.xml中添加shiro过滤器
<!-- shiro filter的名字是shiroFilter,那么在spring的配置文件中要有一个名字为shiroFilter的bean --> <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> </filter-mapping>
以上步骤完成,shiro集成cas的步骤就完成了,实现了单点登录和单点注销登录。