原创 2017年02月08日 17:39:55
  • 4006

Shiro 1.2开始提供了Jasig CAS单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录。

Jasig CAS单点登录系统分为服务器端和客户端,服务器端提供单点登录,多个客户端(子系统)将跳转到该服务器进行登录验证,大体流程如下:

1、访问客户端需要登录的页面http://localhost:9080/ client/,此时会跳到单点登录服务器https://localhost:8443/ server/login?service=https://localhost:9443/ client/cas;

原因:客户端访问任何地址,都会被shirofilter 拦截,shiro 拦截后发现, 应该会使用authc 进行认证 发现用户没有登录,所以会跳转到 shiroFilter 配置的loginUrl 页面

2、如果此时单点登录服务器也没有登录的话,会显示登录表单页面,输入用户名/密码进行登录;

3、登录成功后服务器端会回调客户端传入的地址:https://localhost:9443/client/cas?ticket=ST-1-eh2cIo92F9syvoMs5DOg-cas01.example.org,且带着一个ticket;

4、客户端会把ticket提交给服务器来验证ticket是否有效;如果有效服务器端将返回用户身份;

解释:这个时候 访问/cas就会被casFileter 拦截 ,casFilter 内部创建 带ticket 的token,然后 调用subject.login方法,这时候 继承casRealm 的myrealm  进行处理。

默认认证机制 会去服务器端进行ticket 验证。

5、客户端可以再根据这个用户身份获取如当前系统用户/角色/权限信息。

服务器端

我们使用了Jasig CAS服务器v4.0.0-RC3版本,可以到其官方的github下载:https://github.com/Jasig/cas/tree/v4.0.0-RC3下载,然后将其cas-server-webapp模块封装到shiro-example-chapter15-server模块中,具体请参考源码。

1、数字证书使用和《第十四章 SSL》一样的数字证书,即将localhost.keystore拷贝到shiro-example-chapter15-server模块根目录下;

2、在pom.xml中添加Jetty Maven插件,并添加SSL支持:

Java代码  
  1. <plugin>
  2. <groupId>org.mortbay.jetty</groupId>
  3. <artifactId>jetty-maven-plugin</artifactId>
  4. <version>8.1.8.v20121106</version>
  5. <configuration>
  6. <webAppConfig>
  7. <contextPath>/${project.build.finalName}</contextPath>
  8. </webAppConfig>
  9. <connectors>
  10. <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
  11. <port>8080</port>
  12. </connector>
  13. <connector implementation="org.eclipse.jetty.server.ssl.SslSocketConnector">
  14. <port>8443</port>
  15. <keystore>${project.basedir}/localhost.keystore</keystore>
  16. <password>123456</password>
  17. <keyPassword>123456</keyPassword>
  18. </connector>
  19. </connectors>
  20. </configuration>
  21. </plugin>

3、修改src/main/webapp/WEB-INF/deployerConfigContext.xml,找到primaryAuthenticationHandler,然后添加一个账户:

Java代码  
  1. <entry key="zhang" value="123"/>

其也支持如JDBC查询,可以自己定制;具体请参考文档。

4、mvn jetty:run启动服务器测试即可:

访问https://localhost:8443/chapter15-server/login将弹出如下登录页面:

输入用户名/密码,如zhang/123,将显示登录成功页面:

到此服务器端的简单配置就完成了。

客户端

1、首先使用localhost.keystore导出数字证书(公钥)到D:\localhost.cer

Java代码  
  1. keytool -export -alias localhost -file D:\localhost.cer -keystore D:\localhost.keystore

2、因为CAS client需要使用该证书进行验证,需要将证书导入到JDK中:

Java代码  
  1. cd D:\jdk1.7.0_21\jre\lib\security
  2. keytool -import -alias localhost -file D:\localhost.cer -noprompt -trustcacerts -storetype jks -keystore cacerts -storepass 123456

如果导入失败,可以先把security 目录下的cacerts删掉;

3、按照服务器端的Jetty Maven插件的配置方式配置Jetty插件;

4、在shiro-example-chapter15-client模块中导入shiro-cas依赖,具体请参考其pom.xml;

5、自定义CasRealm:

Java代码  
  1. public class MyCasRealm extends CasRealm {
  2. private UserService userService;
  3. public void setUserService(UserService userService) {
  4. this.userService = userService;
  5. }
  6. @Override
  7. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  8. String username = (String)principals.getPrimaryPrincipal();
  9. SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
  10. authorizationInfo.setRoles(userService.findRoles(username));
  11. authorizationInfo.setStringPermissions(userService.findPermissions(username));
  12. return authorizationInfo;
  13. }
  14. }

CasRealm根据CAS服务器端返回的用户身份获取相应的角色/权限信息。

6、spring-shiro-web.xml配置:

Java代码  
  1. <bean id="casRealm" class="com.github.zhangkaitao.shiro.chapter13.realm.MyCasRealm">
  2. <property name="userService" ref="userService"/>
  3. ……
  4. <property name="casServerUrlPrefix" value="https://localhost:8443/chapter14-server"/>
  5. <property name="casService" value="https://localhost:9443/chapter14-client/cas"/>
  6. </bean>

casServerUrlPrefix:是CAS Server服务器端地址;

casService:是当前应用CAS服务URL,即用于接收并处理登录成功后的Ticket的;

如果角色/权限信息是由服务器端提供的话,我们可以直接使用CasRealm:

Java代码  
  1. <bean id="casRealm" class="org.apache.shiro.cas.CasRealm">
  2. ……
  3. <property name="defaultRoles" value="admin,user"/>
  4. <property name="defaultPermissions" value="user:create,user:update"/>
  5. <property name="roleAttributeNames" value="roles"/>
  6. <property name="permissionAttributeNames" value="permissions"/>
  7. <property name="casServerUrlPrefix" value="https://localhost:8443/chapter14-server"/>
  8. <property name="casService" value="https://localhost:9443/chapter14-client/cas"/>
  9. </bean>

defaultRoles/ defaultPermissions:默认添加给所有CAS登录成功用户的角色和权限信息;

roleAttributeNames/ permissionAttributeNames:角色属性/权限属性名称,如果用户的角色/权限信息是从服务器端返回的(即返回的CAS Principal中除了Principal之外还有如一些Attributes),此时可以使用roleAttributeNames/ permissionAttributeNames得到Attributes中的角色/权限数据;请自行查询CAS获取用户更多信息。

Java代码  
  1. <bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
  2. <property name="failureUrl" value="/casFailure.jsp"/>
  3. </bean>

CasFilter类似于FormAuthenticationFilter,只不过其验证服务器端返回的CAS Service Ticket。

Java代码  
  1. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  2. <property name="securityManager" ref="securityManager"/>
  3. <property name="loginUrl" value="https://localhost:8443/chapter14-server/login?service=https://localhost:9443/chapter14-client/cas"/>
  4. <property name="successUrl" value="/"/>
  5. <property name="filters">
  6. <util:map>
  7. <entry key="cas" value-ref="casFilter"/>
  8. </util:map>
  9. </property>
  10. <property name="filterChainDefinitions">
  11. <value>
  12. /casFailure.jsp = anon
  13. /cas = cas
  14. /logout = logout
  15. /** = user
  16. </value>
  17. </property>
  18. </bean>

loginUrl:https://localhost:8443/chapter15-server/login表示服务端端登录地址,登录成功后跳转到?service参数对于的地址进行客户端验证及登录;

“/cas=cas”:即/cas地址是服务器端回调地址,使用CasFilter获取Ticket进行登录。

7、测试,输入http://localhost:9080/chapter15-client地址进行测试即可,可以使用如Chrome开这debug观察网络请求的变化。

如果遇到以下异常,一般是证书导入错误造成的,请尝试重新导入,如果还是不行,有可能是运行应用的JDK和安装数字证书的JDK不是同一个造成的:

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)

at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)

at sun.security.validator.Validator.validate(Validator.java:260)

at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)

at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)

at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)

at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)

... 67 more

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)

at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)

at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)

... 73 more

 
 
 

shiro 单点登录原理 实例的更多相关文章

  1. CAS单点登录原理简单介绍

    1. SSO简介 1.1 单点登录定义 单点登录(Single sign on),英文名称缩写SSO,SSO的意思就是在多系统的环境中,登录单方系统,就可以在不用再次登录的情况下访问相关受信任的系统. ...

  2. CAS实现SSO单点登录原理

    1.      CAS 简介 1.1.  What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...

  3. CAS实现SSO单点登录原理(转)

    1.      CAS 简介 1.1.  What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...

  4. 转 CAS实现SSO单点登录原理

    原文链接   http://m.blog.csdn.net/hxpjava1/article/details/74019017 CAS 简介 1. 1.1.  What is CAS ? CAS (  ...

  5. 一篇文章彻底弄懂CAS实现SSO单点登录原理

    1. CAS 简介 1.1. What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨在为 Web ...

  6. sso单点登录原理详解

    sso单点登录原理详解     01 单系统登录机制    1.http无状态协议 web应用采用browser/server架构,http作为通信协议.http是无状态协议,浏览器的每一次请求,服务 ...

  7. php sso单点登录原理阐述

    原理:就是用户登录了单点登录系统(sso)之后,就可以免登录形式进入相关系统: 实现: 点击登录跳转到SSO登录页面并带上当前应用的callback地址 登录成功后生成COOKIE并将COOKIE传给 ...

  8. java单点登录原理与简单实现

    一.单系统登录机制 1.http无状态协议 web应用采用browser/server架构,http作为通信协议.http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关 ...

  9. 深入理解跨域SSO(单点登录)原理与技术

    一:SSO体系结构 SSO ​ SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他 ...

随机推荐

  1. mysql 案例 ~超时时间设置

    一 简介:今天咱们来谈谈mysql的连接时间与会话关系二 分类  mysql会话分类  1 程序连接session(最主要的)  2 binlog连接session(复制+canal消费)  3 ro ...

  2. C/C++中 # 的神奇作用:把宏参数字符串化/贴合宏参数

    一.一般用法   我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. #define STR(s) #s #define CONS(a,b) int(a##e##b) printf(ST ...

  3. 引入第三方SDK allowBackup value不一致引起的编译异常

    项目中要引入一个客服的SDK,项目中 <application android:name=".AppApplication" android:allowBackup=&quo ...

  4. zookeeper3.4.6配置实现自动清理日志【转】

    在使用zookeeper过程中,我们知道,会有dataDir和dataLogDir两个目录,分别用于snapshot和事务日志的输出(默认情况下只有dataDir目录,snapshot和事务日志都保存 ...

  5. css3实现不同进度条

    进度条类型1(渐变进度条) 效果1:图片实现进度条 思路,进度条是一张图片,用定位来控制不同时间图片相对进度条box的left值来控制位置,用animate实现动画效果 html <div cl ...

  6. 华为QUIDWAY系列路由器的单臂路由配置案例

    作者:邓聪聪 单臂路由 单臂路由(router-on-a-stick)是指在路由器的一个接口上通过配置子接口(或“逻辑接口”,并不存在真正物理接口)的方式,实现原来相互隔离的不同VLAN(虚拟局域网) ...

  7. python3+selenium入门08-鼠标事件

    使用click()可以模拟鼠标的左键点击事件,现在的web页面中有很多其他的鼠标交互方式,比如鼠标右击.双击.悬停.鼠标拖放等功能.在WebDriver中,将这些关于鼠标操作的方法封装在ActionC ...

  8. 设计模式C++学习笔记之二(Proxy代理模式)

      代理,一看名字就知道这只是个中介而已,真实的执行者在代理的后面呢.cbf4life在他的书里提的例子也很有趣,更详细的内容及说明可以参考原作者博客:cbf4life.cnblogs.com.现在贴 ...

  9. 【转】细说new与malloc的10点区别

    1.申请的内存所在位置 new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存.自由存储区是C++基于new操作符的一个抽象概念,凡是通过new ...

  10. hibernate框架学习之主键生成策略generator

    1)手工控制 assigned(不限制类型) 2)数据库自动生成 uuid(字符串类型) increment(整型数值类型) identity (整型数值类型) sequence (整型数值类型) n ...