当开源论坛JForum配置了SSO时要指定过滤的URL,而此时如果指定的URL为/*时就无法实现游客的浏览功能。
好在JForum的请求URL都经过了特殊配置,对于要经过登录的才能进行的操作,如回复·站内信等等都可以很轻松的指定URL来过滤。但在发表主题或修改主题时,JForum却使用了最常用的的URL方法:jfroum.page?module=posts&action=insert&....
而SERVLET过滤器的<url-pattern>却不能使用类似”jfroum.page*“这样子的映射。这时候JForum就是自动跳转到sso.redirect指定的URL。但他不会走SSO指定的过滤器。从而也无法实现登录效果。现在如下修改即可(我使用的SSO是自己写的超简单的SSO,所以可以很轻松的把过滤器的代码写进JForum源码中):
修改net.jforum.view.forum.common.ViewCommon的public static String contextToLogin(String returnPath)方法:
/** * 首先要调用过滤器中内容。查看Cookies是不是存有了用户名。 */ UserSession userSession = SessionFacade.getUserSession(); RequestContext request = JForumExecutionContext.getRequest(); javax.servlet.http.Cookie diskCookies[] = request.getCookies(); if (diskCookies != null) { for (int i = 0; i < diskCookies.length; i++) { if (diskCookies[i].getName().equals(SystemGlobals.getValue(ConfigKeys.SSO_COOKIENAME))) { String cookieValue = diskCookies[i].getValue(); try{ String result = SSOService(cookieValue); request.getSessionContext().setAttribute("SSOUser", result); new /** *这一步最重要,是手动调用了JForum的检查SSO的方法。不然还是无法实现登录操作 **/ ControllerUtils().checkSSO(userSession); break; }catch(Exception e){} } } } String secondReturn = returnPath; if (ConfigKeys.TYPE_SSO.equals(SystemGlobals.getValue(ConfigKeys.AUTHENTICATION_TYPE))) { String redirect = SystemGlobals.getValue(ConfigKeys.SSO_REDIRECT); if (!StringUtils.isEmpty(redirect)) { URI redirectUri = URI.create(redirect); if (!redirectUri.isAbsolute()) { throw new ForumException( "SSO redirect URL should start with a scheme"); } try { if (returnPath.indexOf("/") == 0) returnPath = returnPath.substring(1); returnPath = URLEncoder.encode(ViewCommon.getForumLink() + returnPath, "UTF-8"); } catch (UnsupportedEncodingException e) { } if (redirect.indexOf('?') == -1) { redirect += "?"; } else { redirect += "&"; } redirect += "goto=" + returnPath; //判断是否登录了,如果没有登录就跳转SSO站点 if (userSession.getUserId() == SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID) || userSession.getUsername() == null || "".equals(userSession.getUsername())) { JForumExecutionContext.setRedirect(redirect); } else { //登录后就直接跳到请示的URL上。 JForumExecutionContext.setRedirect(secondReturn); } //检查COOKIES的方法 private static java.lang.String SSOService(java.lang.String cookievalue) throws java.io.IOException { org.apache.commons.httpclient.HttpClient httpclient = null; org.apache.commons.httpclient.methods.GetMethod httpget = null; java.lang.String authAction = "?action=authcookie&cookiename="; httpclient = new HttpClient(); httpget = new GetMethod( (new StringBuilder()).append(SystemGlobals.getValue(ConfigKeys.SSO_SERVICEURL)).append(authAction).append( cookievalue).toString()); try { java.lang.String s; httpclient.executeMethod(httpget); java.lang.String result = httpget.getResponseBodyAsString(); s = result; httpget.releaseConnection(); return s; } catch (Exception e) { httpget.releaseConnection(); return "failed"; } }
注:修改了SystemGlobal.properties文件添加了两个参数用来指定约定的cookie的名称,及SSO服务器的URL。
#The SSO service URL
#
#used this url from posts a new topic or modify it
#
sso.serviceURL = http://xxx.com/SSO.do
#The SSO Cookies Name
#
#used this for save the user name that logined from sso
#
sso.cookieName = cookie-name
最后的WEB-XML文件中过滤器配置如下:
<filter> <filter-name>SSOFilter</filter-name> <filter-class>sso.filter.SSOFilter</filter-class> <init-param> <param-name>cookieName</param-name> <param-value>cookie-name</param-value> </init-param> <init-param> <param-name>SSOServiceURL</param-name> <param-value>http://xxx.com/SSO.do</param-value> </init-param> <init-param> <param-name>SSOLoginPage</param-name> <param-value>http://xxx.com/login.jsp</param-value> </init-param> </filter> <!--关于站内信的URL--> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/pm/*</url-pattern> </filter-mapping> <!--下面都是关于回复贴子的URL--> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/posts/reply/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/posts/quote/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/posts/insert/*</url-pattern> </filter-mapping> <!--查看活动日志--> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/moderation/showActivityLog.page</url-pattern> </filter-mapping> <!--管理员登录后台的URL--> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/admBase/login.page</url-pattern> </filter-mapping>