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
遇到的问题
项目地址
https://github.com/hjzgg/cas4.2.7-authentication/tree/shiro+cas
cas4.2.7与shiro进行整合的更多相关文章
- SpringBoot2.0+Shiro+JWT 整合
SpringBoot2.0+Shiro+JWT 整合 JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息. 我们利用一定的编 ...
- 项目一:第十三天 1、菜单数据管理 2、权限数据管理 3、角色数据管理 4、用户数据管理 5、在realm中动态查询用户权限,角色 6、Shiro中整合ehcache缓存权限数据
1 课程计划 菜单数据管理 权限数据管理 角色数据管理 用户数据管理 在realm中动态查询用户权限,角色 Shiro中整合ehcache缓存权限数据 2 菜单数据添加 2.1 使用c ...
- 教你 Shiro + SpringBoot 整合 JWT
本篇文章将教大家在 shiro + springBoot 的基础上整合 JWT (JSON Web Token) 如果对 shiro 如何整合 springBoot 还不了解的可以先去看我的上一篇文章 ...
- springboot shiro 基本整合
springboot shiro 基本整合 https://www.w3cschool.cn/shiro/c52r1iff.html http://shiro.apache.org/configura ...
- SpringBoot+Shiro+mybatis整合实战
SpringBoot+Shiro+mybatis整合 1. 使用Springboot版本2.0.4 与shiro的版本 引入springboot和shiro依赖 <?xml version=&q ...
- spring-mvc + shiro框架整合(sonne_game网站开发04)
这篇文章讲的内容是在之前spring + mybatis + spring-mvc + freemarker框架整合的代码的基础上.有需要的可以看看我博客的前两篇文章. 另外,本文章所讲相关所有代码都 ...
- spring+shiro+ehcache整合
1.导入jar包(pom.xml文件) <!-- ehcache缓存框架 --> <dependency> <groupId>net.sf.ehcache</ ...
- shiro实战整合
引入依赖(包括缓存等): <!-- SECURITY begin --> <dependency> <groupId>org.apache.shiro</gr ...
- SpringBoot与Shiro的整合(单体式项目)
1.包结构 2.jar包,配置文件,类 2.1pom.xml文件配置 <?xml version="1.0" encoding="UTF-8"?> ...
随机推荐
- [原]使用MessageAnalyzer实时查看远端日志
1. 下载安装Message Analyzer 从Message Analyzer下载链接下载,安装过程从略. 说明:关于Message Analyzer的视频教程,可以在打开后的主界面上看到. 2. ...
- okHttp基础用法
获取okHttp..jar.包 1.联网获取jar包 2.本地添加 okHttp的使用 get请求 1.创建okHttpClient对象new OkHttpClient(); 2.创建一个请求对象Re ...
- 【shell编程基础1】shell变量篇
Bash shell bash shell 是bourne shell 的升级版,“bourne again shell”.ubuntu的默认shell. 预备知识 1. "#!" ...
- SQL Server 死锁概念和分析
锁的概念 锁是什么 锁是数据库中在并发操作情形下保护资源的机制.通常(具体要看锁兼容性)只有锁的拥有者才能对被锁的资源进行操作,从而保证数据一致性. 锁的概念可分为几部分 锁资源(锁住什么) 锁模式( ...
- redis intset(整数集合)
redis intset (整数集合) 概述 intset 是集合的底层实现结构之一 intset 集合只包含整数 intset 自升级 intset 整数集合是有序的 intset 结构 结构 // ...
- 除去ubuntu的grub引导
除去ubuntu的grub引导 step如下>> 进入ubuntu终端 sudo gedit /etc/defauli/grub 将 #GRUB_HIDDEN_TIMEOUT=0 最前面的 ...
- 【从无到有】JavaScript新手教程——2.分支结构和循环
介绍完JS的简介和向量以及运算符,大家对JS也有了初步的了解和认识,今天带大家来看一下JS中常用的分支结构以及循环结构是怎么使用的 [JS中的分支结构] 一.[if-else结构] 1.结构写法: i ...
- react 各种UI框架
共计bfd-ui,react-amaze-ui,react-ant-design,react-material-ui,react-components,react-desktop,react-ui,s ...
- 跨语言时区处理与Epoch
国际化通用程序或标准协议通常都涉及到时区问题,比如最近项目用到的OIDC(OpenID Connect). OIDC基于OAuth2协议,其id_token中包含了exp来表达该Token的过期时间, ...
- Java程序i学习中各阶段的建议
第一部分:对于尚未做过Java工作的同学,包括一些在校生以及刚准备转行Java的同学. 一.Java基础 首先去找一个Java的基础教程学一下,这里可以推荐一个地址,或者你也可以参照这个地址上去找相应 ...