欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

cas client 4.0 整合 shiro

程序员文章站 2022-03-04 15:19:45
...

 

概念或其它内容可以参考我一系列的博客相关文章 http://sgq0085.iteye.com/category/302777

 

1.Maven主要依赖

 

<dependency>
    <groupId>org.jasig.cas.client</groupId>
    <artifactId>cas-client-core</artifactId>
    <version>3.3.3</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-cas</artifactId>
    <version>1.2.3</version>
</dependency>

 

 

2.web.xml

 

<filter>
    <filter-name>CAS Validation Filter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>shiroFilter</param-value>
    </init-param>
    <!-- targetFilterLifecycle设为true是将filter放入web容器中成为真正意义上的filter。
         否则只是个代理filter,不具有filter的生命周期,因此无法执行filter的init、destroy方法 -->
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

 

 

3.shiro的Spring配置文件

1.主要是配置了casFilter 和 DefaultWebSecurityManager的subjectFactory参数;

2.casFilter 中 failureUrl 参数对应的地址 cas-failure需要自己实现,当登录认证失败的时候,会访问这个地址,可以通过该地址将该请求指向一个错误页面;LoginController中实现

3.注意Bean ShiroFilterFactoryBean属性loginUrl的值是 cas服务器地址,并将当前项目登录地址(注意那个/login)作为参数传入进去的。这里 /login和下面filterChainDefinitions中/login = cas保持一直;

 

 

<?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: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.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
    <!-- 读取配置文件 -->
    <context:property-placeholder location="classpath*:cas.properties" ignore-unresolvable="true"/>

    <bean name="singleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>

    <bean name="assertionThreadLocalFilter" class="org.jasig.cas.client.util.AssertionThreadLocalFilter"/>

    <bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
        <!-- cas-failure 通过SpringMVC 跳转JSP -->
        <property name="failureUrl" value="cas-failure"/>
    </bean>

    <!-- Shiro's main business-tier object for web-enabled applications -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="shiroCasRealm"/>
        <property name="cacheManager" ref="shiroEhcacheManager"/>
        <property name="subjectFactory" ref="casSubjectFactory"/>
    </bean>

    <!-- 項目自定义的Realm -->
    <bean id="shiroCasRealm" class="com.gqshao.cas.realm.MyCasRealm">
        <property name="casServerUrlPrefix" value="https://sso.gqshao.com:8443/cas-server"/>
        <property name="casService" value="http://sso.gqshao.com:8090/client/login"/>
    </bean>

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

    <!-- Shiro Filter -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!-- 用于调用Controller -->
        <property name="loginUrl"
                  value="https://sso.gqshao.com:8443/cas-server/login?service=http://sso.gqshao.com:8090/client/login"/>
        <property name="successUrl" value="/"/>
        <!-- 自己实现的formAuthcFilter,加入key type -->
        <property name="filters">
            <util:map>
                <entry key="cas" value-ref="casFilter"/>
            </util:map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                /login = cas
                /logout = logout
                /static/** = anon
                /cas-failure = anon
                /** = user
            </value>
        </property>
    </bean>

    <!-- 用户授权信息Cache, 采用EhCache -->
    <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:security/ehcache-shiro.xml"/>
    </bean>

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- AOP式方法级权限检查 -->
    <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>
</beans>

 

 

 4.LoginController

1.failure方法是登录失败指定跳转到某条失败页面中

2.logoutUrl用于返回登出地址,实际的地址应该为https://sso.gqshao.com/adp-cas/logout?service=http://sso.gqshao.com:8080/adp-web/logout,/logout配置在shiro配置文件中filterChainDefinitions下ShiroFilterFactoryBean中

 

@Controller
public class LoginController {

    @Value("${client.logoutUrl}")
    public String logoutUrl;

    @RequestMapping("/cas-failure")
    public String failure() {
        return "error/casFailure";
    }

    @RequestMapping("/logout-url")
    @ResponseBody
    public String logoutUrl() {
        return logoutUrl;
    }
}

 

5.Shiro的Realm实现

继承CasRealm

 

public class MyCasRealm extends CasRealm {


    /**
     * 认证回调函数,登录时调用.
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
        return super.doGetAuthenticationInfo(authcToken);
    }

    /**
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
     */
    @Override
    @SuppressWarnings("unchecked")
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        List<Object> listPrincipals = principals.asList();
        String name = listPrincipals.get(0).toString();
        Map<String, String> attributes = (Map<String, String>) listPrincipals.get(1);
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Set<String> roles = Sets.newHashSet("admin","operator");
        authorizationInfo.setRoles(roles);
        Set<String> permissions = Sets.newHashSet("show-info");
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }
}

 

 

6.注意

1.通过shiro-cas整合后AssertionHolder不可用

2.实际部署在tomcat时,Windows环境下catalina.bat文件中需要添加set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8;Linux环境中catalina.sh文件中配置JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"