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

时间: 2024-08-06 23:17:04

cas4.2.7与shiro进行整合的相关文章

项目一:第十三天 1、菜单数据管理 2、权限数据管理 3、角色数据管理 4、用户数据管理 5、在realm中动态查询用户权限,角色 6、Shiro中整合ehcache缓存权限数据

1 课程计划 菜单数据管理 权限数据管理 角色数据管理 用户数据管理 在realm中动态查询用户权限,角色 Shiro中整合ehcache缓存权限数据         2 菜单数据添加 2.1 使用combotree父菜单项数据     1. 页面:menu_add.jsp 2. 修改组件样式:easyui-combotree,修改url  树型表格treeGrid跟下来数combotree要求数据格式基本一致. Combotree通过text属性展示文本.   3. 使用treegrid组件的

SpringBoot2.0+Shiro+JWT 整合

SpringBoot2.0+Shiro+JWT 整合 JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息. 我们利用一定的编码生成 Token,并在 Token 中加入一些非敏感信息,将其传递. 安装环境 开发工具:STS Maven版本:apache-maven-3.5.2 java jdk 1.8 MySQL版本:5.7 系统:Windows10 一.新建Maven项目 配置Maven项目的pom.xml文件 <pr

springMVC和Shiro框架整合使用简单示例 【转】

一.目录结构 首先是目录结构如图: 二.pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0

Spring+Shiro+CAS整合配置笔记

一.前言 Apache Shiro与Spring Security一样是Java的一个安全框架.那为什么与Spring整合却用Shiro?不要问为什么,任性!开个玩笑:D 其实我个人是认为Spring Security太过于笨重,要写太多的过滤器.我是个怕麻烦的人,Shiro的配置简单这就是我选择的理由,何况Spring官方自己都推荐使用Shiro.而Shiro权限控制与CAS单点登录的组合更是堪称Java安全中的***~( ̄_, ̄ )--但本文只介绍它们三者的整合配置(说白了就是给自己留个学习

spring+shiro+ehcache整合

1.导入jar包(pom.xml文件) <!-- ehcache缓存框架 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.11</version> </dependency> Spring 整合 ehcache 包 spring-context-

springboot+springcache+shiro+Redis整合时@Cacheable、@Transactional等注解失效的问题

问题描述: 1.springboot整合shiro之前@Cacheable.@Transactional等注解都可以正常使用: 2.整合了shiro之后,自定义MyShiroRealm中注入RoleUserService时 RolerUservice中的@Cacheable.@Transaction都失效了. MyShiroRealm代码: RoleUserService代码: 原因:shiro和cache在引用service实例顺序问题,shiro引入应在cache后, shiro配置文件中引

SpringBoot与Shiro的整合(单体式项目)

1.包结构 2.jar包,配置文件,类 2.1pom.xml文件配置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ht

java springmvc mybaits maven shiro mysql整合

1. 导出 导入 excel 文件 2  导出word文件 3. IO 流上传下载文件 4. 群发邮件,可以发html.纯文本格式,可以发给任意邮箱(实现批量发送广告邮件) 5. 群发or单独 发送短信,支持两种第三方短信商接口 6. spring   aop  事物处理 7. 代码生成器 (freemarker), 代码 zip 压缩打包 8. MD5加密 SHA加密(登录密码用此加密)接口加密身份校验 9. 数据库连接池  阿里的 druid.Druid在监控.可扩展性.稳定性和性能方面都有

SpringMVC + Mybatis + Shiro 权限整合【转】

<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/> , 否则controller无法使用注解. 这个方法可能避免使用sessionValidationScheduler, 就是避免使用, 就能使用高版本的quartz了. 配置会话监听: Java代码   package com.pandy.core.security.session;