shiro集成cas

  shiro是一个权限管理框架,将安全认证相关的功能抽取出来组成,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。为了能够为多个系统提供统一认证入口,又使用了cas,而且二者都涉及到对session管理,所以需要集成。

cas基本协议过程:

shiro集成cas_第1张图片

基础模式的SSO访问流程步骤:

  1. 访问服务:客户端发送请求访问应用系统提供的服务资源。
  2. 定向认证:客户端重定向用户请求到中心认证服务器。
  3. 用户认证:用户进行身份认证
  4. 发放票据:服务器会产生一个随机的 Service Ticket 。
  5. 验证票据: SSO 服务器验证票据 Service Ticket 的合法性,验证通过后,允许客户端访问服务。
  6. 传输用户信息: SSO 服务器验证票据通过后,传输用户认证结果信息给客户端。

cas认证时序图

shiro集成cas_第2张图片

       对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到Service 和新产生的 Ticket 过后,在第 5,6 步中与 CAS Server 进行身份合适,以确保 Service Ticket 的合法性。

       在该协议中,所有与 CAS 的交互均采用 SSL 协议,确保,ST 和 TGC 的安全性。协议工作过程中会有 2 次重定向的过程,但是 CAS Client 与 CAS Server 之间进行 Ticket 验证的过程对于用户是透明的。

Shiro CAS 认证流程

·       1 用户首次访问受保护 的资源;例如 http://casclient/security/view.do

·       2 由于未通过认证,Shiro首先把请求地址(http://casclient/security/view.do)缓存起来。

·        3然后跳转到 CAS服务器进行登录认证,在 CAS 服务端认证完成后需要返回到请求的 CAS 客户端,因此在请求时,必须在参数中添加返回地址 ( 在 Shiro 中名为 CAS Service)。 例如 http://casserver/login?service=http://casclient/shiro-cas

·        4由CAS服务器认证通过后,CAS 服务器为返回地址添加ticket。例如http://casclient/shiro-cas?ticket=ST-4-BWMEnXfpxfVD2jrkVaLl-cas

·        5接下来,Shiro会校验 ticket 是否有效。由于 CAS 客户端不提供直接认证,所以 Shiro 会向 CAS 服务端发起 ticket 校验检查,只有服务端返回成功时,Shiro 才认为认证通过。

·        6认证通过,进入授权检查。Shiro授权检查与前面提到的相同。

·       7 最后授权检查通过,用户正常访问到 http://casclient/security/view.do

项目中配置:

[java]  view plain  copy
  1. Shiro在1.2.0的时候提供了对cas的集成。因此在项目中添加shiro-cas的依赖  
  2.       
  3.        org.apache.shiro  
  4.       shiro-cas  
  5.        ${shiro.version}  
  6.       
         Shirocas集成后,cas client的配置更加简单了。原理就是将casFilter添加到到shiroFilter的filterChain中。   shiroFilter是在web.xml中定义的
[java]  view plain  copy
  1. "1.0" encoding="UTF-8"?>  
  2. "http://www.springframework.org/schema/beans"  
  3.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"  
  5.     xmlns:context="http://www.springframework.org/schema/context"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  7.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
  8.     http://www.springframework.org/schema/aop   
  9.     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd   
  10.     http://www.springframework.org/schema/tx    
  11.     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd   
  12.     http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd  
  13.     http://www.springframework.org/schema/context  
  14.     http://www.springframework.org/schema/context/spring-context-3.0.xsd"  
  15.     default-lazy-init="true">  
  16.   
  17.       
  18.        
  19.   
  20.       
  21.     "propertyConfigurer"  
  22.         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  23.         "locations">  
  24.               
  25.                 classpath:config/shiro-cas.properties  
  26.               
  27.           
  28.   
  29.       
  30.   
  31.       
  32.   
  33.       
  34.   
  35.       
  36.     "redisManager" class="com.tgb.itoo.authority.cache.RedisManager">  
  37.   
  38.     "redisCache" class="com.tgb.itoo.authority.cache.RedisCache">  
  39.         "redisManager">  
  40.       
  41.   
  42.       
  43.     "redisCacheManager" class="com.tgb.itoo.authority.cache.RedisCacheManager">  
  44.         "redisManager" ref="redisManager" />  
  45.       
  46.   
  47.       
  48.   
  49.       
  50.     "redisShiroSessionDAO" class="com.tgb.itoo.authority.cache.RedisSessionDAO">  
  51.         "redisManager" ref="redisManager" />  
  52.       
  53.   
  54.       
  55.     "sharesession" class="org.apache.shiro.web.servlet.SimpleCookie">  
  56.           
  57.         "name" value="SHAREJSESSIONID" />  
  58.           
  59.         "path" value="/" />  
  60.       
  61.   
  62.       
  63.     "sessionManager"  
  64.         class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  65.           
  66.         "globalSessionTimeout" value="1800000" />  
  67.           
  68.         "deleteInvalidSessions" value="true" />  
  69.   
  70.           
  71.         "sessionValidationInterval" value="1800000" />  
  72.   
  73.           
  74.         "sessionDAO" ref="redisShiroSessionDAO" />  
  75.           
  76.         "sessionIdCookie" ref="sharesession" />  
  77.           
  78.         "sessionValidationSchedulerEnabled" value="true" />  
  79.   
  80.       
  81.   
  82.   
  83.       
  84.   
  85.       
  86.   
  87.   
  88.     "color:#ff0000;">  
  89.   
  90.       
  91.     "shiroRealm" class="com.tgb.itoo.authority.service.ShiroRealmBean">  
  92.         "defaultRoles" value="user">  
  93.           
  94.         "casServerUrlPrefix" value="${casServerUrlPrefix}">  
  95.         "casService" value="${casService}">  
  96.       
  97.   
  98.       
  99.     "casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory" />  
  100.   
  101.     "color:#ff0000;">  
  102.     "securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  103.         "realm" ref="shiroRealm">  
  104.         "sessionMode" value="http">  
  105.         "subjectFactory" ref="casSubjectFactory">  
  106.         "cacheManager" ref="redisCacheManager" />  
  107.         "sessionManager" ref="sessionManager">  
  108.       
  109.   
  110.       
  111.     "lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  112.   
  113.       
  114.     
  115.         class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
  116.         depends-on="lifecycleBeanPostProcessor">  
  117.     
  118.         class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  119.         "securityManager" ref="securityManager" />  
  120.       
  121.   
  122.       
  123.   
  124.   
  125.     "color:#ff0000;">  
  126.       
  127.     "shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  128.         "securityManager" ref="securityManager">  
  129.         "loginUrl" value="${loginUrl}">  
  130.         "filters">  
  131.               
[java]  view plain  copy
  1. "color:#ff0000;">class="comments">                                   
  2.                 "casFilter">  
  3.                     class="org.apache.shiro.cas.CasFilter">  
  4.                           
  5.                         "failureUrl" value="/message.jsp" />  
  6.                         "successUrl" value="getSystemindex" />  
  7.                       
  8.                         
  9.               
  10.           
  11.           
  12.         "filterChainDefinitions">  
  13.               
  14.                 /mobile_**/**=anon  
  15.                 /message.jsp=anon  
  16.                 /shiro-cas=casFilter  
  17.                   
  18.                 /logout=logout  
  19.                 /**=user  
  20.               
  21.           
  22.       
  23.       
  24.       
  25.   
  26.   

shiroRealmBean:负责授权

[java]  view plain  copy
  1. package com.tgb.itoo.authority.service;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.List;  
  5. import org.apache.shiro.authz.AuthorizationInfo;  
  6. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  7. import org.apache.shiro.cas.CasRealm;  
  8. import org.apache.shiro.subject.PrincipalCollection;  
  9.   
  10. /** 
  11.  *  
  12.  * @author hanyi 
  13.  * 
  14.  */  
  15. public class ShiroRealmBean extends CasRealm {  
  16.   
  17.     private ShiroBean permissionMgr;  
  18.   
  19.     /** 
  20.      * 负责授权 
  21.      */  
  22.     @Override  
  23.     protected AuthorizationInfo doGetAuthorizationInfo(  
  24.             PrincipalCollection principals) {  
  25.   
  26.         String permissionName;  
  27.         try {  
  28.             //得到userCode  
  29.             SimpleAuthorizationInfo author = new SimpleAuthorizationInfo();  
  30.             String  userCode = (String) principals.getPrimaryPrincipal();  
  31.   
  32.             //通过自己写的实现来得到用户权限集合  
  33.             List lstPermission = permissionMgr  
  34.                     .queryUserPermission(userCode);  
  35.             Iterator it = lstPermission.iterator();  
  36.   
  37.             //遍历权限集合添加到授权信息对象  
  38.             while (it.hasNext()) {  
  39.                 permissionName = it.next().toString();  
  40.                 author.addStringPermission(permissionName);  
  41.             }  
  42.   
  43.             return author;  
  44.   
  45.         } catch (Exception e) {  
  46.             e.printStackTrace();  
  47.             return null;  
  48.         }  
  49.     }  
  50.   
  51.   
  52.     public ShiroBean getPermissionMgr() {  
  53.         return permissionMgr;  
  54.     }  
  55.   
  56.     public void setPermissionMgr(ShiroBean permissionMgr) {  
  57.         this.permissionMgr = permissionMgr;  
  58.     }  
  59.   
  60. }  

说明:shiroRealmBean继承了CasRealm,CasRealm又继承了AuthorizingRealm。所以,

shiroRealmBean中具体写了授权实现逻辑,而认证则调用了CasRealm中的方法

shiro-cas.properties文件

[java]  view plain  copy
  1. "font-size:18px;">loginUrl=http://192.168.22.246:8888/cas/login?service=http://localhost:8091/itoo-exam-template-web/shiro-cas  
  2. successUrl=http://localhost:8091/itoo-exam-template-web/addTemplet  
  3. casServerUrlPrefix=http://192.168.22.246:8888/cas  
  4. casService=http://localhost:8091/itoo-exam-template-web/shiro-cas  

说明:

loginUrl:cas登录页面(带有请求的受保护资源,用于返回时)

casServerUrlPrefix是CAS服务端地址。

casService是应用服务地址,用来接收CAS服务端票据。

    没有单点登录情况下的话,登录认证和授权认证默认在AuthorizingRealm的doGetAuthorizationInfo和doGetAuthenticationInfo中进行,所以我这里是通过shiroDbRealm(继承AuthorizingRealm的自定义类)覆写doGetAuthorizationInfo和doGetAuthenticationInfo,实现自定义登录认证和授权认证。

 

     有单点登录情况下,登录认证是在casserver进行的,那么执行流程是这样的:用户从 cas server登录成功后,跳到cas client的CasRealm执行默认的doGetAuthorizationInfo和doGetAuthenticationInfo,此时doGetAuthenticationInfo做的工作是把登录用户信息传递给shiro,保持默认即可,而对于授权的处理,可以通过MyCasRealm(继承CasRealm的自定义类)覆写doGetAuthorizationInfo进行自定义授权认证。

你可能感兴趣的:(Shiro)