SSO总结

http://blog.csdn.net/small_love/article/details/6664831(CAS实现单点登录(SSO)经典完整教程)
单点登录
1.单点登录(Single Sign On),简称为 SSO.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
2.CASJava客户端登录相关过滤器的处理流程
   首先了解一下CAS登录原理:
   1.CAS结构中一般包含CAS服务器、应用服务器、客户端三个部分。客户端向应用服务器发出请求,由于未登录,会被跳转到CAS服务器登
     录。登录成功后跳转回应用服务器的登录前的URL,但是CAS服务器会给URL加上一个ticket参数。应用服务器拿着ticket去CAS服务器验证,
     验证成功后即加入一个session表示已登录,以后就不用再次登录了。
   2.整理一下整个登录流程:
     1.第一次请求应用服务器:
       当用户第一次访问应用服务器的URL,由于session中没有"_const_cas_assertion_"且参数中没有ticket,
       会被AuthenticationFilter跳转到CAS服务器的登录页面
     2.第二次请求应用服务器:
       在CAS服务器的登录页面成功登录以后,会跳转到应用服务器登录前的页面,但是加上了一个参数ticket。此次请求由于有ticket参数,
       通过了AuthenticationFilter,但是TicketValidationFilter会对ticket进行校验,校验成功后,会在session中加入"_const_cas_assertion_",再去掉
       ticket参数进行一次跳转
     3.第三次请求应用服务器:
       此时由于session中已经有了"_const_cas_assertion_",会通过AuthenticationFilter,由于没有ticket参数,也通过了TicketValidationFilter,
       也就是可以正常显示出这个页面了.以后再请求应用服务器就和这次一样了,由于session包含"_const_cas_assertion_"即可正常访问
   3. request.getSession().invalidate() 能否释放内存?
      这个会使得整个客户端对应的Session失效,里面的所有东西都会清空了,同时也释放了资源.
      但是你所描述的需求应该不是让客户端对应的Session失效,而是通过Session传递数据后,释放传递数据所占用的资源.
      应该是你在getAttribute后通过request.getSession().remove方法删除你传递的对象就可以了,不必要让整个Session失效


OAuth 2.0协议学习
1.OAuth是一个关于授权(authorization)的开放网络标准
2.OAuth的思路
  2.1 OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。"客户端"不能直接登录"服
      务提供商",只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与
      用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期.
      "客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。
3.运行流程
  (A)用户打开客户端以后,客户端要求用户给予授权
  (B)用户同意给予客户端授权
  (C)客户端使用上一步获得的授权,向认证服务器申请令牌
  (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌
  (E)客户端使用令牌,向资源服务器申请获取资源
  (F)资源服务器确认令牌无误,同意向客户端开放资源
4.客户端的授权模式
     客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0定义了四种授权方式
     1.授权码模式(authorization code)
授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服
务器,与"服务提供商"的认证服务器进行互动
运行流程:
(A)用户访问客户端,后者将前者导向认证服务器
(B)用户选择是否给予客户端授权
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
     2.简化模式(implicit)
     3.密码模式(resource owner password credentials)
     4.客户端模式(client credentials)






2.2.  SSO 原理
2.2.1.      SSO 体系中的角色
      一般 SSO 体系主要角色有三种:1、 User (多个)  2、 Web 应用(多个)  3、 SSO 认证中心( 1 个 )
2.2.2.      SSO 实现模式的原则
      SSO 实现模式一般包括以下三个原则:
          1、   Web 应用不处理 User 的登录,否则就是多点登陆了,所有的登录都在 SSO 认证中心进行
 2、   SSO 认证中心通过一些方法来告诉 Web 应用当前访问用户究竟是不是已通过认证的用户;


CAS 的基本原理
从结构体系看, CAS 包括两部分: CAS Server 和 CAS Client 。
3.1.1.      CAS Server
CAS Server 负责完成对用户的认证工作 , 需要独立部署 , CAS Server 会处理用户名 / 密码等凭证
3.1.2.      CAS Client
负责处理对客户端受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。
(原则上,客户端应用不再接受任何的用户名密码等 Credentials )。
CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。


CAS 的 SSO 实现方式可简化理解为: 1 个 Cookie 和 N 个 Session 。 CAS Server 创建 cookie,在所有应用认证时使用,各应用通过创建各自的 Session 来标识用户是否已登录。
用户在一个应用验证通过后,以后用户在同一浏览器里访问此应用时,客户端应用中的过滤器会在 session 里读取到用户信息,所以就不会去 CAS Server 认证。如果在此浏览器里访问别的 web 应用时,
客户端应用中的过滤器在 session 里读取不到用户信息,就会去 CAS Server 的 login 接口认证,但这时CAS Server 会读取到浏览器传来的 cookie ( TGC ),所以 CAS Server 不会要求用户去登录页面登录
,只是会根据 service 参数生成一个 Ticket ,然后再和 web 应用做一个验证 ticket 的交互而已


Ticket-granting cookie(TGC) :存放用户身份认证凭证的 cookie ,在浏览器和 CAS Server 间通讯时使用,并且只能基于安全通道传输( Https ),
是 CAS Server 用来明确用户身份的凭证


基础模式 SSO 访问流程主要有以下步骤:
1. 访问服务: SSO 客户端发送请求访问应用系统提供的服务资源。
2. 定向认证: SSO 客户端会重定向用户请求到 SSO 服务器。
3. 用户认证:用户身份认证。
4. 发放票据: SSO 服务器会产生一个随机的 Service Ticket 。
5. 验证票据: SSO 服务器验证票据 Service Ticket 的合法性,验证通过后,允许客户端访问服务。
6. 传输用户信息: SSO 服务器验证票据通过后,传输用户认证结果信息给客户端。
下面是 CAS 最基本的协议过程:
http://www.coin163.com/java/cas/cas.html
1. 浏览器   发起访问WebAPP 请求:  http://www.web.com/app
2. 客户端  AuthenticationFilter Filter 发现Session中无 Assertion,且URL中无 ticket 变量。生成 service url 变量,并重定向到:  https://www.cas-server.com/cas/login?service=http://www.web.com/app
3. CAS server  生成 Login ticket, service 对象,并展示 login 页面,默认提供 username / password 给用户验证。
4. CAS server 端,用户输入 username / password 验证,若通过则生成TGT,存入服务器段(默认为 Map 类型的 cache),同时将TGT id 作为 content创建 cookie 并发送到浏览器。
5. CAS server 端通过TGT 生成service ticket.  重定向到 http://www.web.com/app?ticket=ST-xxx
6. 客户端   访问 http://www.web.com/app?ticket=ST-xxx 
7. 客户端   AuthenticationFilter Filter 发现URL中有 ticket, 跳过 AuthenticationFilter过滤器,到达 Cas20ProxyReceivingTicketValidationFilter过滤器。
8. 客户端 生成验证 service url:  http://www.web.com/app
9. 客户端   Cas20ProxyReceivingTicketValidationFilter 过滤器,使用6处的ticket 与8处的 service 作为参数验证。
  9.1  客户端 生成验证 servlet: https://www.cas-server.com/cas/serviceValidate?ticket=ST-xxx&service=http://www.web.com/app
  9.2  客户端 通过HttpClient访问 9.1 的 url
                注:AbstractUrlBasedTicketValidator.java line 207,如果是用CAS ptotocol验证,则第二个参数 ticket无用。
                得到如下形式的 response:
 9.3  客户端 解析 response 字符串,生成 assertion (包含 username, validate info 等)
   9.4  客户端 设置 assertion 为 request 的 _const_cas_assertion_ 属性,同时会将assertion记录到session 中去。
   9.5  客户端 如果设置了重定向属性,则重定向到 http://www.web.com/app  --  转步骤10
              否则继续执行以后的 filter,通过servlet 访问 http://www.web.com/app 服务,结束CAS的验证。
用户已成功登录,非第一次访问:
10. 客户端 通过重定向访问 http://www.web.com/app
11. 客户端 AuthenticationFilter Filter 发现 session 中有Assertion, 结束本过滤器,转移到下一个过滤器 Cas20ProxyReceivingTicketValidationFilter.
12. 客户段 Cas20ProxyReceivingTicketValidationFilter 发现 本次访问的URL 无 ticket,结束本次过滤,转移到下一个过滤器,继续执行以后的 filter,通过servlet 访问 http://www.web.com/app 服务。


PostMethod postMethod = new PostMethod("http://10.24.0.115:30013/ysyt/api/b2b2c/goodsRecomment!queryOnTailGoodPage.do");
postMethod.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded;charset=utf-8");
// 增加变量
postMethod.addParameter("userId", sessionUser.getUserId());
client.executeMethod(postMethod);
String str = "";
str = new String(postMethod.getResponseBodyAsString());
postMethod.releaseConnection();
JSONObject jsonObj = JSONObject.fromObject(str);
int result = jsonObj.optInt("result");
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
if (1==result) {
JSONArray jsonArray = jsonObj.optJSONObject("data").optJSONArray("list");
if (jsonArray!=null && jsonArray.size()!=0) {
for (int i = 0; i < jsonArray.size(); i++) {
Map<String, Object> resultMap = MapUtils.newHashMap();
JSONObject jObject = jsonArray.optJSONObject(i);
resultMap.put("appId", jObject.opt("goods_id"));
resultMap.put("appName", jObject.opt("app_name"));
resultMap.put("traiEndTime", jObject.opt("trial_end_time")!=null?jObject.optInt("trial_end_time")*1000:0);
resultMap.put("appIcon", jObject.opt("app_icon"));
list.add(resultMap);
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值