简介
- Shiro 1.2开始支持Jasig CAS单点登录。
- 作用:用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无需多次登录。
服务器下载
- Jasig CAS分为服务器端和客户端,服务器提供用户验证。访问需要登录的页面,自动跳转单点登录服务器:https://localhost:8443/server/login?service=原url,单点登录采用的是https。
- war包下载地址:http://central.maven.org/maven2/org/jasig/cas/cas-server-webapp/4.0.3、http://mvnrepository.com/artifact/org.jasig.cas/cas-server-webapp/4.0.3。
- 我们使用cas 4.0.0版本的服务器,除了以上地址还可以到https://www.apereo.org/cas/download选择版本下载zip自己构建war包(没试过),也可以到网盘https://pan.baidu.com/s/1snr4Tzv,密码:z45j,下载cas-server-4.0.0-release.rar(已下载到E和网盘/五年高考三年模拟)。
- 解压(网盘版解压外层压缩包后依然有两个压缩包,再接着把俩一起解压了),找到cas-server-4.0.0\modules\cas-server-webapp-4.0.0.war,重命名为cas.war(主要是为了待会访问系统时url短一点)。
- 将cas-server.war放入tomcat/webapps,启动tomcat。
- 访问https://localhost:8443/cas/login,默认用户名casuser,密码Mellon登录。
以上只是测试cas server的效果,下面正式集成cas,分为server和client两部分。
- 新建Maven项目:shiro-chapter15。
CAS Server
- 直接将E:\cas-server-4.0.0-release\cas-server-4.0.0\cas-server-webapp拷到shirochapter15下成为其子模块,并重命名为shiro-chapter15-server;idea将自动扫描到更改。
- 在idea中修改shiro-chapter15的pom.xml,设置shiro-chapter15-server为其子模块。
- 修改shiro-chapter15-server的pom.xml中的一些头信息,增加tomcat插件。
- 添加证书:src下建包licensing,把E:\cas导入maven缺少head.txt文件中俩文件复制进去即可。
添加自定义用户:src/main/webapp/WEB-INF/deployerConfigContext.xml,primaryAuthenticationHandler节点下添加代码:
<entry key="zhang" value="123"/>
- tomcat7:run运行,出现上面登录界面,输入zhang/123即可登录。cas server配置成功。
CAS Client
- 示例采用shirochapter12,web.xml、pom.xml、src、resources下文件基本一致,以下只列出不同的部分。
- 导出证书:cas客户端和服务端间交互需要用到证书,因此需要将D:/keys/localhost.keystore导出证书到相同目录下。
//导出证书
keytool -export -alias localhost -file D:\keys\localhost.cer
-keystore D:\keys\localhost.keystore
//导入jdk
cd D:\jdk\1.8\jre\lib\security //进入jdk(真正的jdk而非本地jdk目录)
keytool -import -alias localhost
-file D:\localhost.cer -noprompt -trustcacerts -storetype jks
-keystore cacerts -storepass 123456
导入失败的话可先将security下的cacerts删掉。
导入shiro-cas依赖:
<dependency> <!--集成cas-client--> <groupId>org.apache.shiro</groupId> <artifactId>shiro-cas</artifactId> <version>1.2.2</version> </dependency>
自定义CasRealm:继承CasRealm类,实现权限验证,用户验证则交给cas server做,不用自定义。
public class MyCasRealm extends CasRealm {
private UserService userService;
public void setUserService(UserService userService){
this.userService=userService;
}
/**
* @Author haien
* @Description 根据CAS服务器返回的用户身份获取相应的权限信息
* @Date 2019/3/11
* @Param [principals]
* @return org.apache.shiro.authz.AuthorizationInfo
**/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username=(String)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
authorizationInfo.setRoles(userService.findRoles(username));
authorizationInfo.setStringPermissions(userService.findPermissions(username));
return authorizationInfo;
}
}
spring-shiro-web.xml:配置CasRealm和CasFilter,即查找用户权限以支持权限验证和配置cas过滤器使登录时重定向到cas server的登录页面。
<!--CasRealm--> <bean id="casRealm" class="com.haien.chapter15.realm.MyCasRealm"> <property name="userService" ref="userService"/> <property name="cachingEnabled" value="true"/> <property name="authenticationCachingEnabled" value="true"/> <property name="authenticationCacheName" value="authenticationCache"/> <property name="authorizationCachingEnabled" value="true"/> <property name="authorizationCacheName" value="authorizationCache"/> <!--CAS Server服务器端地址--> <property name="casServerUrlPrefix" value="https://localhost:8443/chapter15-server"/> <!--登录成功后跳转的url,即用于接收并处理登录成功后的Ticket的--> <property name="casService" value="https://localhost:8443/chapter15-client/cas"/> </bean>
如果用户权限信息也由服务端提供的话,可以不用继承而直接使用CasRealm。
<bean id="casRealm" class="org.apache.shiro.cas.CasRealm"> <!--和上面一样的property--> <!--默认添加给所有登录成功用户的角色和权限--> <property name="defaultRoles" value="admin,user"/> <property name="defaultPermissions" value="user:create,user:update"/> <!--角色、权限字段名;若权限信息是从服务端返回的(即返回的CAS Principal中 除了Principal外还有Attributes),可以使用roleAttributeNames、 permissionAttributeNames来获取Attributes中的角色、权限信息; 请自行查询cas如何获取用户更多信息--> <property name="roleAttributeNames" value="roles"/> <property name="permissionAttributeNames" value="permissions"/> </bean>
CasFilter:
<!--CasFilter:类似于FormAuthenticationFilter,只不过其验证服务器端返回的是 CAS Service Ticket--> <bean id="casFilter" class="org.apache.shiro.cas.CasFilter"> <property name="failureUrl" value="/casFailure.jsp" /> </bean> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--登录路径;service为登录成功后跳转的url--> <property name="loginUrl" value="https://localhost:8443/chapter15-server/login? service=https://localhost:8443/chapter15-client/cas"/> <!-- 登录成功后跳转路径 --> <property name="successUrl" value="/" /> <!--定义自己的过滤器--> <property name="filters"> <util:map> <entry key="cas" value-ref="casFilter"/> </util:map> </property> <property name="filterChainDefinitions"> <value> /casFailure.jsp=anon /cas=cas //走cas服务器,带着ticket过去再次身份验证 /logout = logout /** = user </value> </property> </bean>
测试:
- 访问http://localhost:8080/chapter15-client/,自动跳转登录页面,即在spring-shiro-web.xml
配置的loginUrl————https://localhost:8443/server/login?service=
https://localhost:8443/chapter15-client/cas,原url从/变成/cas; - 登录成功后,转回原url:https://localhost:8443/chapter15-client/cas?ticket=
ST-1-eh2cIo92F9syvoMs5DOg-cas01.example.org; - spring-shiro-web.xml配置了/cas要走cas过滤器,它会先验证ticket是否有效,有效再调用MyCasRealm获取权限信息。
- 代码实例:ideaProjects/shirochapter15
- 《跟我学Shiro》第十五章