首页 > 代码库 > cas4.2.7与shiro进行整合

cas4.2.7与shiro进行整合

准备工作

  cas单点登录开始前准备,请参考cas4.2.7实现单点登录。

与shiro进行整合

  注:准备工作的基础上,对cas客户端进行如下改进。

  引入相关jar包

shiro-cas-1.2.6.jarshiro-core-1.2.6.jarshiro-spring-1.2.6.jarshiro-web-1.2.6.jar

  web.xml引入shiro过滤器

<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">    <display-name>Archetype Created Web Application</display-name>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>            classpath:spring-web.xml, classpath:spring-shiro.xml        </param-value>    </context-param>    <!-- Shiro配置 -->    <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>    <!-- ****************** 单点登录开始 ********************-->    <!-- 用于实现单点登出功能  可选 -->    <listener>        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>    </listener>    <!-- 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前 可选 -->    <filter>        <filter-name>CAS Single Sign Out Filter</filter-name>        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>        <init-param>            <param-name>casServerUrlPrefix</param-name>            <param-value>http://127.0.0.1:8080/cas-web/</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>CAS Single Sign Out Filter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- 该过滤器对HttpServletRequest请求包装, 可通过HttpServletRequest的getRemoteUser()方法获得登录用户的登录名,可选 -->    <filter>        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>        <filter-class>            org.jasig.cas.client.util.HttpServletRequestWrapperFilter        </filter-class>    </filter>    <filter-mapping>        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- 该过滤器使得可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。         比如AssertionHolder.getAssertion().getPrincipal().getName()。         这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息 -->    <filter>        <filter-name>CAS Assertion Thread Local Filter</filter-name>        <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>    </filter>    <filter-mapping>        <filter-name>CAS Assertion Thread Local Filter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- ****************** 单点登录结束 ********************-->    <servlet>        <servlet-name>springMVC</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath:spring-web.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>springMVC</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>

  引入shiro的配置文件

<?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"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <context:property-placeholder location="classpath:shiro.properties" ignore-unresolvable="true"/>    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">        <property name="securityManager" ref="securityManager"/>        <!-- 设定角色的登录链接,这里为cas登录页面的链接可配置回调地址  -->        <property name="loginUrl" value="${cas.loginUrl}" />        <property name="successUrl" value="${shiro.successUrl}" />        <property name="filters">            <map>                <entry key="casFilter" value-ref="casFilter"/>            </map>        </property>        <property name="filterChainDefinitions">            <value>                /shiro-cas = casFilter                /** = authc            </value>        </property>    </bean>    <bean id="casFilter" class="org.apache.shiro.cas.CasFilter">        <property name="failureUrl" value="${shiro.failureUrl}"/>    </bean>    <bean id="ShiroCasRealm" class="com.hjzgg.client.shiro.ShiroCasRealm"/>    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">        <property name="realm" ref="ShiroCasRealm"/>        <property name="subjectFactory" ref="casSubjectFactory"/>    </bean>    <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的需要属性

cas.loginUrl=http://127.0.0.1:8080/cas-web/login?service=http://127.0.0.1:8080/cas-client/shiro-cascas.logoutUrl=http://127.0.0.1:8080/cas-web/logout?service=http://127.0.0.1:8080/cas-client/shiro-cascas.serverUrlPrefix=http://127.0.0.1:8080/cas-webshiro.cas.service=http://127.0.0.1:8080/cas-client/shiro-casshiro.failureUrl=/errorshiro.successUrl=/success

  自定义shiro的realm

package com.hjzgg.client.shiro;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.cas.CasAuthenticationException;import org.apache.shiro.cas.CasToken;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.SimplePrincipalCollection;import org.apache.shiro.util.StringUtils;import org.jasig.cas.client.authentication.AttributePrincipal;import org.jasig.cas.client.util.AssertionHolder;import org.jasig.cas.client.validation.Assertion;import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;import org.jasig.cas.client.validation.TicketValidationException;import org.jasig.cas.client.validation.TicketValidator;import org.springframework.beans.factory.annotation.Value;import java.util.ArrayList;import java.util.List;import java.util.Map;public class ShiroCasRealm extends AuthorizingRealm {    @Value("${shiro.cas.service}")    private String shiroCasServiceUrl;    @Value("${cas.serverUrlPrefix}")    private String casServerUrlPrefix;    @Override    protected AuthorizationInfo doGetAuthorizationInfo(            PrincipalCollection principals) {        AttributePrincipal principal = AssertionHolder.getAssertion().getPrincipal();        if (principal != null) {            Map<String, Object> attributes = principal.getAttributes();            if (attributes.size() > 0) {//                List<String> roles = CommonUtils.arrayStringtoArrayList((String)attributes.get("roles"));                List<String> roles = null;                //权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)                SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();                //用户的角色集合                      info.addRoles(roles);                //用户的角色对应的所有权限,如果只使用角色定义访问权限,下面的一行可以不要                      //info.addStringPermissions(user.getPermissionList());            }        }        return null;    }    @Override    protected AuthenticationInfo doGetAuthenticationInfo(            AuthenticationToken token) throws AuthenticationException {        CasToken casToken = (CasToken) token;        if (token == null)            return null;        String ticket = (String) casToken.getCredentials();        if (!StringUtils.hasText(ticket))            return null;        Cas20ServiceTicketValidator cas20ServiceTicketValidator = new Cas20ServiceTicketValidator(casServerUrlPrefix);        cas20ServiceTicketValidator.setEncoding("utf-8");        TicketValidator ticketValidator = cas20ServiceTicketValidator;        try {            Assertion casAssertion = ticketValidator.validate(ticket, shiroCasServiceUrl);            AttributePrincipal casPrincipal = casAssertion.getPrincipal();            String userId = casPrincipal.getName();            List principals = new ArrayList<String>();            if (casPrincipal != null) {                Map<String, Object> attributes = casPrincipal.getAttributes();                principals.add(userId);                principals.add(attributes);            }            PrincipalCollection principalCollection = new SimplePrincipalCollection(principals, getName());            return new SimpleAuthenticationInfo(principalCollection, ticket);        } catch (TicketValidationException e) {            throw new CasAuthenticationException((new StringBuilder()).append("Unable to validate ticket [").append(ticket).append("]").toString(), e);        }    }    @Override    protected void onInit() {        super.onInit();        this.setAuthenticationTokenClass(CasToken.class);    }}

  引入日志系统

    http://www.cnblogs.com/hujunzheng/p/6926429.html

遇到的问题

  shiro+cas学习及整合问题

  cas4.2.7学习笔记

项目地址

  https://github.com/hjzgg/cas4.2.7-authentication/tree/shiro+cas

 

cas4.2.7与shiro进行整合