统一身份证自定义协议(2)

上一篇文章介绍了自定义协议,但是从某种角度来看,上面的自定义协议并不是一个完全可靠的协议,为何?待我慢慢道来。

简单的来讲,统一身份认证应该分为两块,一是身份认证,一是统一认证(可以理解为sso),如果要集成多协议,比如SAMLCAS,是在统一认证进行集成,而不是身份认证。

1

  •  1)何为身份认证,我们从图1 的过程来阐述。假设用户没有登陆过任何系统,某用户访问sp1sp1检查发现该用户没有登陆过,即重定向到ServerServer返回一个页面让用户输入用户名、密码等,然后提交表单到Server进行验证。红色部分即为身份认证的过程。为什么,因为对于CASSAML协议来说,不关注用户的身份认证的过程,而是关注步骤6返回的内容是否是符合某个协议格式的内容当然内容是加密过的)当该用户访问sp2时,sp2发现该用户没有登陆过,重定向到ServerServer检查发现该用户已经认证过,即生产相应格式的响应到sp2sp2检查校验通过,即可访问sp2,而这个过程可以理解为统一认证过程(简单的来讲就是抛开步骤3的过程)
  • 2)在有前面的基础后,我们来阐述为什么自定义协议1并不是一个可靠的协议,到底不可靠在哪?问题出在了身份认证过程中,即步骤3以后的操作,我们知道步骤3会发起一个身份认证的请求,而Server并不能认证身份,而是将请求进行封装加上自己的签名交给了Engine进行认证,认证后返回UA票据,而Server根据持有的UA票据向Engine申请SP票据和Server票据(我们知道sp票据是Engine用sp的公钥进行签名加密的,Server票据是Engine用Server的公钥进行签名加密的),问题就出在这里,这里导致了Server的权限过大,Server不能为sp进行签名,如果Server要求Engine为非sp签名的请求进行签名加密,即产生了伪造。举个简单的例子来说:有A、B、C三人(A可理解为sp,B为Server,C为Engine),C负责印章,当A来盖章的时候,C认识A,C识别到A允许签名盖章、B来盖章的时候,C认识B,C也可以为B签名盖章,但不允许B在没有A的委托下为A进行签名盖章(即B跟C说为我盖个A的章吧,这是不允许的)。换个更简单的例子就是使用银行卡消费时,只有本人签名才有效,不能说A消费时签B的名,这不符合安全的理念。现在我们来改进自定协议1,让它变得更安全。

1.原理和协议

结构上,自定义协议还是包括SP、IDP Server和IDP Engine三部分。这时候我们需要建立一个信任体系,我们认为IDP Server是可信的。

第一步,sp、IDP Server和IDP Engine都有自己的身份的,所以我们首先得认证自己和对方,但是我们的信任体系的建立是我们认为IDP Server是可信的。

第二步,SP和IDP Server需要向IDP Engine注册生成自己的编号和密钥。

如下图所示:

图2

    协议交互流程如下:
  •  1.SP初始化的时候,因为信任体系是信任Server,SP的统一认证交给Server,这时候需要建立一个SP和Server之间的共享密钥。如何申请?SP用自己的密钥签名向Server发起一个代理向Engine申请共享密钥的申请(为什么是向Engine,因为只有Engine知道sp和Server的密钥,也只有Engine能产生共享密钥,相当于就是Engine就是sp和Server信任的桥梁,共享密钥是有时间限制的,一般来讲一天)
  • 2.Server认证不了请求的真实性,于是加上自己的签名将请求转发给Engine,Engine认证该请求来自SP和Server(因为Server加上了自己的签名),认证通过,生成共享密钥,分别使用sp的密钥和Server的加密返回给Server和sp,于是SP和Server持有了sp和Server之间的共享密钥。
  • 3.UA访问SP,SP判断该用户是否已经登录,如果没有登录,SP产生认证请求;如果用户已经登录,直接响应结果。
  • 4.SP重定向到IDP Server,URL带有AuthnRequest参数,如果已经登录,跳转到5;如果没有登录,返回登录页面,进行认证操作。
  • 5.UA输入用户密码等生成身份认证请求,URL带有CredentialsRequest参数。IDP Server接收到认证请求后,首先判断请求的合法性。然后判断该用户是否已经成功单点登录。如果用户登录过,则IDP Server使用sp和IDP Server的共享密钥生成响应到sp;如果未登录过,则跳转到4。
  • 6.IDP Server将CredentialsRequest请求参数包装成Credentials加上自己的签名向IDP Engine发出身份认证请求(IDP Server需要向IDP Engine认证自己的身份,相当于sp委托IDP Server 向IDP Engine认证自己的身份),如果认证通过,IDP Engine 使用 IDP Server的密钥加密结果并返回给IDP Server。
  • 7.IDP Server根据请求协议将IDP Engine返回的结果包装成不同的协议并将其使用sp和 IDP Server之间的共享密钥进行加密返回给sp。
  • 8.SP检查验证密文。

 

2.安全性

1.保证了只有SP的请求才能让Engine为SP签名,不会出现IDP Server权利过大的问题保证安全,解决了自定义协议1的存在的不足,安全性更进一步提高。

2.将身份认证和统一认证分开,更容易集成多协议的支持。

3.设计实现

3.1数据交互方式

通过URL传递数据。

3.2参数格式

3.2.1. AuthnRequest

内容

由SP属性集合、callbackURL、签名组成

注:CallbackURL不是必须,可以使用IDP Engine注册的默认callbackURL

格式

Sp属性集合

1、Sp编号:sp

元素之间以“;”分隔,key与value之间用“:”分隔

比如:sp:12345;authnReqID:abc123;sign:signValue

callbackURL:service

签名:对请求属性使用共享密钥进行加密

请求格式组成 req=请求属性格式&service=callbackURL

编码

Base64,在网络以Base64编码传输

 
3.2.2. CredentialsRequest

内容

由请求属性集合,签名和callbackURL组成

格式

l请求的属性主要有:

1、身份(由用户名和域组成,格式: 用户名@域): principal

2、当前时间:time

3、票据类型:type

4、随机数标识:nonce

5、IDP Server代理:agent

6、引用: reference

7、sp编号:sp

格式:time:x;type:x;principal:x;nonce:x;agent:x;reference:x;sp:x

元素之间以“;”分隔,key与value之间用“:”分隔

l签名,对请求属性用私有密钥加密生成密文,格式:

sign=加密算法:密文

私有密钥由用户名、域和密码 md5而成,格式

域 + ":" + 用户 + ":" + 密码

lcallbackURL:service

请求格式组成 req=请求属性格式&sign=签名&service=xxxx

编码

Base64,在网络以Base64编码传输

猜你喜欢

转载自udukwilliam.iteye.com/blog/1703783