- 浏览: 252654 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
mabusyao:
漠北空城 写道请问下,你这个是JDK版本是多少呢?!忘记了,应 ...
HashMap 源码解读 -
漠北空城:
请问下,你这个是JDK版本是多少呢?!
HashMap 源码解读 -
schumee:
完美团队~
项目沉思录 - 1.1 -
winie:
整理下 搞成引擎嘛 国产需要这样的engine
简单工作流引擎 -
mabusyao:
某位同学给我提供的堪称完美的解决方案:1. 将三个int数组放 ...
CraneWork
很多门户网站的用户验证都是通过服务器提供的验证方式来实现的, 比如说,WAS就可以配置LDAP作为用户验证的数据源。当用户访问一个受限制的网页时,如果用户没有权限,便会自动跳转到登录界面。当用户登录后,再跳转回到用户之前访问的页面。
前两天遇到个问题,当用户登录后,IE在某些情况下,不会自动跳转到登录前页面,而是回到了welcome页面。
这个问题折磨了我快一周的时间,绞尽脑汁找不出原因。而且这个defect不是总能重现,因此很难找到原因。
后来想了想,换一条路,我们可以从WAS的验证机制入手,看看有没有什么漏洞所在。
在网上找了很多有用的文章,一篇一篇帖出来,最后形成了我的解决办法:
文章1:
企业信息化建设多年,建立了包括人事、财务、市场、销售、客户关系管理等一系列的业务和应用信息系统。这些系统种类繁多并且由不同的应用开发商提供,比如 SAP、金碟的 ERP 软件,微软、ORACLE、用友的财务软件等等。不同的系统和开发商有自己专用的一套用户存储和管理系统 ( 存储用户名口令和组等信息 -- username, password, group etc),例如早期的各种 Unix、Windows 操作系统帐号、后来的各种关系型数据库、以及目录服务器等等。混乱的用户存储和管理系统给企业 IT 管理带来了繁重的维护工作量和新的问题,企业很希望信息系统能采用标准的用户注册表,轻量级目录访问协议 LDAP 由于标准化是一种比较理想的选择。
有关 IBM WebShpere 应用服务器安全性、如何配置 LDAP 的文章已经很多,但是大多数是 6.0 以前的版本。在 6.0 以前,WebSphere 只能配置一种用户注册表,比如操作系统、目录服务器、定制用户注册表。
本文介绍 WebSphere 6.1 的新特性“联合存储库”,如何为联合存储库配置 LDAP 服务器,以及如何迁移 J2EE Web 应用程序以使用 J2EE 规范的表单认证,进而能通过 WebSphere 6.x 的存储库 ( 联合存储库、其他支持的用户注册表 ) 进行身份认证和授权。
我们会首先来了解一下 WebSphere 6.1 的最新特性“联合存储库”,看看它和 6.0 用户注册表有什么区别,它是如何同时使用多种存储库进行身份认证的;接下来,我们来看看如何配置“联合存储库”,让它能够使用 LDAP 外部存储库进行身份认证;配置 LDAP 身份认证是一个需要多方面知识和经验的工作,我们需要掌握在 WebSphere 配置 LDAP 的过程中如何进行排错 (trouble shooting) 的技能。配置好了 WebSphere“联合存储库”,WebSphere 缺省的例子应用、服务器管理控制台已经可以通过“联合存储库”进行身份认证,但是我们现有的部署在 WebSphere 上面的业务应用系统并不能马上自动地使用到这一特性。让我们分析一下现有的 J2EE 应用 -- 以 Struts 例子应用为代表,分析一下现有应用常用的认证机制;接下来我们会设定一下移植现有 J2EE 应用到使用 J2EE 表单登录认证和“联合存储库”的移植目标;根据这个目标,我们对 Struts 例子应用进行移植,为它增加标准的 J2EE 表单登录方式,增加新的 J2EE 标准格式的 Form 登录页面,最后为 Struts 应用增加新的代码,在用户通过新的 J2EE 标准格式的 Form 登录页面登录以后,后台应用系统如何为登录用户构造用户会话信息。
WAS V6.1 用户帐号存储库介绍
首先,我们来了解一下 WebSphere 6.1 的最新特性“联合存储库”,看看它和 6.0 用户注册表有什么区别,它是如何同时使用多种存储库进行身份认证的。
IBM WAS 可以借助管理员配置的用户帐号存储库,帮助运行在 WAS 上面的 J2EE 应用程序以标准的 J2EE 认证方式进行用户身份认证。换言之,J2EE 应用程序可以使用 WAS 上面配置的用户帐号存储库进行统一的用户身份认证。
WAS V6.0 提供了本地操作系统、独立 LDAP 注册表、独立定制注册表等三种用户帐号存储库。通常 WAS V6.0 管理员只能选择其中的一种。
WAS V6.1 提供了新的用户帐号存储库—联合存储库,该存储库支持同时使用多种存储库进行身份认证,包括 IBM 提供的内置于系统的基于文件的存储库、一个或多个 JDBC 关系数据库存储库 (IBM 提供数据库表的定义和实现 )、一个或多个外部 LDAP 存储库。
图 1:WAS V6.1 的“用户帐号存储库”
WAS V6.1 配置 LDAP 的两种方法
下面让我们来看看如何配置“联合存储库”,让它能够使用 LDAP 外部存储库进行身份认证。
如果只使用 LDAP 注册表作为唯一的用户帐号存储库,那么可以通过 WAS V6.1 的“安全配置向导”即可。其配置方法、界面和 WAS V6.0 基本一样。
图 2:WAS V6.1 的“安全配置向导”
WAS V6.1“联合存储库”为管理员提供了新的选择,管理员可以在“联合存储库”中添加一个或多个 LDAP 外部存储库 (“联合存储库”可以是由多个 LDAP 外部存储库和文件存储库、关系数据库存储库组成,但是这些数据库里面不能有重名用户 )。添加以后,我们不仅可以用 LDAP 进行应用的身份验证,而且可以利用到 WAS V6.1 联合存储库为用户和组管理提供的读写能力,包括使用以下选项添加、创建和删除用户和组:
* 用户 / 组管理应用程序编程接口 (IBM WebSphere Java API)
* 管理控制台
* wsadmin 命令
注:在 WAS 以前的版本中,LDAP 只能用于身份认证,不能通过 WAS 读写 LDAP。
为 WAS V6.1“联合存储库”添加 LDAP 外部存储库
在 WAS V6.1 管理控制台中选择导航安全性 > 安全管理、应用程序和基础结构 > 联合存储库 > 管理存储库,选择按钮“添加”新的外部存储库。
注:在安装 WAS V6.1 的时候,如果选择了使能安全性保护 WAS 管理控制台,那么你会看到联合存储库里面已经有了基于文件的存储库。
图 3:管理存储库
在接下来的“新建”页面中录入如下数据:
* 数据库标识:选取合适的容易说明即可,可以是服务器主机名称、英文说明,都可以。
* 目录类型:选择 IBM Tivoli Directory Server 6,也可以是 Domino、微软活动目录等等。
* 主要主机名:主目录服务器主机名。
* 故障转移主机名:当主目录服务器出故障 out of service 的时候,WAS V6.1 会自动切换使用备份的目录服务器。
* 登录属性:缺省是 uid,如果你想让用户能够以其他 LDAP 属性登录,比如用户可以用 uid 或者 cn 或者 email 都能登录,那么你可以录入 uid;cn;email。
* 支持到其它 LDAP 服务器的指向信息:LDAP 服务器的数据可以通过 referral 指向其他 LDAP 服务器。
* 需要 SSL 通信:配置 WAS 和 LDAP 服务器之间的通信要走 SSL。
* 证书映射:如果 J2EE Web 应用使能 SSL 证书登录,那么 WAS 缺省会将客户浏览器提供的 SSL 证书中的 Subject 提取出来,在 LDAP 服务器中和 inetOrgPerson 类对象的 DN 属性进行比对,如果相同,那么这个人的证书认证就算通过了,用户的身份就是其个人对象 DN 属性和 SSL 证书 Subject 相同的用户。
图 4:新建 LDAP 存储库
新建了 LDAP 外部存储库以后,这个库还没有真正被“联合存储库”引用,仍需要做一个简单的引用管理配置。选择安全性 > 安全管理、应用程序和基础结构 > 联合存储库,选择按钮“将基本条目添加至域”。
图 5:存储库引用
“将基本条目添加至域”以后,“联合存储库”现在有两个存储库了。用户登录 J2EE Web 应用的时候,WAS 会先后在两个存储库中进行查找用户进行身份认证。
图 6:保存有多个存储库的联合存储库
配置完毕“联合存储库”以后,还需要分别“启用管理安全性”和“启用应用程序安全性”。
注:在 WebSphere Application Server V6.0.x 的环境中,其 Web 管理控制台缺省是不受保护的,任何人不需提供用户名和口令就能登陆 WAS 的管理控制台,进行所有的管理操作。
和 6.0 版本不同的是,WAS V6.1 新增了“管理安全性”安装选项,安装 WAS 的时候就可以指定是否保护 WAS 的管理服务器并指定管理员用户名、口令,让管理员可以轻松地保护 WAS 的管理服务器。WAS V6.1 安装时候启用的安全性缺省采用“内置存储库”,存储库标识 InternalFileRepository,存储库类型为文件 ( 保存位置 WebSphere\AppServer\profiles\AppSrv01\config\cells\<node name>\fileRegistry.xml)。
图 7:启用“管理安全性”和“应用程序安全性”
启用安全性以后停止并重启 WAS,使用浏览器访问 WAS 6.1 例子应用 DefaultApplication 的 Snoop Servlet,可以 LDAP 的用户进行登录访问了。浏览器访问 Snoop URL: http://wp6x.cn.ibm.com:9080/snoop,根据提示输入 LDAP 用户名口令,访问成功 !
使用 WAS 的身份验证带来的额外好处是,缺省情况下单服务器上面的 Web 应用之间已经实现了单点登录!比如,首先浏览器访问 Snoop URL: http://wp6x.cn.ibm.com:9080/snoop,根据提示输入 WAS 管理员口令,访问成功。然后在浏览器里面输入 WAS V6.1 管理控制台 URL: http://wp6x.cn.ibm.com:9060/ibm/console/,你会发现不需要再次输入用户信息直接能够访问了 ! 如果想做到多服务器的单点登录,还需要进行一些额外的 WAS LTPA 配置,这里就不多说了,请参考后面的参考资料。
WAS LDAP 安全性配置排错处理
配置 LDAP 身份认证是一个需要多方面知识和经验的工作,我们需要掌握在 WebSphere 配置 LDAP 的过程中如何进行排错 (trouble shooting) 的技能。
WAS LDAP 配置排错可以从两方面着手。首先是从 WAS 入手,除了 WAS 标准系统输出和错误文件 SystemOut.log 和 SystemErr.log 文件之外,还打开 WAS 的安全方面的日志,里面记录了从用户登录、WAS 到 LDAP 服务器上面进行身份校验、用户提交会话 Cookie/LTPAToken 等等信息。打开 WAS 日志的方法是登录 WAS 管理控制台,导航到记录和跟踪 > server1 > 诊断跟踪服务 > 更高日志详细信息级别,添加有关安全跟踪的内容 *=info:com.ibm.ws.security.*=all ,保存配置,重新启动 WAS 服务器,进行访问测试,出问题后查看位于 <server root>\log 目录下面的 trace.log 文件,比如 WebSphere\AppServer\profiles\<node name>\logs\server1\trace.log。
另外,你也可以打开 LDAP 服务器的日志跟踪,看看 WAS 服务器那边发过来的 LDAP 请求到底是什么内容,特别是 LDAP 绑定、LDAP 搜索过滤器是否正确,LDAP 返回给 WAS 的结果是否正常。
Domino LDAP 服务器的日志打开方法是,在 Domino 服务器控制台上面执行命令 set config LDAPDEBUG=7,结果是在 Domino 服务器的配置文件 notes.ini 最后面自动加入了一段 LDAPDEBUG=7,重新启动 Domino 服务器或者单独起停 LDAP 服务器。当 WAS 以 LDAP 协议访问 Domino 的时候,所有 LDAP 的访问请求交互信息将打印到 Domino 服务器控制台上面。
分析 Struts 例子应用 MailReader 的身份认证和访问控制
配置了 WAS 服务器“联合存储库”使用 LDAP 服务器进行身份认证,我们看到了 WAS 内置的例子应用 DefaultApplication 受到安全保护,WebSphere 缺省的例子应用、服务器管理控制台已经可以通过“联合存储库”进行身份认证,但是我们现有的部署在 WebSphere 上面的业务应用系统并不能马上自动地使用到这一特性。
我们还需要做一定的修改、或者叫做移植工作,才能让我们的现有的 J2EE Web 应用能够使用 WAS 的 LDAP 登录机制,进而能够利用到 WAS 强大的单点登录能力。
让我们分析一下现有的 J2EE 应用 -- 以 Struts 例子应用 MailReader 为代表,分析一下现有应用常用的认证机制,确定移植目标,对应用进行移植,为它增加标准的 J2EE 表单登录方式,增加新的 J2EE 标准格式的 Form 登录页面,最后为 Struts 应用增加新的代码,在用户通过新的 J2EE 标准格式的 Form 登录页面登录以后,后台应用系统如何为登录用户构造用户会话信息。
在 Struts 网站下载 Struts 1.3.8 的 Example Applications struts-1.3.8-apps.zip,解压缩后找到 struts-mailreader-1.3.8.war 文件,使用 WAS V6.1 管理控制台安把这个 war 文件安装并启动。访问 http://wp6x.cn.ibm.com:9080/mail/EditSubscription.do,系统提示登录。录入用户名 user 口令 pass 就可以登录。
MailReader 的用户名口令等数据保存在 WEB-INF\database.xml 文件数据库中 ( 类似的,企业 J2EE Web 应用的用户数据大多保存在关系型数据库或者是目录服务器中 )。用户每次访问 MailReader 受限访问的资源,MailReader 都会调用 doGetUser 方法查看在 J2EE 会话 HttpSession 里面否有登录用户的信息。如果没有用户信息,则或者重定向客户浏览器到用户注册页面(比如访问 EditRegistration.do),或者是重定向到登录页面(比如访问 DeleteSubscription.do?host=mail.yahoo.com)。 doGetUser 方法的代码很简单,就是从 HttSession 对象中查找属性名字为常量 Constants.USER_KEY 的 User 对象,如果没有就说明用户没有登录过,更不要说有权限了。
清单 1.doGetUser() 从用户会话中获得 User 对象
/** Helper method to obtain User form session (if any).
* @param request Our HttpServletRequest
* @return User object, or null if there is no user. */
protected User doGetUser(HttpServletRequest request) {
HttpSession session = request.getSession();
return (User) session.getAttribute(Constants.USER_KEY);
}
接下来我们看看 MailReader 的登录程序。在下面 LogonAction.java 代码的 ActionForward 方法中,首先从 Form 中取得用户提交的用户名口令,然后调用 doGetUser(username, password, errors) 方法进行用户名口令身份验证,如果验证通过,调用 doCacheUser(request, user) 方法把 User 对象保存到 HttpSession 中。
清单 2.LogonAction.java 部分登录代码
// Retrieve user
String username = doGet(form, USERNAME);
String password = doGet(form, PASSWORD);
ActionMessages errors = new ActionMessages();
User user = doGetUser(username, password, errors);
……
// Cache user object in session to signify logon
doCacheUser(request, user);
移植 Struts 例子应用的目标
接下来让我们设定一下移植现有 J2EE 应用到使用 J2EE 表单登录认证和“联合存储库”的移植目标。我们为 MailReader 增加 WAS LDAP 认证的移植目标如下:
* 原有的 MailReader 用户数据库存储方式不变,登录方式不变。经过移植以后,用户仍然可以使用原有的用户名和口令,通过 MailReader 原有的登录界面进行登录。
* 增加新的登录方式,支持使用 WAS LDAP 身份认证,登录方式是标准的 J2EE 表单登录。经过移植以后,用户可以使用新的 LDAP 用户名和口令通过 MailReader 新的 J2EE 表单登录界面进行登录。
* 如果用户提供的用户名口令通过了 WAS LDAP 身份认证,MailReader 信任 WAS 的身份认证信息不再使用 MailReader 用户数据库进行二次用户名口令验证,而是直接在 MailReader 用户数据库查找用户的其他信息并构造出 User 对象,然后放到 HttpSession 里面,最后重定向用户的请求到 MailReader 业务操作页面中。
* 如果用户提供的用户名口令通过了 WAS LDAP 身份认证,但是在 MailReader 用户数据库中找不到该用户的其他信息,也就构造不出来 User 对象,那么我们需要提示用户-您输入的用户名是 LDAP 合法用户,但不是 MailReader 的合法用户,请重新登录。
为 MailReader 增加标准的 J2EE 表单登录方式
根据上面的移植目标,我们对 Struts 例子应用进行移植,首先为 MailReader 增加标准的 J2EE 表单登录方式,这样 MailReader 部署到 WAS 上面以后,就可以使用 WAS 的机制通过 LDAP 服务器进行身份验证了。 把 struts-mailreader-1.3.8.war 用 jar 或者 winzip 解压缩到硬盘上,打开 web.xml 文件在 </web-app> 标记之前加入如下内容。
清单 3.web.xml 文件中有关 J2EE 安全的内容
<security-constraint>
<display-name>Secured</display-name>
<web-resource-collection>
<web-resource-name>MailReader Demonstration Application</web-resource-name>
<description>Protection area for MailReader</description>
<url-pattern>/loginadapter.jsp</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>All Authenticated users for MailReader</description>
<role-name>All Role</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/failedlogin.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>All Authenticated Users Role.</description>
<role-name>All Role</role-name>
</security-role>
web.xml 文件中 <web-resource-collection> 标记定义了 J2EE 安全保护的资源列表;
<url-pattern> 标记订了受 J2EE 安全保护的资源的 URL 列表,比如 /loginadapter.jsp;<auth-constraint> 标记说明了有权访问这个文件的用户必须是属于 All Role 角色的用户;<login-config><form-login-page> 标记指定用户可以通过 /login.jsp 登录页面进行 FORM 表单方式的登录;<form-error-page> 标记指定用户登录失败 ( 用户名或者口令错误 ) 后 WAS 返回给用户的错误页面。
为 MailReader 增加 J2EE Form 登录页面
前面我们修改了 MailReader 的 web.xml 文件,增加了标准的 J2EE 表单登录方式的配置。下面我们为 MailReader 定制 J2EE 用户身份认证的登录界面 --login.jsp。根据 J2EE 的规定,这个登录页面有一些具体的规定:
* 必须包括一个 form 元素,form 的 action 属性必须是 j_security_check,j_security_check 是 J2EE 中专门处理用户登录的一个小应用程序
* form 中必须包括两个文本框,一个名为:j_username,另外一个是:j_password,这两个文本框的名字不能更改
* 其他的页面元素可以随意定制以满足客户个性化、风格化的需求
需要特别指出的是,为控制用户使用 login.jsp Form 表单登录以后重定向的页面,我们可以在 login.jsp 里面设置一个 IBM WAS 专用的 cookie,cookie 名字是 WASReqURL,告诉 WAS 在通过用户 LDAP 身份认证以后重定向客户的浏览器到指定 URL – loginadapter.jsp。
清单 4.loginadapter.jsp 页面重定向代码
<%
if (request.getParameter("WASReqURL")!=null) {
// 获得要重定向的 URL 参数
String url = request.getParameter("WASReqURL");
} %>
<script language="JavaScript">
document.cookie = "WASReqURL=<%=url%>";
</script>
根据登录 LDAP 用户名构造 MailReader 用户会话信息
MailReader 移植的最后一步,我们为它增加新的代码,在用户通过新的 J2EE 标准格式的 Form 登录页面登录以后,后台应用系统可以根据业务逻辑为登录用户构造用户会话信息。
在 loginadapter.jsp 中,我们首先调用标准 J2EE API request.getRemoteUser() 获得当前登录 LDAP 用户名,我们信任 WAS 的身份验证,因此就不再访问 MailReader database 中进行信息用户名口令的校验了。接下来使用 MailReader 的 UserDatabase. findUser(username) 方法构造 User 对象,并且把 User 对象保存到 HttpSession 对象中。最后通过 JavaScript 把页面重定向到客户想要访问的 MailReader 业务页面。
清单 5.loginadapter.jsp 构造用户会话信息代码
<%
// getRemoteUser() 是 J2EE Servlet 标准 API,从 J2EE Container 中获得登录用户身份
String username = request.getRemoteUser();
//UserDatabase 是 MailReader 的数据库访问对象
UserDatabase database = (UserDatabase)session.
getServletContext().getAttribute(Constants.DATABASE_KEY);
// 从 MailReader 数据库里面查找用户对象
User user = database.findUser(username);
……
// 把用户对象 User 保存到 HttpSession 中
session.setAttribute(Constants.USER_KEY, user);
……
<!-- 使用 JavaScript 重定向客户浏览器到指定的 MailReader 页面郳 par <script language="JavaScript">
<%
String scheme = request.getScheme(); // http
String serverName = request.getServerName(); // hostname.com
int serverPort = request.getServerPort(); // 80
String contextPath = request.getContextPath(); // /mywebapp
// Reconstruct original requesting URL
String url = scheme+"://"+serverName+":"+serverPort+contextPath;
url = url + "/EditRegistration.do";
%>
window.location="<%=url%>";
</script>
部署、设置 J2EE 角色和 LDAP 用户的绑定,测试
在解压缩的 struts war 文件目录修改了 web.xml,新增加了 login.jsp、failedlogin.jsp、loginadapter.jsp,现在我们可以使用 java jar 命令把这个目录再次压缩打包成 war 文件。
移植工作结束以后,使用 WAS 管理控制台部署新的应用。部署以后不要立即启动应用,还需要在管理控制台上把 MailReader 新定义的角色 All Role 和“所有已认证的用户”进行绑定。绑定安全角色和用户 / 组的映射以后,就可以启动 MailReader Web 应用,使用 LDAP 的用户进行登录访问了。
图 10:安全角色到用户 / 组映射
访问 http://wp6x.cn.ibm.com:9080/mailreader/loginadapter.jsp,这是一个受 WAS 保护的页面,WAS 重定向客户浏览器到 J2EE Web 登录页 http://wp6x.cn.ibm.com:9080/mailreader/login.jsp。
输入 LDAP 用户名和口令,WAS 服务器验证通过以后,如果这个用户也同时存在于 MailReader 的用户数据库里面,那么 loginadapter.jsp 根据 LDAP 用户名构造 User 对象放到 HttpSession 里面,然后重定向浏览器到 MailRader 业务页面 http://wp6x.cn.ibm.com:9080/mailreader/EditRegistration.jsp。
图 11:MailReader 新的 J2EE 登录页面
图 12:MailReader J2EE 登录后的业务页面
输入 LDAP 用户名和口令,WAS 服务器验证通过以后,如果这个用户不存在于 MailReader 的用户数据库里面,loginadapter.jsp 提示用户选择使用新的用户名口令登录。
图 13:MailReader J2EE 登录的用户在 MailReader 用户数据库中不存在
移植总结
回顾一下,在以上的移植工作中,我们修改了 Struts 例子应用 MailReader 的 web.xml 文件,加入新的 FORM 表单登录界面 login.jsp、加入一个简单的登录错误提示页面 failedlogin.jsp、一个用户会话构造和重定向页面 loginadapter.jsp,我们就为原来使用文件数据库进行用户身份验证的 Struts 应用增加 ( 移植 ) 了使用 IBM WAS LDAP 登录的能力。通常情况下,快的半天,慢的一天的时间就可以成功地把一个企业应用迁移到 IBM WAS(LDAP) 身份认证和登录方式。
文章2:
用户的很多功能通过邮件提醒,用户需要点链接后,希望能直接进入到具体的页面。但由于各个系统等都已经是和门户(门户采用的是IBM的portal)做了sso。其他系统的密码已经不再维护了。如果到了原系统的登陆页面,那这时就登陆不了。需要将登陆页面重定向到门户的登陆页面。这时就又出现了新的问题了,就是用户登陆后如何跳到具体的页面。默认登陆后是到门户的主页面的。由于门户的应用服务器是 portlet的容器。不直接支持httprequest。本来可以通过传递一个参数来解决。但在门户就实现不了。上了ibm官方网站的论坛,搜索了一把,发现也是很多人都在问这问题。但就是没具体的解决方法。打800咨询了一下。1线的解决不了,丢到2线德国,查了下,还有7小时的时差,只有等第2天的答复了。第2天是给了答复,但给的是定制登陆和登出的页面,这个还是针对整个门户而言的,根本就满足不了我的要求,有点答非所问了。经过自己的摸索,发现了一点。当登陆/wps/myportal时,发现登陆后是跳转到/wps/myportal的页面。查看了一下页面的cookie,发现当访问了 /wps/myportal时,门户会自己写入wasrequrl这个cookie。而这个值就是http://portal.domain.com/wps/myportal,发现了这点后,兴奋了一把,马上让我同事在公司测试了一下,因为在客户现场,没有测试的环境。同时继续与800沟通,看是否能通过这个cookie来实现。同事给的测试结果是在页面登陆前写入后,只要你登陆了,门户就会自己把这个cookie清除掉。根本不能写。
这时好象又陷入了死胡同了。怎么办呢?等ibm的话,又得到第2天了。
突然想到,如果用其他的应用服务器来写呢,是不是可以解决被清除的问题呢。
马上测试一下。写了一个写cookie的页面。当然写之前要先把原来的cookie清除掉,然后直接通过url测试。先写cokie,然后重定向到 http;//portal.domain.com/wps/portal,查看页面的cookie,发现WASReqURL还在,测试登陆,果然登陆后直接就跳到了写的那个cookie的值的那个页面了。
实现的过程是很简单的。但这问题也是花了几天才解决这么个小问题。
实验室最后给的答复:
from looking at this it does not appear that this is a setable cookie.
It is something the was layer does for you. Some have tried to set it
via a custom jaas module but I never saw this work
文章3:
Examples
Example 1
set a cookie with the JSON-serialized contents of an object which will expire 5 days from now:
dojo.cookie("configObj", dojo.toJson(config), { expires: 5 });
Example 2
de-serialize a cookie back into a JavaScript object:
var config = dojo.fromJson(dojo.cookie("configObj"));
Example 3
delete a cookie:
dojo.cookie("configObj", null, {expires: -1});
Final
最后,折中的办法想了出来,先把WASReqURL的数据给存到另一个cookie里面:
if (dojo.cookie("WASReqURL") != null) {
dojo.cookie("redirect", encodeURI(dojo.cookie("WASReqURL")));
}
当页面跳转错误,到welcome的时候,检查cookie,如果有redirect,就跳转到redirect页面。
if (dojo.cookie("redirect") != null) {
var url = dojo.cookie("redirect");
dojo.cookie("redirect", null, {expires: -1});
window.location = url;
}
为了防止用户进了login却没有登录,还需要另一个cookie来判断:
if (dojo.cookie("redirect") != null && dojo.cookie("LtpaToken") != null) {
var url = dojo.cookie("redirect");
dojo.cookie("redirect", null, {expires: -1});
window.location = url;
}
这样,当用户登录成功时,便会自动跳转到正确的页面。
前两天遇到个问题,当用户登录后,IE在某些情况下,不会自动跳转到登录前页面,而是回到了welcome页面。
这个问题折磨了我快一周的时间,绞尽脑汁找不出原因。而且这个defect不是总能重现,因此很难找到原因。
后来想了想,换一条路,我们可以从WAS的验证机制入手,看看有没有什么漏洞所在。
在网上找了很多有用的文章,一篇一篇帖出来,最后形成了我的解决办法:
文章1:
企业信息化建设多年,建立了包括人事、财务、市场、销售、客户关系管理等一系列的业务和应用信息系统。这些系统种类繁多并且由不同的应用开发商提供,比如 SAP、金碟的 ERP 软件,微软、ORACLE、用友的财务软件等等。不同的系统和开发商有自己专用的一套用户存储和管理系统 ( 存储用户名口令和组等信息 -- username, password, group etc),例如早期的各种 Unix、Windows 操作系统帐号、后来的各种关系型数据库、以及目录服务器等等。混乱的用户存储和管理系统给企业 IT 管理带来了繁重的维护工作量和新的问题,企业很希望信息系统能采用标准的用户注册表,轻量级目录访问协议 LDAP 由于标准化是一种比较理想的选择。
有关 IBM WebShpere 应用服务器安全性、如何配置 LDAP 的文章已经很多,但是大多数是 6.0 以前的版本。在 6.0 以前,WebSphere 只能配置一种用户注册表,比如操作系统、目录服务器、定制用户注册表。
本文介绍 WebSphere 6.1 的新特性“联合存储库”,如何为联合存储库配置 LDAP 服务器,以及如何迁移 J2EE Web 应用程序以使用 J2EE 规范的表单认证,进而能通过 WebSphere 6.x 的存储库 ( 联合存储库、其他支持的用户注册表 ) 进行身份认证和授权。
我们会首先来了解一下 WebSphere 6.1 的最新特性“联合存储库”,看看它和 6.0 用户注册表有什么区别,它是如何同时使用多种存储库进行身份认证的;接下来,我们来看看如何配置“联合存储库”,让它能够使用 LDAP 外部存储库进行身份认证;配置 LDAP 身份认证是一个需要多方面知识和经验的工作,我们需要掌握在 WebSphere 配置 LDAP 的过程中如何进行排错 (trouble shooting) 的技能。配置好了 WebSphere“联合存储库”,WebSphere 缺省的例子应用、服务器管理控制台已经可以通过“联合存储库”进行身份认证,但是我们现有的部署在 WebSphere 上面的业务应用系统并不能马上自动地使用到这一特性。让我们分析一下现有的 J2EE 应用 -- 以 Struts 例子应用为代表,分析一下现有应用常用的认证机制;接下来我们会设定一下移植现有 J2EE 应用到使用 J2EE 表单登录认证和“联合存储库”的移植目标;根据这个目标,我们对 Struts 例子应用进行移植,为它增加标准的 J2EE 表单登录方式,增加新的 J2EE 标准格式的 Form 登录页面,最后为 Struts 应用增加新的代码,在用户通过新的 J2EE 标准格式的 Form 登录页面登录以后,后台应用系统如何为登录用户构造用户会话信息。
WAS V6.1 用户帐号存储库介绍
首先,我们来了解一下 WebSphere 6.1 的最新特性“联合存储库”,看看它和 6.0 用户注册表有什么区别,它是如何同时使用多种存储库进行身份认证的。
IBM WAS 可以借助管理员配置的用户帐号存储库,帮助运行在 WAS 上面的 J2EE 应用程序以标准的 J2EE 认证方式进行用户身份认证。换言之,J2EE 应用程序可以使用 WAS 上面配置的用户帐号存储库进行统一的用户身份认证。
WAS V6.0 提供了本地操作系统、独立 LDAP 注册表、独立定制注册表等三种用户帐号存储库。通常 WAS V6.0 管理员只能选择其中的一种。
WAS V6.1 提供了新的用户帐号存储库—联合存储库,该存储库支持同时使用多种存储库进行身份认证,包括 IBM 提供的内置于系统的基于文件的存储库、一个或多个 JDBC 关系数据库存储库 (IBM 提供数据库表的定义和实现 )、一个或多个外部 LDAP 存储库。
图 1:WAS V6.1 的“用户帐号存储库”
WAS V6.1 配置 LDAP 的两种方法
下面让我们来看看如何配置“联合存储库”,让它能够使用 LDAP 外部存储库进行身份认证。
如果只使用 LDAP 注册表作为唯一的用户帐号存储库,那么可以通过 WAS V6.1 的“安全配置向导”即可。其配置方法、界面和 WAS V6.0 基本一样。
图 2:WAS V6.1 的“安全配置向导”
WAS V6.1“联合存储库”为管理员提供了新的选择,管理员可以在“联合存储库”中添加一个或多个 LDAP 外部存储库 (“联合存储库”可以是由多个 LDAP 外部存储库和文件存储库、关系数据库存储库组成,但是这些数据库里面不能有重名用户 )。添加以后,我们不仅可以用 LDAP 进行应用的身份验证,而且可以利用到 WAS V6.1 联合存储库为用户和组管理提供的读写能力,包括使用以下选项添加、创建和删除用户和组:
* 用户 / 组管理应用程序编程接口 (IBM WebSphere Java API)
* 管理控制台
* wsadmin 命令
注:在 WAS 以前的版本中,LDAP 只能用于身份认证,不能通过 WAS 读写 LDAP。
为 WAS V6.1“联合存储库”添加 LDAP 外部存储库
在 WAS V6.1 管理控制台中选择导航安全性 > 安全管理、应用程序和基础结构 > 联合存储库 > 管理存储库,选择按钮“添加”新的外部存储库。
注:在安装 WAS V6.1 的时候,如果选择了使能安全性保护 WAS 管理控制台,那么你会看到联合存储库里面已经有了基于文件的存储库。
图 3:管理存储库
在接下来的“新建”页面中录入如下数据:
* 数据库标识:选取合适的容易说明即可,可以是服务器主机名称、英文说明,都可以。
* 目录类型:选择 IBM Tivoli Directory Server 6,也可以是 Domino、微软活动目录等等。
* 主要主机名:主目录服务器主机名。
* 故障转移主机名:当主目录服务器出故障 out of service 的时候,WAS V6.1 会自动切换使用备份的目录服务器。
* 登录属性:缺省是 uid,如果你想让用户能够以其他 LDAP 属性登录,比如用户可以用 uid 或者 cn 或者 email 都能登录,那么你可以录入 uid;cn;email。
* 支持到其它 LDAP 服务器的指向信息:LDAP 服务器的数据可以通过 referral 指向其他 LDAP 服务器。
* 需要 SSL 通信:配置 WAS 和 LDAP 服务器之间的通信要走 SSL。
* 证书映射:如果 J2EE Web 应用使能 SSL 证书登录,那么 WAS 缺省会将客户浏览器提供的 SSL 证书中的 Subject 提取出来,在 LDAP 服务器中和 inetOrgPerson 类对象的 DN 属性进行比对,如果相同,那么这个人的证书认证就算通过了,用户的身份就是其个人对象 DN 属性和 SSL 证书 Subject 相同的用户。
图 4:新建 LDAP 存储库
新建了 LDAP 外部存储库以后,这个库还没有真正被“联合存储库”引用,仍需要做一个简单的引用管理配置。选择安全性 > 安全管理、应用程序和基础结构 > 联合存储库,选择按钮“将基本条目添加至域”。
图 5:存储库引用
“将基本条目添加至域”以后,“联合存储库”现在有两个存储库了。用户登录 J2EE Web 应用的时候,WAS 会先后在两个存储库中进行查找用户进行身份认证。
图 6:保存有多个存储库的联合存储库
配置完毕“联合存储库”以后,还需要分别“启用管理安全性”和“启用应用程序安全性”。
注:在 WebSphere Application Server V6.0.x 的环境中,其 Web 管理控制台缺省是不受保护的,任何人不需提供用户名和口令就能登陆 WAS 的管理控制台,进行所有的管理操作。
和 6.0 版本不同的是,WAS V6.1 新增了“管理安全性”安装选项,安装 WAS 的时候就可以指定是否保护 WAS 的管理服务器并指定管理员用户名、口令,让管理员可以轻松地保护 WAS 的管理服务器。WAS V6.1 安装时候启用的安全性缺省采用“内置存储库”,存储库标识 InternalFileRepository,存储库类型为文件 ( 保存位置 WebSphere\AppServer\profiles\AppSrv01\config\cells\<node name>\fileRegistry.xml)。
图 7:启用“管理安全性”和“应用程序安全性”
启用安全性以后停止并重启 WAS,使用浏览器访问 WAS 6.1 例子应用 DefaultApplication 的 Snoop Servlet,可以 LDAP 的用户进行登录访问了。浏览器访问 Snoop URL: http://wp6x.cn.ibm.com:9080/snoop,根据提示输入 LDAP 用户名口令,访问成功 !
使用 WAS 的身份验证带来的额外好处是,缺省情况下单服务器上面的 Web 应用之间已经实现了单点登录!比如,首先浏览器访问 Snoop URL: http://wp6x.cn.ibm.com:9080/snoop,根据提示输入 WAS 管理员口令,访问成功。然后在浏览器里面输入 WAS V6.1 管理控制台 URL: http://wp6x.cn.ibm.com:9060/ibm/console/,你会发现不需要再次输入用户信息直接能够访问了 ! 如果想做到多服务器的单点登录,还需要进行一些额外的 WAS LTPA 配置,这里就不多说了,请参考后面的参考资料。
WAS LDAP 安全性配置排错处理
配置 LDAP 身份认证是一个需要多方面知识和经验的工作,我们需要掌握在 WebSphere 配置 LDAP 的过程中如何进行排错 (trouble shooting) 的技能。
WAS LDAP 配置排错可以从两方面着手。首先是从 WAS 入手,除了 WAS 标准系统输出和错误文件 SystemOut.log 和 SystemErr.log 文件之外,还打开 WAS 的安全方面的日志,里面记录了从用户登录、WAS 到 LDAP 服务器上面进行身份校验、用户提交会话 Cookie/LTPAToken 等等信息。打开 WAS 日志的方法是登录 WAS 管理控制台,导航到记录和跟踪 > server1 > 诊断跟踪服务 > 更高日志详细信息级别,添加有关安全跟踪的内容 *=info:com.ibm.ws.security.*=all ,保存配置,重新启动 WAS 服务器,进行访问测试,出问题后查看位于 <server root>\log 目录下面的 trace.log 文件,比如 WebSphere\AppServer\profiles\<node name>\logs\server1\trace.log。
另外,你也可以打开 LDAP 服务器的日志跟踪,看看 WAS 服务器那边发过来的 LDAP 请求到底是什么内容,特别是 LDAP 绑定、LDAP 搜索过滤器是否正确,LDAP 返回给 WAS 的结果是否正常。
Domino LDAP 服务器的日志打开方法是,在 Domino 服务器控制台上面执行命令 set config LDAPDEBUG=7,结果是在 Domino 服务器的配置文件 notes.ini 最后面自动加入了一段 LDAPDEBUG=7,重新启动 Domino 服务器或者单独起停 LDAP 服务器。当 WAS 以 LDAP 协议访问 Domino 的时候,所有 LDAP 的访问请求交互信息将打印到 Domino 服务器控制台上面。
分析 Struts 例子应用 MailReader 的身份认证和访问控制
配置了 WAS 服务器“联合存储库”使用 LDAP 服务器进行身份认证,我们看到了 WAS 内置的例子应用 DefaultApplication 受到安全保护,WebSphere 缺省的例子应用、服务器管理控制台已经可以通过“联合存储库”进行身份认证,但是我们现有的部署在 WebSphere 上面的业务应用系统并不能马上自动地使用到这一特性。
我们还需要做一定的修改、或者叫做移植工作,才能让我们的现有的 J2EE Web 应用能够使用 WAS 的 LDAP 登录机制,进而能够利用到 WAS 强大的单点登录能力。
让我们分析一下现有的 J2EE 应用 -- 以 Struts 例子应用 MailReader 为代表,分析一下现有应用常用的认证机制,确定移植目标,对应用进行移植,为它增加标准的 J2EE 表单登录方式,增加新的 J2EE 标准格式的 Form 登录页面,最后为 Struts 应用增加新的代码,在用户通过新的 J2EE 标准格式的 Form 登录页面登录以后,后台应用系统如何为登录用户构造用户会话信息。
在 Struts 网站下载 Struts 1.3.8 的 Example Applications struts-1.3.8-apps.zip,解压缩后找到 struts-mailreader-1.3.8.war 文件,使用 WAS V6.1 管理控制台安把这个 war 文件安装并启动。访问 http://wp6x.cn.ibm.com:9080/mail/EditSubscription.do,系统提示登录。录入用户名 user 口令 pass 就可以登录。
MailReader 的用户名口令等数据保存在 WEB-INF\database.xml 文件数据库中 ( 类似的,企业 J2EE Web 应用的用户数据大多保存在关系型数据库或者是目录服务器中 )。用户每次访问 MailReader 受限访问的资源,MailReader 都会调用 doGetUser 方法查看在 J2EE 会话 HttpSession 里面否有登录用户的信息。如果没有用户信息,则或者重定向客户浏览器到用户注册页面(比如访问 EditRegistration.do),或者是重定向到登录页面(比如访问 DeleteSubscription.do?host=mail.yahoo.com)。 doGetUser 方法的代码很简单,就是从 HttSession 对象中查找属性名字为常量 Constants.USER_KEY 的 User 对象,如果没有就说明用户没有登录过,更不要说有权限了。
清单 1.doGetUser() 从用户会话中获得 User 对象
/** Helper method to obtain User form session (if any).
* @param request Our HttpServletRequest
* @return User object, or null if there is no user. */
protected User doGetUser(HttpServletRequest request) {
HttpSession session = request.getSession();
return (User) session.getAttribute(Constants.USER_KEY);
}
接下来我们看看 MailReader 的登录程序。在下面 LogonAction.java 代码的 ActionForward 方法中,首先从 Form 中取得用户提交的用户名口令,然后调用 doGetUser(username, password, errors) 方法进行用户名口令身份验证,如果验证通过,调用 doCacheUser(request, user) 方法把 User 对象保存到 HttpSession 中。
清单 2.LogonAction.java 部分登录代码
// Retrieve user
String username = doGet(form, USERNAME);
String password = doGet(form, PASSWORD);
ActionMessages errors = new ActionMessages();
User user = doGetUser(username, password, errors);
……
// Cache user object in session to signify logon
doCacheUser(request, user);
移植 Struts 例子应用的目标
接下来让我们设定一下移植现有 J2EE 应用到使用 J2EE 表单登录认证和“联合存储库”的移植目标。我们为 MailReader 增加 WAS LDAP 认证的移植目标如下:
* 原有的 MailReader 用户数据库存储方式不变,登录方式不变。经过移植以后,用户仍然可以使用原有的用户名和口令,通过 MailReader 原有的登录界面进行登录。
* 增加新的登录方式,支持使用 WAS LDAP 身份认证,登录方式是标准的 J2EE 表单登录。经过移植以后,用户可以使用新的 LDAP 用户名和口令通过 MailReader 新的 J2EE 表单登录界面进行登录。
* 如果用户提供的用户名口令通过了 WAS LDAP 身份认证,MailReader 信任 WAS 的身份认证信息不再使用 MailReader 用户数据库进行二次用户名口令验证,而是直接在 MailReader 用户数据库查找用户的其他信息并构造出 User 对象,然后放到 HttpSession 里面,最后重定向用户的请求到 MailReader 业务操作页面中。
* 如果用户提供的用户名口令通过了 WAS LDAP 身份认证,但是在 MailReader 用户数据库中找不到该用户的其他信息,也就构造不出来 User 对象,那么我们需要提示用户-您输入的用户名是 LDAP 合法用户,但不是 MailReader 的合法用户,请重新登录。
为 MailReader 增加标准的 J2EE 表单登录方式
根据上面的移植目标,我们对 Struts 例子应用进行移植,首先为 MailReader 增加标准的 J2EE 表单登录方式,这样 MailReader 部署到 WAS 上面以后,就可以使用 WAS 的机制通过 LDAP 服务器进行身份验证了。 把 struts-mailreader-1.3.8.war 用 jar 或者 winzip 解压缩到硬盘上,打开 web.xml 文件在 </web-app> 标记之前加入如下内容。
清单 3.web.xml 文件中有关 J2EE 安全的内容
<security-constraint>
<display-name>Secured</display-name>
<web-resource-collection>
<web-resource-name>MailReader Demonstration Application</web-resource-name>
<description>Protection area for MailReader</description>
<url-pattern>/loginadapter.jsp</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>All Authenticated users for MailReader</description>
<role-name>All Role</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/failedlogin.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>All Authenticated Users Role.</description>
<role-name>All Role</role-name>
</security-role>
web.xml 文件中 <web-resource-collection> 标记定义了 J2EE 安全保护的资源列表;
<url-pattern> 标记订了受 J2EE 安全保护的资源的 URL 列表,比如 /loginadapter.jsp;<auth-constraint> 标记说明了有权访问这个文件的用户必须是属于 All Role 角色的用户;<login-config><form-login-page> 标记指定用户可以通过 /login.jsp 登录页面进行 FORM 表单方式的登录;<form-error-page> 标记指定用户登录失败 ( 用户名或者口令错误 ) 后 WAS 返回给用户的错误页面。
为 MailReader 增加 J2EE Form 登录页面
前面我们修改了 MailReader 的 web.xml 文件,增加了标准的 J2EE 表单登录方式的配置。下面我们为 MailReader 定制 J2EE 用户身份认证的登录界面 --login.jsp。根据 J2EE 的规定,这个登录页面有一些具体的规定:
* 必须包括一个 form 元素,form 的 action 属性必须是 j_security_check,j_security_check 是 J2EE 中专门处理用户登录的一个小应用程序
* form 中必须包括两个文本框,一个名为:j_username,另外一个是:j_password,这两个文本框的名字不能更改
* 其他的页面元素可以随意定制以满足客户个性化、风格化的需求
需要特别指出的是,为控制用户使用 login.jsp Form 表单登录以后重定向的页面,我们可以在 login.jsp 里面设置一个 IBM WAS 专用的 cookie,cookie 名字是 WASReqURL,告诉 WAS 在通过用户 LDAP 身份认证以后重定向客户的浏览器到指定 URL – loginadapter.jsp。
清单 4.loginadapter.jsp 页面重定向代码
<%
if (request.getParameter("WASReqURL")!=null) {
// 获得要重定向的 URL 参数
String url = request.getParameter("WASReqURL");
} %>
<script language="JavaScript">
document.cookie = "WASReqURL=<%=url%>";
</script>
根据登录 LDAP 用户名构造 MailReader 用户会话信息
MailReader 移植的最后一步,我们为它增加新的代码,在用户通过新的 J2EE 标准格式的 Form 登录页面登录以后,后台应用系统可以根据业务逻辑为登录用户构造用户会话信息。
在 loginadapter.jsp 中,我们首先调用标准 J2EE API request.getRemoteUser() 获得当前登录 LDAP 用户名,我们信任 WAS 的身份验证,因此就不再访问 MailReader database 中进行信息用户名口令的校验了。接下来使用 MailReader 的 UserDatabase. findUser(username) 方法构造 User 对象,并且把 User 对象保存到 HttpSession 对象中。最后通过 JavaScript 把页面重定向到客户想要访问的 MailReader 业务页面。
清单 5.loginadapter.jsp 构造用户会话信息代码
<%
// getRemoteUser() 是 J2EE Servlet 标准 API,从 J2EE Container 中获得登录用户身份
String username = request.getRemoteUser();
//UserDatabase 是 MailReader 的数据库访问对象
UserDatabase database = (UserDatabase)session.
getServletContext().getAttribute(Constants.DATABASE_KEY);
// 从 MailReader 数据库里面查找用户对象
User user = database.findUser(username);
……
// 把用户对象 User 保存到 HttpSession 中
session.setAttribute(Constants.USER_KEY, user);
……
<!-- 使用 JavaScript 重定向客户浏览器到指定的 MailReader 页面郳 par <script language="JavaScript">
<%
String scheme = request.getScheme(); // http
String serverName = request.getServerName(); // hostname.com
int serverPort = request.getServerPort(); // 80
String contextPath = request.getContextPath(); // /mywebapp
// Reconstruct original requesting URL
String url = scheme+"://"+serverName+":"+serverPort+contextPath;
url = url + "/EditRegistration.do";
%>
window.location="<%=url%>";
</script>
部署、设置 J2EE 角色和 LDAP 用户的绑定,测试
在解压缩的 struts war 文件目录修改了 web.xml,新增加了 login.jsp、failedlogin.jsp、loginadapter.jsp,现在我们可以使用 java jar 命令把这个目录再次压缩打包成 war 文件。
移植工作结束以后,使用 WAS 管理控制台部署新的应用。部署以后不要立即启动应用,还需要在管理控制台上把 MailReader 新定义的角色 All Role 和“所有已认证的用户”进行绑定。绑定安全角色和用户 / 组的映射以后,就可以启动 MailReader Web 应用,使用 LDAP 的用户进行登录访问了。
图 10:安全角色到用户 / 组映射
访问 http://wp6x.cn.ibm.com:9080/mailreader/loginadapter.jsp,这是一个受 WAS 保护的页面,WAS 重定向客户浏览器到 J2EE Web 登录页 http://wp6x.cn.ibm.com:9080/mailreader/login.jsp。
输入 LDAP 用户名和口令,WAS 服务器验证通过以后,如果这个用户也同时存在于 MailReader 的用户数据库里面,那么 loginadapter.jsp 根据 LDAP 用户名构造 User 对象放到 HttpSession 里面,然后重定向浏览器到 MailRader 业务页面 http://wp6x.cn.ibm.com:9080/mailreader/EditRegistration.jsp。
图 11:MailReader 新的 J2EE 登录页面
图 12:MailReader J2EE 登录后的业务页面
输入 LDAP 用户名和口令,WAS 服务器验证通过以后,如果这个用户不存在于 MailReader 的用户数据库里面,loginadapter.jsp 提示用户选择使用新的用户名口令登录。
图 13:MailReader J2EE 登录的用户在 MailReader 用户数据库中不存在
移植总结
回顾一下,在以上的移植工作中,我们修改了 Struts 例子应用 MailReader 的 web.xml 文件,加入新的 FORM 表单登录界面 login.jsp、加入一个简单的登录错误提示页面 failedlogin.jsp、一个用户会话构造和重定向页面 loginadapter.jsp,我们就为原来使用文件数据库进行用户身份验证的 Struts 应用增加 ( 移植 ) 了使用 IBM WAS LDAP 登录的能力。通常情况下,快的半天,慢的一天的时间就可以成功地把一个企业应用迁移到 IBM WAS(LDAP) 身份认证和登录方式。
文章2:
用户的很多功能通过邮件提醒,用户需要点链接后,希望能直接进入到具体的页面。但由于各个系统等都已经是和门户(门户采用的是IBM的portal)做了sso。其他系统的密码已经不再维护了。如果到了原系统的登陆页面,那这时就登陆不了。需要将登陆页面重定向到门户的登陆页面。这时就又出现了新的问题了,就是用户登陆后如何跳到具体的页面。默认登陆后是到门户的主页面的。由于门户的应用服务器是 portlet的容器。不直接支持httprequest。本来可以通过传递一个参数来解决。但在门户就实现不了。上了ibm官方网站的论坛,搜索了一把,发现也是很多人都在问这问题。但就是没具体的解决方法。打800咨询了一下。1线的解决不了,丢到2线德国,查了下,还有7小时的时差,只有等第2天的答复了。第2天是给了答复,但给的是定制登陆和登出的页面,这个还是针对整个门户而言的,根本就满足不了我的要求,有点答非所问了。经过自己的摸索,发现了一点。当登陆/wps/myportal时,发现登陆后是跳转到/wps/myportal的页面。查看了一下页面的cookie,发现当访问了 /wps/myportal时,门户会自己写入wasrequrl这个cookie。而这个值就是http://portal.domain.com/wps/myportal,发现了这点后,兴奋了一把,马上让我同事在公司测试了一下,因为在客户现场,没有测试的环境。同时继续与800沟通,看是否能通过这个cookie来实现。同事给的测试结果是在页面登陆前写入后,只要你登陆了,门户就会自己把这个cookie清除掉。根本不能写。
这时好象又陷入了死胡同了。怎么办呢?等ibm的话,又得到第2天了。
突然想到,如果用其他的应用服务器来写呢,是不是可以解决被清除的问题呢。
马上测试一下。写了一个写cookie的页面。当然写之前要先把原来的cookie清除掉,然后直接通过url测试。先写cokie,然后重定向到 http;//portal.domain.com/wps/portal,查看页面的cookie,发现WASReqURL还在,测试登陆,果然登陆后直接就跳到了写的那个cookie的值的那个页面了。
实现的过程是很简单的。但这问题也是花了几天才解决这么个小问题。
实验室最后给的答复:
from looking at this it does not appear that this is a setable cookie.
It is something the was layer does for you. Some have tried to set it
via a custom jaas module but I never saw this work
文章3:
Examples
Example 1
set a cookie with the JSON-serialized contents of an object which will expire 5 days from now:
dojo.cookie("configObj", dojo.toJson(config), { expires: 5 });
Example 2
de-serialize a cookie back into a JavaScript object:
var config = dojo.fromJson(dojo.cookie("configObj"));
Example 3
delete a cookie:
dojo.cookie("configObj", null, {expires: -1});
Final
最后,折中的办法想了出来,先把WASReqURL的数据给存到另一个cookie里面:
if (dojo.cookie("WASReqURL") != null) {
dojo.cookie("redirect", encodeURI(dojo.cookie("WASReqURL")));
}
当页面跳转错误,到welcome的时候,检查cookie,如果有redirect,就跳转到redirect页面。
if (dojo.cookie("redirect") != null) {
var url = dojo.cookie("redirect");
dojo.cookie("redirect", null, {expires: -1});
window.location = url;
}
为了防止用户进了login却没有登录,还需要另一个cookie来判断:
if (dojo.cookie("redirect") != null && dojo.cookie("LtpaToken") != null) {
var url = dojo.cookie("redirect");
dojo.cookie("redirect", null, {expires: -1});
window.location = url;
}
这样,当用户登录成功时,便会自动跳转到正确的页面。
发表评论
-
大数据下的实体解析
2016-07-07 12:03 671大数据时代的实体解析困境 <!--[if !sup ... -
中文相似度匹配算法
2015-12-30 14:44 1921基于音形码的中文字 ... -
简单工作流引擎
2012-07-06 16:58 2410从公司的一个项目中挖出来的工作流引擎的代码,虽然是一个很简单的 ... -
在线词典的数据结构实现。
2012-05-18 08:37 0昨天在网上看到了一道百度的面试题: Baidu写道 ... -
Log4j 代码学习 - Factory
2012-05-17 08:47 1108我们最早提到,Log4j的初始代码在LogManager的静态 ... -
Log4j 代码学习 - Appender
2012-05-16 09:09 1352在上一篇文章里,我们 ... -
Log4j 代码学习
2012-05-15 14:58 1159最近闲来无事,正好手头上有Log4j的代码,于是就拿来学习了下 ... -
java7中的ThreadLocalRandom(转)
2012-01-20 09:08 4344今天早上看到一个关于java7中的ThreadLocalRan ... -
(转)追MM与23种设计模式
2011-11-16 14:13 9941、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德 ... -
项目开发过程 - 转载
2010-08-04 13:35 1099一位软件工程师的软件过程总结 ... -
LAMP网站架构(转载)
2010-06-30 09:04 896LAMP(Linux-Apache-MySQL-PHP)网 ... -
个人发展成长路线
2010-06-28 14:25 1181其实对自己的发展路线,一直存在着很多困惑,究竟应该成为什么样的 ... -
Decorator
2010-03-15 16:35 1138看java与模式中装饰器模式,没有看懂。。。 在网上找了一篇 ... -
设计模式解读之一: 策略模式
2009-10-13 00:03 786转载 当我们掌握了Java的语法,当我们了解了面向对象的封装 ... -
贫血模式or领域模式
2009-09-13 10:53 4125在论坛看到一个好帖: ... -
整体设计
2009-09-10 14:46 773目前的思路是这样的: -
DaoFactory的设计
2009-09-10 14:29 2178本打算在网上找一些资源的,可是发现大多数人都是用的hibern ... -
Junit 的模式
2009-09-08 23:32 823Junit的Composite模式, 跟享元模式很接近: ... -
IBaseDao的设计
2009-09-08 09:30 1364去网上查了下,发现泛型Dao的设计比较热门,比较起来也相对通用 ... -
数据库连接池
2009-09-06 18:53 1183感谢网络提供资源的朋友,自己做了个版本,正在测试,看看是否有问 ...
相关推荐
JAVA中使用LDAP进行用户认证是指在JAVA应用程序中使用轻量级目录访问协议(LDAP)来进行用户身份验证。LDAP是一种基于X.500标准的目录访问协议,但它更简单、更灵活,可以根据需要进行定制。LDAP支持TCP/IP协议,使...
ldap 服务器是一个目录服务,用于存储和管理用户信息,sasl 则是一个安全认证协议,用于在客户端和服务器之间进行身份验证。 在实现 svn+ldap+sasl 认证时,需要安装 ldap 服务器和配置 ldap 服务,然后在 svn ...
**Python和LDAP进行域认证** 在信息技术领域,域认证是一种重要的身份验证机制,它允许用户在特定的网络环境中登录并访问资源。 Lightweight Directory Access Protocol(LDAP)是实现这种认证方式的一种标准协议。...
Java 连接和验证 LDAP 文档是一份关于 Java 语言连接和验证 LDAP 服务器的学习文档。LDAP(Lightweight Directory Access Protocol)是一种目录访问协议,用于管理和访问目录服务中的数据。 一、LDAP 概述 LDAP 是...
若依框架支持LDAP认证 该版本是比较老版本,使用新版本可以参照博客修改 相关实现博客:https://blog.csdn.net/shawshank_bingo/article/details/128818128?spm=1001.2014.3001.5501
我们可以使用Vue-Router的全局路由钩子,在访问任何页面时先判断localStorage中是否存在Jwt加密后的Token并且Token是否过期,如果存在且没有过期则正常跳转到请求的页面,不存在或者过期则跳转到登录页重新认证。...
LDAP的研究及其在统一身份认证系统中的应用 LDAP的研究与在校园网统一身份认证中的应用 基于LDAP的统一身份认证的设计与实现 基于LDAP的统一身份认证系统的实现 基于LDAP的校园网统一身份认证系统设计 基于LDAP和...
2. **定义LDAP认证提供者**:使用`LdapAuthenticationProvider`,它负责与LDAP服务器通信进行用户身份验证。可以通过`LdapAuthoritiesPopulator`自定义角色获取策略,将LDAP中的组或OU映射为应用的角色。 3. **配置...
LDAP认证是通过LDAP协议实现的一种用户身份验证机制,广泛应用于企业内部系统的用户管理。 #### 二、LDAP认证过程步骤解析 **1. 客户端发送绑定请求** 客户端首先向LDAP服务器发起绑定请求,这个请求可以是匿名...
在"单点登录 - CAS【三】 LDAP认证源"这个主题中,我们将深入探讨如何将CAS与LDAP(Lightweight Directory Access Protocol)结合使用,以实现基于LDAP的身份验证。LDAP是一种轻量级的目录访问协议,广泛用于存储和...
禅道开源版11.5 LDAP插件是一个用于禅道项目管理软件的扩展工具,它主要功能是集成轻量级目录访问协议(LDAP)进行用户身份验证。此插件允许禅道系统与LDAP服务器通信,使得用户可以通过已有的LDAP账户登录禅道,...
在IT行业中, Lightweight Directory Access Protocol (LDAP) 是一种用于存储和检索目录信息的标准协议,而Active Directory (AD) 是微软提供的目录服务,广泛应用于企业环境中进行用户身份验证和权限管理。...
为了提供安全的用户认证和授权,Tomcat支持多种身份验证机制,其中包括使用外部身份验证服务,如LDAP。 **Lightweight Directory Access Protocol (LDAP)** LDAP是一种开放标准的目录访问协议,用于存储和检索...
4. **故障排查**:当用户登录问题或权限问题出现时,LdapBrowser可以帮助快速定位问题,通过查看和修改目录条目来解决问题。 5. **数据备份与恢复**:LdapBrowser可以方便地导出目录数据,用于备份和恢复操作,确保...
使用开源软件Freeradius及LDAP进行身份认证的说明文档
它利用中间件技术(如LDAP和MOM)解决数据同步、身份验证和通信问题。这种系统可以支持远程参与者进行实时交流,包括视频、音频、文档共享等功能。通过LDAP,系统能实现安全的用户管理;而MOM则确保了信息在各节点间...
- 设置联合存储库,允许WAS与多个身份验证源(如LDAP服务器)进行通信。 - **Ldap存储库**: - 配置Ldap存储库,指定连接到的LDAP服务器的具体参数,如URL、端口、绑定DN等。 - **安全角色到用户/组映射**: - 定义...
基于SSL的LDAP安全访问AD认证 基于SSL的LDAP安全访问AD认证是指使用SSL(Secure Sockets Layer)协议来保护LDAP(Lightweight Directory Access Protocol)协议与AD(Active Directory)的通信,使得密码在网络中...
3. **用户身份验证**:通过ecology系统配置LDAP作为身份验证的后端,允许用户使用LDAP凭证登录。 4. **权限管理**:利用LDAP的访问控制机制,在ecology系统中实施细粒度的权限管理策略。 通过这些步骤,泛微ecology...
### JAVA中使用LDAP进行用户认证的关键知识点 #### LDAP简介与特性 LDAP,即轻量级目录访问协议(Lightweight Directory Access Protocol),源自X.500标准,但更简化且可定制。它支持TCP/IP协议,是互联网环境下...