WI/SSO 默认的 Eager Sign in 将用户认证信息直接提交到 WebSEAL 提供的认证表单,缺乏灵活性以及适用性。本文的解决方案在自定义登录页面和 WebSEAL 认证表单之间加入了中间过程,将该登录认证过程分为两步提交:1)提供一个自定义登录页面和 Servlet 用来收集用户认证信息,通常是用户名和口令;2)在服务器端将该 Servlet 收集到的认证信息连同必要的 HTTP 请求数据通过 HttpClient 一同提交到 WebSEAL 的认证表单,并根据 WebSEAL 返回的结果进行相应的处理。如果在认证过程中发生任何错误,通过结果处理可以转到自定义的错误页面,避免 WebSEAL 默认的认证错误处理。该解决方案的优点在于其灵活性以及适用性,可以有效地提升用户体验。
SSO 与 IBM WI/SSO
SSO 介绍
SSO 基本概念
单点登录(Single Sign On,简称为 SSO),是目前比较流行的企业业务整合的解决方案之一。利用 SSO,用户只需在应用服务器上登录一次,便可以访问启用了 SSO 域中的任何应用服务器,而无需再次登录。其实质就是获得对企业资源的访问权限。
单点登录不仅是企业应用集成(EAI)的一个重要方面,还是 SOA 按需时代的要求之一。它不仅降低安全风险和管理消耗,并且大大简化 SOA 的安全问题,从而提高服务之间的合作效率。
SSO 实现
SSO 并不是 Java EE 中的标准实现,而是各中间件提供商在提供 Java EE 应用服务器集群时提供的一种共享认证信息的机制,所以各厂商提供的实现方式不一样。例如 IBM 的 WebSphere 是通过 Cookies 记录认证信息,BEA 的 WebLogic 通过 Session 共享技术实现认证信息的共享,国内深圳金蝶的 Apusic 采用的技术和 BEA WebLogic 基本一致。
IBM WI/SSO 介绍
WI/SSO 基本概念及原理
IBM 提供的 SSO 解决方案——WI/SSO(Web Identity/Single Sign On)是 IBM 为其外部应用提供的标准用户服务,用来对 ibm.com 的用户进行注册,授权以及管理。它允许用户通过 IBM Tivoli Access Manager(TAM) 中的 WebSEAL 逆向代理安全服务器组件访问被保护的应用程序。WebSEAL 会对用户进行统一认证,并且管理用户认证信息。
图 1 WI/SSO 体系结构
如图 1 所示,WebSEAL 位于外部和内部防火墙之间的非保护区(Demilitarized Zone,DMZ),用来向绿色区域的 Web 服务器转发请求。它会一直跟踪受保护的 IP 地址,接收发往 Web 服务器或应用服务器的请求,提供认证和授权服务,并在发送请求前把该请求的地址更改为实际目标地址转发出去。
图 2 以一个典型的用户登录会话为例,描述了 WI/SSO 认证过程。
图 2 典型的用户登录会话场景
首先,用户请求 ibm.com 域中任何被 WebSEAL 保护的资源,并将用户名 / 口令或者证书提交给 WebSEAL,要求认证;
WebSEAL 利用 LDAP 注册表中存储的用户信息对用户进行认证;
WebSEAL 签发一个 LTPA 令牌,在本地缓存并发送给 Web 服务器,最后发送到应用服务器;
应用服务器接受令牌并允许用户访问受保护的资源;WebSEAL 通过将 SSL 会话标识或者用户请求带来的的其它 Cookie 映射到 LTPA 令牌来维护状态,并且将它们发送到应用服务器。
在整个认证过程中, WI/SSO 还提供一些用于单点登录的标准静态页面,例如登录页面、帐户被锁页面等等。通常这些静态页面用来重定向到 WI 用户服务应用中相应 JSP 页面,同时设置一些 Cookie 的值。表 1 列出了几个重要的静态 HTML 页面与 JSP 页面、Cookie 之间的对应关系。
表 1. WI/SSO 的几个标准页面
静态页面 | 相应的 JSP | 设置的 Cookies | 描述 |
login.html | login.jsp?persistParge=true | PD-ERR=%ERROR_CODE%
PD-REFPAGE=%URL% PD-REFERER=%REFERER% |
登录页面 |
acct_locked.html | acc_locked.jsp | PD-REFPAGE=%URL% | 五次登录,帐户被锁 |
help.html | help.jsp | PD-REFPAGE=%URL% | 已登录用户再次登录 |
WI/SSO 的登录认证方式
IBM WI/SSO 方案提供两种基本登录认证方式:
标准登录认证
使用标准方式登录认证时,在应用中页面中需要添加一个标记为类似“现在登录”的链接,指向受 WebSEAL 保护的任何资源,点击该链接将自动导向到 WI/SSO 登录页面(如图 3 所示)。
图 3 WI/SSO 登录页面
由图 3 可知,标准登录认证方式的登录页面是由 WebSEAL 统一提供的,这势必会导致在对遗留系统进行 SSO 方案集成时,登录、修改密码、出错等页面风格与企业应用风格不一致的问题,同时也会给用户造成一定的困惑。
为解决此问题,WI/SSO 中还提供另一种更为灵活的登录认证方式,这就是 Eager Sign in。
Eager Sign in 登录认证
Eager Sign in 登录认证方式允许应用提供根据企业应用风格自定义的登录页面,不再使用 WebSEAL 提供的标准登录页面,并且以 WebSEAL 所认可的方式提交认证请求。之后,WebSEAL 会对用户提交的认证信息进行认证,如果认证成功,会将用户重定向到应用指定的目标页面;否则,将用户重定向到 WebSEAL 标准的错误页面或者相应的登录 / 修改口令 / 用户被锁页面。
通过上面的介绍可以看到,Eager Sign in 登录认证方式的登录页面可以由企业应用自身提供,保持了遗留应用系统的整体风格,从而带来更完美的用户体验。因此,本文后面部分将着重介绍这种登录认证方式,并结合其不足提出改进的解决方案。
WI/SSO Eager Sign in
Eager Sign in
Eager Sign in 登录认证方式要求用户根据企业应用整体风格自定义登录页面。为了以 WebSEAL 所认可的方式提交用户认证请求,需要在自定义的登录页面中加入一个 Form 表单,如下所示:
<form action="../../pkmslogin.form" method="POST"
enctype="application/www-x-form-urlencoded">
该表单用来收集用户名和口令,并以设定的方式将用户名称 username 和口令 password 等参数 POST 到 WebSEAL 的标准登录表单 pkmslogin.form。WebSEAL 对用户进行认证,根据 WebSEAL 的配置将用户重定向到 loginredir.jsp 页面。该页面用来设置 IBMISS/IBMISP Cookie,并且将用户重定向到应用在 PD-SGNPAGE Cookie 指定的目标页面。至此,成功完成了整个 Eager Sign in 登录认证过程。
但是,如果在登录过程中出现任何错误,WebSEAL 会将用户自动重定向到标准的登录错误处理页面,比如标准的登录页面、修改口令页面、用户被锁页面等。下一小节将重点讨论 Eager Sign in 的不足并加以分析。
Eager Sign in 缺点
虽然 Eager Sign in 登录认证方式允许用户自定义登录页面,并且指定登录成功后所转向的目标页面,但是却不允许用户定制登录失败后的出错处理页面。显然这在某种程度上会影响用户的网络体验,主要体现为如下几个方面:
用户登录认证失败,页面会自动转向到 WI/SSO 所定义的标准登录页面,应用程序不能自定义错误处理页面以及控制页面转向流程;
当登录失败尝试超过五次时,会自动转向到标准的帐户锁定页面,页面并不十分友好。同样的,应用程序也不能自定义帐户锁定提示页面;
对所保护应用页面的请求都必须通过 WebSEAL 逆向代理服务器转向,降低了应用的性能;
不能和企业已有应用系统的认证模块相结合,企业应用整合困难;
将认证信息直接提交到 WebSEAL 提供的认证表单,缺乏灵活性和适用性。
分步登录认证方案
为解决 Eager Sign in 的几个问题,本文提供了利用 HttpClient 实现 WI/SSO Eager Sign in 的分步登录认证方案——在自定义登录页面和 WebSEAL 认证表单之间加入了中间过程,将用户登录认证过程分为两步提交。首先,应用提供自定义的登录页面自身用于采集用户认证信息,一般包括用户名和口令;其次,在服务器端将采集到的认证信息以及必要的 HTTP 请求数据通过 HttpClient 提交到 WebSEAL 的认证表单,并对认证结果分析处理。如果在认证过程中发生任何错误 , 通过结果处理可以转到自定义的错误页面,避免 WebSEAL 默认的认证错误处理。该解决方案的优点在于其灵活性以及适用性,可以有效地提升用户体验。
HttpClint 介绍
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然 java.net 工具包提供了通过 HTTP 访问互联网资源的基本功能,但它并不完全满足企业应用程序所需要的丰富性和灵活性要求。Apache HttpClient 提供了一个高效、快速更新、功能丰富的支持 HTTP(S) 协议的客户端编程工具,极大地方便网络访问应用开发。
HttpClient 的主要功能包括以下几个方面,更多详细的功能可以参见 HttpClient 的主页 http://commons.apache.org/httpclient。
实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
支持自动转向
支持 HTTPS 协议
分步认证方案
针对 Eager Sign in 登录认证方式不能控制登录流程等问题,本文提出了分步登录认证的方案,目的是利用 HttpClient 模拟客户端浏览器与 WebSEAL 进行交互,从而控制认证流程。若用户未通过认证,由 HttpClient 捕获 WebSEAL 响应的 HTTP 信息,并且对认证结果进行分析处理,最终将用户重定向到应用提供的登录处理页面,以获得极大的灵活性和适用性。该分步认证方案不仅可以控制 WebSEAL 认证流程,而且可以和企业应用很好的配合,从而兼容遗留认证模块。一旦认证成功,改进的登录认证方案就可以减少客户端浏览器与 WebSEAL 的交互,进而提高应用效率。
下面详细介绍利用 HttpClient 实现 WI/SSO 登录的分步认证策略:
第一步,提供自定义登录页面用以采集用户认证信息,包括用户名以及口令,设置 WebSEAL 认证表单需要的请求参数。
用户自定义的登录页面表单中的参数需要满足如下一些条件:
表单要 POST 到第二步所使用的 Servlet,也就是说表单使用这个 Servlet 为 Action
POST 请求主体必须包含如下三个参数:
用户名 username
口令 password
登录表单的类型 login-form-type
以用户名 / 口令方式认证时,login-form-type 的值必须为 "pwd"
content-length 请求头必须与请求体的长度相等
例如,使用 telenet 提交认证信息数据:
prompt>telnet webseal.example.com 80
Connected to webseal.example.com.
Escape character is '^]'.
POST /myServlet HTTP/1.1
host: webseal.webseal.com
content-length: 56
username=testuser&password=my0passwd&login-form-type=pwd
其中,login-form-type 指定了用户登录方式,例如:
用户名 / 口令登录表单: <INPUT TYPE="HIDDEN" NAME="login-form-type" VALUE="pwd">
令牌登录表单: <INPUT TYPE="HIDDEN" NAME="login-form-type" VALUE="token">
自定义的认证信息采集页面应该如下面的代码片段所示:
<form action="myServlet" enctype="application/x-www-form-urlencoded" method="post">
<input type="hidden" name="login-form-type" value="pwd"/>
<input type="text" name="username" id="username" value=""/>
<input type="password" name="password" id="password" value=""/>
</form>
第二步,将采集到的认证信息用户名和口令参数连同必要的 Cookie、Header 提交到 WebSEAL 的认证表单,并对返回结果进行分析处理。具体如下:
(1) 在向 WebSEAL 认证表单提交认证信息之前,首先利用 HttpClient Get 方法尝试获取一个受保护的页面,用于判断该用户是否已经登录。如果返回响应状态是 SC_OK 200,并且返回内容为所访问的受保护页面,则说明该页面已找到,用户可以直接访问到受保护的资源,即用户已经成功登录过,不需要再次提交认证信息;否则说明该用户没有登录,需要继续执行(2),向 WebSEAL 提交认证信息。
(2) 在提交认证请求之前,为了能控制页面转向流程,首先需要禁止 HttpClient Post 方法的自动转向功能:
将登录页面采集到的认证信息如用户名和口令参数连同必要的 Cookie、Header 拷贝到 postMethod 中。值得注意的是,为了符合 WebSEAL 的规范,定制登录成功页面,需要为 HttpClient 额外添加两个会话 Cookie,分别是 PD-SGNPAGE 和 PD-FROMPAGE。其中,
1. PD-SGNPAGE ——指定用户认证成功后所导向的目标页面编码后的 URL;
2. PD-FROMPAGE ——指定用户选择“取消”后所显示页面编码后的 URL。它必须是一个没有被保护的页面,并且可能是与目前所显示页面相同的页面(带有登录表单的页面)。
(3) 提交 postMethod 并判断返回状态代码:
int statusCode = ssoHttpClient.executeMethod(postMethod);
如果返回 SC_OK 200 状态,说明登录失败或者已经登录,转入认证失败处理,要么是无效的用户名 / 口令,要么是多次尝试失败被锁,要么是已经登录再次提交认证信息;如果返回 SC_MOVED_TEMPORARILY 302 状态,说明登录成功,将会重定向到 loginredir.jsp 页面,继续请求重定向页面,最终会重定向到受保护的目标页面。
其中,HTTP 的返回代码为 200 说明页面已经找到,对 GET 和 POST 请求的应答文档跟在后面。返回代码为 302 是暂时重定向,说明所请求的资源在一个不同的 URL 处临时保存。出现该状态代码时,HttpClient 的方法(和客户端浏览器类似)一般会自动访问 HTTP 请求头中 Location 头指定的 URL。将 HttpClient 的方法自动转向功能取消掉,所以需要再次发起请求才能完成重定向,这带来的好处是我们可以控制页面的转向。
认证结果分析处理
认证成功
图 4 认证成功流程
将认证信息提交到 WebSEAL 认证表单后,如果认证成功,则执行如图 4 所示的流程。请求 loginredir.jsp 页面,并判断返回状态代码,如果页面请求成功,会再次返回 SC_MOVED_TEMPORARILY 302 状态。同时,loginredir.jsp 还会根据用户标识设置 IBMISS 和 IBMISP 两个 Cookie 值,并重定向到 PD-SGNPAGE Cookie 中指定的登录成功后显示的目标页面。
继续请求用户指定的登录成功后显示的目标页面,并判断返回状态代码,如果请求成功,返回 SC_OK 200 状态,说明目标页面已经找到,可以访问受 WebSEAL 保护的页面。
为了将目标页面返回给用户浏览器端,还需要将 postMethod 中的 Header 和 HttpClient 获取到的 Cookie 加到 HttpServletResponse 中以发送给客户端浏览器。至此,用户完成登录认证,并定向到登录成功页面。
认证失败
图 5 描述了用户登录失败的情况。可以看到,由于分步登录方案人为控制认证流程,Servlet 可以捕获 WebSEAL 重定向到标准错误页面的响应,从而可以导向到应用自定义的错误页面。这样就避免了 Eager sign in 不能自定义错误处理页面的问题。
图 5 认证失败流程
将认证信息提交到 WebSEAL 认证表单后,如果认证失败,返回 SC_OK 200 状态,则执行如图 5 所示的流程。
WebSEAL 返回的响应页面内容如下:
<html>
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Set-Cookie" content="PD-REFPAGE=/pkmslogin.form;
path=/; domain=.ibm.com" />
<meta http-equiv="Set-Cookie" content="
PD-REFERER=https://webauth.ibm.com/SSOWithLTPA/login.jsp; path=/; domain=.ibm.com" />
<meta http-equiv="Set-Cookie" content="PD-ERR=0x132120c8; path=/; domain=.ibm.com" />
<meta http-equiv="Refresh" content="0; url=
https://www-304.ibm.com/usrsrvc/account/userservices/jsp/login.jsp?persistPage=true" />
<title>IBM Registration>/title>
</head>
</html>
可以看出,该页面的作用是设置 PD-REFPAGE、PD-REFERER 和 PD-ERR 三个 Cookie 值,并且交由客户端自动刷新页面到请求头中所指定的 URL,可能是要求再次登录或者帐户被锁的页面。在这里,我们可以通过匹配自动刷新的 URL 地址的方法判断用户认证的失败原因,包括如下两种情况:无效的用户名 / 口令,多次失败尝试用户被锁。另外还有一种情况是:用户已经登录但仍然提交认证信息到 WebSEAL 认证表单,自动刷新的目标 URL 会是 help.jsp。
其中,PD-REFPAGE 代表了用户所请求的页面或 WebSEAL 缓存的页面 url。这个 url 认证成功后 WebSEAL 所应该请求的页面。
PD-REFERER 代表了请求从哪儿来的页面,或是 HTTP referrer 请求头。如果用户在地址栏手动输入地址,或是使用书签触发一个登录的流程,该 Cookie 的值即为空“none”,意味着不能判定 referrer 请求头。
PD-ERR 通过登录或账户管理页面设置。该 Cookie 的值即错误编码用来查找错误信息。
认证失败的情况如下:
无效的用户名 / 口令
如果用户提交了非法或者无效的用户名 / 口令,则 WebSEAL 返回自动刷新到要求再次登录的页面,刷新的目标 URL 是 https://www-304.ibm.com/usrsrvc/account/userservices/jsp/login.jsp?persistPage=true
多次登录失败尝试
用户多次输入错误的用户名 / 口令,提交到 WebSEAL 认证表单,则 WebSEAL 返回自动刷新到提示用户被锁的页面,刷新的目标 URL 是 https://www-304.ibm.com/usrsrvc/account/userservices/jsp/acct_locked.jsp
已经登录再次提交认证信息
如果用户已经成功登录并且再次提交认证信息,则 WebSEAL 返回自动刷新到提示用户已经登录的页面,刷新的目标 URL 是 https://www-304.ibm.com/usrsrvc/account/userservices/jsp/help.jsp
最后,需要 Get 方法中的 Header 和 HttpClient 的 Cookie 一并加入 HttpServletResponse 中返回给用户,并根据分析的失败原因,重新请求应用中定义的相应错误处理页面。
从上面的介绍中可以看出,该方案保留了 Eager Sign in 方式自定义登录页面的优点,能够很好地和遗留系统的页面风格保持一致。还针对 Eager Sign in 方式缺少灵活性和适用性的问题,使用分步登录认证的策略,即使用 HttpClient 模拟客户端浏览器与 WebSEAL 进行交互认证。一旦在该过程中发生认证错误,HttpClient 能捕获该错误并重定向到应用本身的错误处理页面,这样也实现了错误页面的定制,提升了用户体验。
此外,由于分步登录的方案能够人为控制页面转向流程,使用户有可能在 WI/SSO 方案之外根据企业已有应用系统的认证策略增加一些安全措施,减少了迁移的工作量,做到了与遗留系统认证模块的完美结合。并且,由于集成了已有的认证策略,用户在登录之后,不必将受保护应用的所有页面请求都通过 WebSEAL 逆向代理服务器转向,从而提高了应用的性能。
遇到的问题及解决办法
下面介绍在利用 HttpClient 实现 WI/SSO Eager Sign in 过程中可能遇到的一些问题及其解决办法。
字符编码和 Content-Length 请求头
自定义登录页面的编码方式可能出现在不同地方,一是服务器返回的 HTTP 头中,二是得到的 html/xml 页面中。为正确读取认证信息,在服务器端读取用户提交的信息时必须指定字符编码。从请求中获取参数时,设置字符编码方式一般是:
httpRequest.setCharacterEncoding("UTF-8");
一旦设置完请求的编码方式,则会按照 UTF-8 的方式读取用户提交的参数值。
将参数通过 HttpClient 接口添加到 Post 方法后,HttpClient 会对整个提交的内容进行编码,从而导致实际的内容长度和请求 Content-Length 头不一致,所以最好在处理请求头时忽略 Content-Length 头。或者调用 HttpClient 接口对内容进行编码后获取新的内容长度,从而保证传入的 Content-Length 值和实际内容长度一致,以便能够正确的提交到 WebSEAL 认证表单。
String content = EncodingUtil.formUrlEncode(postMethod.getParameters(),
postMethod.getRequestCharSet());
postMethod.setRequestHeader("Content-Length", "" + content.length());
Cookie 处理
HttpClient Cookie 规范参数
在 HttpClient 中有两种方法来指定 Cookie 规范的使用:
HttpClient client = new HttpClient();
client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY);
这种方法设置的规范只对当前 HttpState 有效。另一种方法是指定系统的属性,对每个新建立的 HttpState 对象都有效。
System.setProperty(“apache.commons.httpclient.cookiespec”, “COMPATIBILITY”);
PD-ERR 和 PD-ID
用户认证成功后,会生成 PD-ID Cookie,当该 Cookie 被添加到客户浏览器之后,任何到受 SSO 保护的应用的请求都会附上该 Cookie。同样,用户输入了无效的用户名 / 口令提交到 WebSEAL 认证表单进行认证时,会生成 PD-ERR Cookie,除非显式地清除,该 Cookie 会一直存在客户端的请求中直到当前会话结束。
用户认证失败后,SSO 生成 PD-ERR 同时清除 PD-ID;用户再次提交正确的用户名 / 口令 , 认证成功后,SSO 会生成 PD-ID 同时清除 PD-ERR Cookie。所以我们需要在服务器端对客户浏览器的请求的 Cookie 和 HttpClient 认证结果中的 Cookie 进行同步,以到达认证状态的一致性。
Cookie 域
WI/SSO 所生成的所有 Cookie 的域都被指定为 ibm.com,从而保证在 ibm.com 域下的受 SSO 保护的应用之间作边界切换时能够共享 Cookie。但是有时候从请求中获取 Cookie 时 Domain 和 Path 可能都为空,所以不得不重置这些 Cookie,将其 Domain 设置为 ibm.com,Path 设置为“/”,这样,发送到 ibm.com 域下所有应用的请求都会附上这些 Cookie。
支持 HTTPS 协议
WI/SSO 依赖于 SSL 进行用户信息的传递。HttpClient 提供对 SSL 的支持,但是在使用 SSL 之前必须安装 JSSE。这里有两种方法可以打开 HTTPS 连接,一种是将服务器颁发的证书导入到本地的 keystore 中,另一种是扩展 HttpClient 来实现自动接受证书。就第一种方法可以参考引用中的 HttpClient 入门文章,下面介绍第二种方法。
扩展 HttpClient 实现自动接受证书
因为这种方法自动接受证书,因此存在一定的安全问题,所以在使用该方法前请仔细考虑应用系统的安全需求,在真正产品中并不建议使用自动接受证书或者接受所有证书。
具体步骤如下:
提供一个自定义的 Socket factory。自定义的类必须实现 HttpClient 接口 org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory,在实现接口的类中调用自定义的 X509TrustManager,就这些类的实现可以参考 HttpClient 官方网站。
创建一个 org.apache.commons.httpclient.protocol.Protocol 实例,指定协议名称和默认的端口号:Protocol https = new Protocol(“https”, new MySecureProtocolSocketFactory(), 443);
注册创建的 https 协议对象,然后就可以按照普通方式打开 HTTPS 的目标地址Protocol.registerProtocol(“https”, https);
HttpClient 重定向
HttpClient 支持自动转向处理,但是像 POST 和 PUT 方式这种要求接受后继服务的请求方式,暂时不支持自动转向,因此如果碰到 POST 方式提交后返回的是 301 或者 302 的话需要自己处理,所要请求的地址可以在头字段 location 中得到。不过需要注意的是,有时候 location 返回的可能是相对路径,因此需要对 location 返回的值做一些处理才可以发起向新地址的请求。
另外除了在头中包含的信息可能使页面发生重定向外,在页面中也有可能会发生页面的重定向。引起页面自动转发的标签是:<meta http-equiv="refresh" content="5; url=http://www.ibm.com/us">。如果你想在程序中也处理这种情况的话得自己分析页面来实现转向。需要注意的是,在上面那个标签中 url 的值也可以是一个相对地址,如果是这样的话,需要对它做一些处理后才可以转发。
为了禁止 httpClient 自动重定向,需要在 post 之前将 httpClient 的重定向功能关闭:
httpMethod.setFollowRedirects(false);
总结
本文针对 WI/SSO 中 Eager Sign in 的登录认证方式缺少灵活性和适用性的问题提出了分步登录的认证方案。该方案不仅保留了 Eager Sign in 方式自定义登录页面的优点,还实现了错误页面的定制,结合了已有系统的认证策略,从而做到与遗留系统认证模块的完美结合,提升了用户体验。
值得注意的是,我们并不能保证本文所提出的分布登录认证方案可以完美地实现企业应用单点登录集成。
<!-- 分页 --><!-- 分页end -->