nighty
折腾的年华
posts - 37, comments - 143, trackbacks - 0, articles - 0
导航
BlogJava
首页
新随笔
联系
聚合
管理
<
2009年10月
>
日
一
二
三
四
五
六
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(7)
给我留言
查看公开留言
查看私人留言
随笔分类
Eclipse(7)
Flex(2)
Java(6)
Struts2(2)
SWT/JFace(1)
信息安全(1)
心得(5)
操作系统(3)
数据库(3)
服务器部署(5)
测试(2)
系统集成(2)
软件架构(2)
随笔档案
2013年4月 (2)
2013年3月 (1)
2012年4月 (1)
2011年10月 (1)
2011年8月 (1)
2011年5月 (3)
2011年4月 (1)
2011年3月 (2)
2011年2月 (1)
2011年1月 (1)
2010年11月 (1)
2009年11月 (1)
2009年10月 (1)
2009年8月 (1)
2009年7月 (1)
2008年8月 (2)
2008年7月 (2)
2008年6月 (2)
2008年5月 (4)
2008年4月 (1)
2008年1月 (1)
2007年11月 (1)
2007年10月 (2)
2007年8月 (2)
文章分类
测试
搜索
最新评论
1. re: 关于commons dbutils组件的一个小缺陷分析
dbutils中连传入到的参数都不区分大小写??
--starhe
2. re: B/S,C/S架构混合使用[未登录]
评论内容较长,点击标题查看
--eagle
3. re: B/S,C/S架构混合使用[未登录]
补充一下:用的语言是java,开发环境是eclipse
--eagle
4. re: B/S,C/S架构混合使用
评论内容较长,点击标题查看
--Unbotrusive
5. re: struts2中重定向中文参数乱码梳理[未登录]
有用啊
--tony
阅读排行榜
1. ubuntu安装Java开发环境(38182)
2. Eclipse3.3安装中文语言包(13936)
3. Http状态码思维导图(13748)
4. B/S,C/S架构混合使用(13734)
5. 添加完整的Eclipse RCP帮助系统(8927)
评论排行榜
1. B/S,C/S架构混合使用(25)
2. 无奈只能放弃iBatis(24)
3. Eclipse3.3安装中文语言包(13)
4. httpclient3.1使用小结(8)
5. JDBC连接DB2的一些总结(8)
JForum集成--用户重名的一种解决方案
Posted on 2009-10-14 17:41
寒武纪
阅读(2164)
评论(1)
编辑
收藏
所属分类:
系统集成
JForum做为一个成熟的开源BBS论坛解决方案,提供了非常方便的SSO集成接口。它的主页上和网上都有许多介绍如何用SSO方式进行集成的办法。这里不罗列,google可以找到许多资料,主要描述一下如何解决用户名重名的一种方式。目前使用的JForum版本是2.1.8
简单地介绍一下采用的SSO方式。由于应用上需要一个BBS,找了JForum做为一个子系统,集成到现成的一个管理系统当中,管理系统本身有一套完全的身份权限认证方案,由于系统的安全要求不是特别严格,所以采了最直接和最省事的方式:Cookie写入。即在管理系统登录时,把用户信息写入Cookie,JForum从Cookie中读取用户信息进行登录。
为JForum项目添加一个SSO接口的扩展类CookieSSO,主要实现authenticateUser(RequestContext request)方法。方法大体如下:
public
String authenticateUser(RequestContext request)
{
String userId
=
null
;
Cookie c
=
ControllerUtils.getCookie(
"
ehrbbsuserid
"
);
if
(c
!=
null
)
{
userId
=
c.getValue();
}
logger.info(
"
单点登录BBS用户ID为:
"
+
userId);
return
userId;
}
就是从Cookie中读取在管理系统中放入的username。但是这里写的是:ehrbbsuserid,主要是这个变量名来区分传过来的内容的不同。
按照正常的方式就是从管理系统把一个用户的username传过来。然后在这里取出,return给调用方法进行验证。在实际项目中,
问题就出在这里了
!
举例说有二个用户名字都叫:李四,那么当二个李四都同时登录时,JForum的验证方式就会出问题!它认不清到底是哪个李四,数据库查询时只按第一个来!
仔细看一下jforum的数据库表设计,jforum_user这个表没有display_user_name类似的字段,它就是把username做为显示在页面上的用户名,如果不做集成,把它单独做为一个BBS时,username既是登录的用户名,也是显示在页面上的用户名。主要原因我想大概就是老外的思维方式跟中国人的不太一样。中国人登录的时候用英文,显示的时候还有一个昵称或是中文名等。
所以把它集成的时候,用Cookie传送一个username给JForum时就得用中文(而且重名的概率很大)。我们再跟进一个它的代码,看是谁调用了SSO接口的这个方法:
结果发现是类:net.jforum.ControllerUtils的checkSSO(UserSession userSession)方法
/** */
/**
* Checks for user authentication using some SSO implementation
*
@param
userSession UserSession
*/
protected
void
checkSSO(UserSession userSession)
{
try
{
SSO sso
=
(SSO) Class.forName(SystemGlobals.getValue(ConfigKeys.SSO_IMPLEMENTATION)).newInstance();
String username
=
sso.authenticateUser(JForumExecutionContext.getRequest());
if
(username
==
null
||
username.trim().equals(
""
))
{
userSession.makeAnonymous();
}
else
{
SSOUtils utils
=
new
SSOUtils();
if
(
!
utils.userExists(username))
{
SessionContext session
=
JForumExecutionContext.getRequest().getSessionContext();
String email
=
(String) session.getAttribute(SystemGlobals.getValue(ConfigKeys.SSO_EMAIL_ATTRIBUTE));
String password
=
(String) session.getAttribute(SystemGlobals.getValue(ConfigKeys.SSO_PASSWORD_ATTRIBUTE));
if
(email
==
null
)
{
email
=
SystemGlobals.getValue(ConfigKeys.SSO_DEFAULT_EMAIL);
}
if
(password
==
null
)
{
password
=
SystemGlobals.getValue(ConfigKeys.SSO_DEFAULT_PASSWORD);
}
utils.register(password, email);
}
this
.configureUserSession(userSession, utils.getUser());
}
}
catch
(Exception e)
{
e.printStackTrace();
throw
new
ForumException(
"
Error while executing SSO actions:
"
+
e);
}
}
在这里明显的,它是通过username去确定这个人是否存在?再继续跟进代码就会发现最后调用了Dao的selectUserByName方法。
解决的思路:修改JForum的数据库表,并更改代码和页面文件是不科学的,工作量大,而且风险比较高!那么就继续把username用来保存中文名称,它的user_id是一个自增的数字序列。在管理系统的用户表中,扩展一个字段bbs_user_id,用来保存在JForum中的用户id,这个字段就肯定是唯一的,在管理系统登录时,把这个bbs_user_id查询出来,放到Cookie中。在JForum验证时,不再使用它推荐的返回username方式,而是返回它的user_id值。
那么回到最上面的CookieSSO类的代码,这里返回的String其实是jforum_user表中user_id字段。为了匹配,那么net.jforum.ControllerUtils的checkSSO(UserSession userSession)方法也要改!改为下面的方式:
protected
void
checkSSO(UserSession userSession)
{
try
{
SSO sso
=
(SSO) Class.forName(SystemGlobals.getValue(ConfigKeys.SSO_IMPLEMENTATION)).newInstance();
String username
=
sso.authenticateUser(JForumExecutionContext.getRequest());
if
(username
==
null
||
username.trim().equals(
""
))
{
userSession.makeAnonymous();
}
else
{
//
SSOUtils utils = new SSOUtils();
/**/
/*
重构为按userId验证身份
*/
//
if (!utils.userExists(username)) {
//
SessionContext session = JForumExecutionContext.getRequest().getSessionContext();
//
//
String email = (String) session.getAttribute(SystemGlobals.getValue(ConfigKeys.SSO_EMAIL_ATTRIBUTE));
//
String password = (String) session.getAttribute(SystemGlobals.getValue(ConfigKeys.SSO_PASSWORD_ATTRIBUTE));
//
//
if (email == null) {
//
email = SystemGlobals.getValue(ConfigKeys.SSO_DEFAULT_EMAIL);
//
}
//
//
if (password == null) {
//
password = SystemGlobals.getValue(ConfigKeys.SSO_DEFAULT_PASSWORD);
//
}
//
//
utils.register(password, email);
//
}
/**/
/*
新添加的代码
*/
UserDAO dao
=
DataAccessDriver.getInstance().newUserDAO();
User user
=
dao.selectById(Integer.parseInt(username));
//
this.configureUserSession(userSession, utils.getUser());
this
.configureUserSession(userSession, user);
}
}
catch
(Exception e)
{
e.printStackTrace();
throw
new
ForumException(
"
Error while executing SSO actions:
"
+
e);
}
}
这样就可以解决认证的问题!同时又保证username可以是中文的,而且重名也无所谓。
附加:查看它的SQL配置文件,发现有selectUserByName这样的方法,通过用户名来查找用户,起初怕是它在某些模块中使用了。后来详细查看,发现它只使用在后台管理(即admin模块)中的用户管理。这个页面提供了一个按用户名来查找用户的功能,所以也是非常合理的!
刚进场的时候戏就落幕
Feedback
#
re: JForum集成--用户重名的一种解决方案
回复
更多评论
2009-10-21 21:50 by
liuxin
请问:
JFORUM 1.2.8已经將SyntaxHighlighter納入支援 ,为什么我下载JFORUM.WAR ,测试就没有出现类似JAVAEEYE这样的
程式碼語法高亮呢?
我注意了一下:点击javaeye的页面源码,可以看到页面有类似<pre name="code" class="java"> 的代码,
我用JFORUM.WAR 测试的页面没有生成类似的代码 ,倒是在HEADER.HTML 页有这样的定义: <#assign hasCodeBlock = hasCodeBlock?default(false)/>,在bottom.HTML <#if hasCodeBlock><#include "highlighter_js.htm"/>
但是在JAVA 中只有net.jforum.view.forum.common.PostCommon private static void processText(Post post)
boolean hasCodeBlock = false; ... if (hasCodeBlock) {JForumExecutionContext.getTemplateContext().put("hasCodeBlock", hasCodeBlock);}
请问我在JAVA 代码中怎么改动才能够实现页面程式碼語法高亮呢?
期待你的帮助
我的EMAIL:liuxinsudi@163.com
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理
相关文章:
Http状态码思维导图
JForum集成--用户重名的一种解决方案
Powered by:
BlogJava
Copyright © 寒武纪