在分布式应用中,单点登录系统有着举足轻重的地位。

浅谈单点登录系统sso的实现 - 图1

实现思路

如何动手实现一个简单的单点登录系统呢?下面是实现思路:

  1. 在子系统中设置一个过滤器,用于过滤所有的请求。当请求过来时,首先判断有没有登录过,如果没有登录过,则跳转到单点登录系统尝试登录。
  2. 登录完成后,在单点登录系统中用一个Map结构缓存登录信息。Map中的key可以是一个uuid,val保存登录信息,如用户名,所属部门等。
  3. 信息缓存后,再通过url重定向的方式跳转回子系统,并带上登录信息(在重定向url中添加上登录信息参数,参数值为上面生成的key)。

  4. 子系统接收到跳转回来的请求后,取出url中的登录参数,然后向单点登录系统验证参数的有效性,验证成功后完成登录。

在上述思路中,有几个细节需要考虑:

  • sso登录成功后如何告知子系统登录信息?
  • 系统如何存储登录信息,从而判断有没有登录过?
  • 如何实现跨子系统间的登录信息共享?

sso登录成功后的跳转

上面提到的,可以在重定向中的url中添加上登录信息参数,如上面生成的map key。实际上这样比较不安全,因为url地址是很容易获取到的,也就意味着拦截到登录参数后,可以实现无限制的身份验证。为了解决该问题,可以在sso中生成一个临时票据,用于与登录map中的key相对应,这个临时票据是一次性的,用完即销毁。然后将这个临时票据传递到子系统中,子系统拿到临时票据后去sso进行验证。

子系统存储登录信息

BS系统的身份识别一般有session和cookie两种方式,在分布式环境下,session容易出现同步问题,因此可以将信息缓存到浏览器端的cookie中。用于登录验证的过滤器捕获请求后,查找有没有对应的cookie信息。
cookie信息最多可以在同一主域之间共享,如果子系统在不同的域下,则需要用nginx解决一下域名问题,或者让请求提交到本系统后台,处理一下response对象,然后跳转到具体的系统。