当开源论坛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>