基于Spirng的Shiro安全框架与CAS SSO的集成

首先需要在maven的pom文件中添加依赖

< dependency>
     <groupId >org.apache.shiro groupId >
     <artifactId > shiro-cas artifactId >
     <version >${shiro.version} version >
     <exclusions >
          <exclusion >
            <artifactId > servlet-api artifactId >
            <groupId >javax.servlet groupId >
          exclusion >
          <exclusion >
           <artifactId >commons-logging artifactId >
            <groupId >commons-logging groupId >
          exclusion >
    exclusions >
    dependency >
    <dependency >
     <groupId >org.apache.shiro groupId >
     <artifactId > shiro-springartifactId>
     <version >${shiro.version} version >
    dependency >
    <dependency >
     <groupId >org.apache.shiro groupId >
     <artifactId > shiro-ehcache artifactId >
     <version >${shiro.version} version >
dependency >

在web.xml中添加相应的filter和listener


    <filter>
        <filter-name>shiroFilterfilter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
        <init-param>
            <param-name>targetFilterLifecycleparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter>
        <filter-name>singleSignOutFilterfilter-name>
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilterfilter-class>
    filter>
    <listener>
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListenerlistener-class>
    listener>

    <filter-mapping>
        <filter-name>singleSignOutFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
    <filter-mapping>
        <filter-name>shiroFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

先来看一下shiro的property文件

shiro.session.timeout=1800000
shiro.session.validate.timespan=1800000
shiro.login.url=http://login.51idc.cn/user/login?service=http://localhost:8086/tickets/shiro-cas
shiro.logout.url=http://login.51idc.cn/user/logout?service=http://localhost:8086/tickets/ticket/create
shiro.login.success.url=http://localhost:8086/home
shiro.casServer.url=http://login.51idc.cn/user
shiro.client.cas=http://localhost:8086/tickets/shiro-cas
shiro.failureUrl=/error.jsp

下面进行applicationContext-shiro.xml的配置,记得在sping的主配置文件中引用此配置


<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        
        
        
        <property name="loginUrl" value="${shiro.login.url}" />
        <property name="successUrl" value="${shiro.login.success.url}" />
        <property name="filters">
            <map>
                <entry key="casFilter" value-ref="casFilter" />
                <entry key="anon" value-ref="anonymousFilter" />
                <entry key="logout" value-ref="logoutFilter" />
                <entry key="loginSuccessFilter" value-ref="loginSuccessFilter" />   
            map>
        property>
        <property name="filterChainDefinitions">
            <value>
                /shiro-cas = casFilter
                /**/*.js = anon
                /**/*.css = anon
                /static/** = anon
                /api/** = anon
                /logout = logout
                /admin/** = loginSuccessFilter,roles[admin]
                /** =loginSuccessFilter,roles[employee]
            value>
        property>
    bean>
<bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
    
    <property name="failureUrl" value="${shiro.failureUrl}" />
bean>

<bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
    <property name="redirectUrl" value="${shiro.logout.url}" />
bean>

<bean id="anonymousFilter" class="org.apache.shiro.web.filter.authc.AnonymousFilter" />


<bean id="loginSuccessFilter" class="com.anchnet.tickets.web.filters.LoginSuccessFilter" />



        <property name="sessionManager" ref="defaultWebSessionManager"/>
        <property name="realms">
            <list>
                <ref bean="casRealm" />
            list>
        property>
        <property name="subjectFactory" ref="casSubjectFactory" />

        <property name="cacheManager" ref="shiroEhcacheManager" />
    bean>

<bean id="casRealm" class="com.anchnet.tickets.service.account.CustomCASRealm">
        <property name="defaultRoles" value="ROLE_USER" />
        <property name="casServerUrlPrefix" value="${shiro.casServer.url}" />
        
        <property name="casService" value="${shiro.client.cas}" />
bean>


<bean id="casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory" />


<bean id="defaultWebSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="globalSessionTimeout" value="${shiro.session.timeout}"/>
    <property name="sessionIdCookie" ref="simpleCookie"/>
    <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
    <property name="sessionValidationSchedulerEnabled" value="true"/>
    <property name="deleteInvalidSessions" value="true"/>
bean>

<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <constructor-arg index="0" value="JSESSIONID_COOKIE"/>
    <property name="httpOnly" value="true"/>
bean>

<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
    <property name="sessionManager" ref="defaultWebSessionManager"/>
    <property name="interval" value="${shiro.session.validate.timespan}"/>
bean>


    <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:cache/ehcache-shiro.xml" />
    bean>


    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />




<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
    <property name="proxyTargetClass" value="true" />
bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
bean>

上面的用户授权的cache采用ehcache,以下是ehcache-shiro.xml的配置

<ehcache updateCheck="false" name="shiroCache">
    
   <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            />
ehcache>

下面详细介绍 CasRealm bean的实现

import java.io.Serializable;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;

public class CustomCASRealm extends CasRealm {

    private static Logger logger = LoggerFactory
            .getLogger(CustomCASRealm.class);

    // @Autowired
    protected AccountService accountService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String loginName = (String) principals.getPrimaryPrincipal();
        if (loginName == null) {
            throw new UnauthorizedException("无效的凭证");
        }
        try {
            Map rolesMaps = (Map) principals.asList().get(1);
            String roles = (String) rolesMaps.get("role");
            if (roles.length() > 0) {
                roles = roles.substring(1);
                roles = roles.substring(0, roles.length() - 1);
                logger.debug("!!!!! get roles:{}", roles);
                authorizationInfo.addRoles(ImmutableList.copyOf(StringUtils.split(roles, ", ")));
            } else {
                logger.debug("user {} has no roles!!!", loginName);
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new UnauthorizedException("无效的凭证");
        }
        return authorizationInfo;
    }

你可能感兴趣的:(基于Spirng的Shiro安全框架与CAS SSO的集成)