<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    nighty

    折騰的年華
    posts - 37, comments - 143, trackbacks - 0, articles - 0
         JForum做為一個(gè)成熟的開(kāi)源BBS論壇解決方案,提供了非常方便的SSO集成接口。它的主頁(yè)上和網(wǎng)上都有許多介紹如何用SSO方式進(jìn)行集成的辦法。這里不羅列,google可以找到許多資料,主要描述一下如何解決用戶名重名的一種方式。目前使用的JForum版本是2.1.8

         簡(jiǎn)單地介紹一下采用的SSO方式。由于應(yīng)用上需要一個(gè)BBS,找了JForum做為一個(gè)子系統(tǒng),集成到現(xiàn)成的一個(gè)管理系統(tǒng)當(dāng)中,管理系統(tǒng)本身有一套完全的身份權(quán)限認(rèn)證方案,由于系統(tǒng)的安全要求不是特別嚴(yán)格,所以采了最直接和最省事的方式:Cookie寫入。即在管理系統(tǒng)登錄時(shí),把用戶信息寫入Cookie,JForum從Cookie中讀取用戶信息進(jìn)行登錄。
         為JForum項(xiàng)目添加一個(gè)SSO接口的擴(kuò)展類CookieSSO,主要實(shí)現(xiàn)authenticateUser(RequestContext request)方法。方法大體如下:
        
    public String authenticateUser(RequestContext request) {
            String userId 
    = null;
            Cookie c 
    = ControllerUtils.getCookie("ehrbbsuserid");
            
    if(c!=null){
                userId 
    = c.getValue();
            }

            logger.info(
    "單點(diǎn)登錄BBS用戶ID為:" + userId);
            
    return userId;
        }
        就是從Cookie中讀取在管理系統(tǒng)中放入的username。但是這里寫的是:ehrbbsuserid,主要是這個(gè)變量名來(lái)區(qū)分傳過(guò)來(lái)的內(nèi)容的不同。

        按照正常的方式就是從管理系統(tǒng)把一個(gè)用戶的username傳過(guò)來(lái)。然后在這里取出,return給調(diào)用方法進(jìn)行驗(yàn)證。在實(shí)際項(xiàng)目中,問(wèn)題就出在這里了
         舉例說(shuō)有二個(gè)用戶名字都叫:李四,那么當(dāng)二個(gè)李四都同時(shí)登錄時(shí),JForum的驗(yàn)證方式就會(huì)出問(wèn)題!它認(rèn)不清到底是哪個(gè)李四,數(shù)據(jù)庫(kù)查詢時(shí)只按第一個(gè)來(lái)!
         仔細(xì)看一下jforum的數(shù)據(jù)庫(kù)表設(shè)計(jì),jforum_user這個(gè)表沒(méi)有display_user_name類似的字段,它就是把username做為顯示在頁(yè)面上的用戶名,如果不做集成,把它單獨(dú)做為一個(gè)BBS時(shí),username既是登錄的用戶名,也是顯示在頁(yè)面上的用戶名。主要原因我想大概就是老外的思維方式跟中國(guó)人的不太一樣。中國(guó)人登錄的時(shí)候用英文,顯示的時(shí)候還有一個(gè)昵稱或是中文名等。
         所以把它集成的時(shí)候,用Cookie傳送一個(gè)username給JForum時(shí)就得用中文(而且重名的概率很大)。我們?cè)俑M(jìn)一個(gè)它的代碼,看是誰(shuí)調(diào)用了SSO接口的這個(gè)方法:
        結(jié)果發(fā)現(xiàn)是類: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);
            }

        }
         在這里明顯的,它是通過(guò)username去確定這個(gè)人是否存在?再繼續(xù)跟進(jìn)代碼就會(huì)發(fā)現(xiàn)最后調(diào)用了Dao的selectUserByName方法。

         解決的思路:修改JForum的數(shù)據(jù)庫(kù)表,并更改代碼和頁(yè)面文件是不科學(xué)的,工作量大,而且風(fēng)險(xiǎn)比較高!那么就繼續(xù)把username用來(lái)保存中文名稱,它的user_id是一個(gè)自增的數(shù)字序列。在管理系統(tǒng)的用戶表中,擴(kuò)展一個(gè)字段bbs_user_id,用來(lái)保存在JForum中的用戶id,這個(gè)字段就肯定是唯一的,在管理系統(tǒng)登錄時(shí),把這個(gè)bbs_user_id查詢出來(lái),放到Cookie中。在JForum驗(yàn)證時(shí),不再使用它推薦的返回username方式,而是返回它的user_id值。
         那么回到最上面的CookieSSO類的代碼,這里返回的String其實(shí)是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();
                    /* 重構(gòu)為按userId驗(yàn)證身份 */
    //                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);
            }

        }

        這樣就可以解決認(rèn)證的問(wèn)題!同時(shí)又保證username可以是中文的,而且重名也無(wú)所謂。

        附加:查看它的SQL配置文件,發(fā)現(xiàn)有selectUserByName這樣的方法,通過(guò)用戶名來(lái)查找用戶,起初怕是它在某些模塊中使用了。后來(lái)詳細(xì)查看,發(fā)現(xiàn)它只使用在后臺(tái)管理(即admin模塊)中的用戶管理。這個(gè)頁(yè)面提供了一個(gè)按用戶名來(lái)查找用戶的功能,所以也是非常合理的!


    剛進(jìn)場(chǎng)的時(shí)候戲就落幕

    Feedback

    # re: JForum集成--用戶重名的一種解決方案  回復(fù)  更多評(píng)論   

    2009-10-21 21:50 by liuxin
    請(qǐng)問(wèn):
    JFORUM 1.2.8已經(jīng)將SyntaxHighlighter納入支援 ,為什么我下載JFORUM.WAR ,測(cè)試就沒(méi)有出現(xiàn)類似JAVAEEYE這樣的
    程式碼語(yǔ)法高亮呢?
    我注意了一下:點(diǎn)擊javaeye的頁(yè)面源碼,可以看到頁(yè)面有類似<pre name="code" class="java"> 的代碼,
    我用JFORUM.WAR 測(cè)試的頁(yè)面沒(méi)有生成類似的代碼 ,倒是在HEADER.HTML 頁(yè)有這樣的定義: <#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);}

    請(qǐng)問(wèn)我在JAVA 代碼中怎么改動(dòng)才能夠?qū)崿F(xiàn)頁(yè)面程式碼語(yǔ)法高亮呢?
    期待你的幫助
    我的EMAIL:liuxinsudi@163.com

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲最大成人网色| 亚洲日韩aⅴ在线视频| 亚洲成电影在线观看青青| 国产精品无码免费专区午夜 | 蜜臀98精品国产免费观看| 国产V亚洲V天堂A无码| 久久久久免费视频| 亚洲国产精品一区二区第一页| 一本到卡二卡三卡免费高| 亚洲AV日韩精品一区二区三区| 久久久久免费看黄A片APP| 亚洲欧洲日产国码在线观看| free哆啪啪免费永久| 亚洲国产精品免费在线观看| 和日本免费不卡在线v| 亚洲一区电影在线观看| 韩国二级毛片免费播放| 麻豆一区二区三区蜜桃免费| 亚洲伊人成无码综合网| 毛片免费在线观看| 亚洲高清日韩精品第一区| 免费视频专区一国产盗摄| 亚洲精品理论电影在线观看| www国产亚洲精品久久久日本| 黄桃AV无码免费一区二区三区 | 中文字幕免费观看| 亚洲1区1区3区4区产品乱码芒果 | 亚洲综合色在线观看亚洲| 两性色午夜视频免费网| 亚洲专区先锋影音| 岛国片在线免费观看| 成人免费观看男女羞羞视频| 亚洲精品无码MV在线观看| 免费下载成人电影| xxxxx做受大片视频免费| 久久亚洲AV午夜福利精品一区| 一二三四免费观看在线电影| 香蕉97碰碰视频免费| 亚洲永久永久永久永久永久精品| 成人免费无码大片A毛片抽搐色欲 成人免费无码大片a毛片 | 国产福利电影一区二区三区,亚洲国模精品一区 |