《跟我学Shiro》笔记15-单点登录
原文地址:第十五章 单点登录——《跟我学Shiro》
目录贴: 跟我学Shiro目录贴
源码:https://github.com/zhangkaitao/shiro-example
Shiro 1.2 开始提供了 Jasig CAS
单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录。此处我们使用 Jasig CAS v4.0.0-RC3 版本:
Jasig CAS
单点登录系统分为服务器端和客户端,服务器端提供单点登录,多个客户端(子系统)将跳转到该服务器进行登录验证,大体流程如下:
- 访问客户端需要登录的页面 http://localhost:9080/client/,此时会跳到单点登录服务器 https://localhost:8443/server/login?service=https://localhost:9443/client/cas;
- 如果此时单点登录服务器也没有登录的话,会显示登录表单页面,输入用户名/密码进行登录;
- 登录成功后服务器端会回调客户端传入的地址:https://localhost:9443/client/cas?ticket=ST-1-eh2cIo92F9syvoMs5DOg-cas01.example.org,且带着一个
ticket
; - 客户端会把
ticket
提交给服务器来验证ticket
是否有效;如果有效服务器端将返回用户身份; - 客户端可以再根据这个用户身份获取如当前系统用户/角色/权限信息。
服务器端
我们使用了 Jasig CAS
服务器 v4.0.0-RC3
版本,可以到其官方的 github
下载:https://github.com/Jasig/cas/tree/v4.0.0-RC3 下载,然后将其 cas-server-webapp
模块封装到 shiro-example-chapter15-server
模块中,具体请参考源码。
修改 src/main/webapp/WEB-INF/deployerConfigContext.xml
,找到 primaryAuthenticationHandler
,然后添加一个账户: <entry key="zhang" value="123"/>
,其也支持如 JDBC
查询,可以自己定制;具体请参考文档。
客户端
首先使用 localhost.keystore
导出数字证书(公钥)到 D:\localhost.cer
keytool -export -alias localhost -file D:\localhost.cer -keystore D:\localhost.keystore
因为 CAS client
需要使用该证书进行验证,需要将证书导入到 JDK
中:
cd D:\jdk1.7.0_21\jre\lib\security
keytool -import -alias localhost -file D:\localhost.cer -noprompt -trustcacerts -storetype jks -keystore cacerts -storepass 123456
导入 shiro-cas
依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>1.2.2</version>
</dependency>
自定义 CasRealm
:
// CasRealm 根据 CAS 服务器端返回的用户身份获取相应的角色/权限信息。
public class MyCasRealm extends CasRealm {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
@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
配置:
<bean id="casRealm" class="com.github.zhangkaitao.shiro.chapter13.realm.MyCasRealm">
<property name="userService" ref="userService"/>
<!-- …… -->
<property name="casServerUrlPrefix" value="https://localhost:8443/chapter15-server"/>
<property name="casService" value="https://localhost:9443/chapter15-client/cas"/>
</bean>
casServerUrlPrefix
:是CAS Server
服务器端地址;casService
:是当前应用CAS
服务URL
,即用于接收并处理登录成功后的Ticket
的;
如果角色/权限信息是由服务器端提供的话,我们可以直接使用 CasRealm
:
<bean id="casRealm" class="org.apache.shiro.cas.CasRealm">
<!-- …… -->
<property name="defaultRoles" value="admin,user"/>
<property name="defaultPermissions" value="user:create,user:update"/>
<property name="roleAttributeNames" value="roles"/>
<property name="permissionAttributeNames" value="permissions"/>
<property name="casServerUrlPrefix" value="https://localhost:8443/chapter15-server"/>
<property name="casService" value="https://localhost:9443/chapter15-client/cas"/>
</bean>
defaultRoles/defaultPermissions
:默认添加给所有CAS
登录成功用户的角色和权限信息;roleAttributeNames/permissionAttributeNames
:角色属性/权限属性名称,如果用户的角色/权限信息是从服务器端返回的(即返回的CAS Principal
中除了Principal
之外还有如一些Attributes
),此时可以使用roleAttributeNames/permissionAttributeNames
得到Attributes
中的角色/权限数据;请自行查询CAS
获取用户更多信息。
<bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
<property name="failureUrl" value="/casFailure.jsp"/>
</bean>
CasFilter
类似于 FormAuthenticationFilter
,只不过其验证服务器端返回的 CAS Service Ticket
。
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="https://localhost:8443/chapter15-server/login?service=https://localhost:9443/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
/logout = logout
/** = user
</value>
</property>
</bean>
loginUrl
:https://localhost:8443/chapter15-server/login 表示服务端端登录地址,登录成功后跳转到?service
参数对于的地址进行客户端验证及登录;/cas=cas
:即/cas
地址是服务器端回调地址,使用CasFilter
获取Ticket
进行登录。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com
文章标题:《跟我学Shiro》笔记15-单点登录
文章字数:1.3k
本文作者:Bin
发布时间:2018-04-20, 20:12:22
最后更新:2019-09-03, 16:50:26
原始链接:http://coolview.github.io/2018/04/20/%E8%B7%9F%E6%88%91%E5%AD%A6Shiro/%E3%80%8A%E8%B7%9F%E6%88%91%E5%AD%A6Shiro%E3%80%8B%E7%AC%94%E8%AE%B015-%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。