zoukankan      html  css  js  c++  java
  • cas4.2.7与shiro进行整合

    准备工作

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

    与shiro进行整合

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

      引入相关jar包

    shiro-cas-1.2.6.jar
    shiro-core-1.2.6.jar
    shiro-spring-1.2.6.jar
    shiro-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-cas
    cas.logoutUrl=http://127.0.0.1:8080/cas-web/logout?service=http://127.0.0.1:8080/cas-client/shiro-cas
    cas.serverUrlPrefix=http://127.0.0.1:8080/cas-web
    shiro.cas.service=http://127.0.0.1:8080/cas-client/shiro-cas
    shiro.failureUrl=/error
    shiro.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

  • 相关阅读:
    柔性的沟通
    as3简单的文字提示队列
    恢复低版本的FlashPlayer
    AIR切换SDK版本时遇到的问题
    文字闪烁提示
    as3 ISOLIB学习资料整理
    xml文件转二进制文件的AIR
    Photoshop CS5的序列号
    MySQL导出、导出数据
    as3 shake动画
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/6928498.html
Copyright © 2011-2022 走看看