近日发现一个奇怪的问题。一个Portlet,匿名用户访问没有问题,如果用户登陆后,反而出现权限问题,消息显示"您没有存取这portlet所需权限的角色"。
7.1 源代码分析
试图通过分析源代码,找出问题的原因。
查找资源文件
you-do-not-have-the-roles-required-to-access-this-portlet=您没有存取这portlet所需权限的角色 。
查找"you-do-not…"的位置
出现在文件portal-web/docroot/html/portal/portlet_access_denied.jsp 中
查找portlet_access_denied.jsp的出现位置
有两个出现位置
1、tiles-defs.xml
<definition name="portal.portlet_access_denied" extends="portlet">
<put name="portlet_content" value="/portal/portlet_access_denied.jsp" />
</definition>
2、portal/portal-web/docroot/html/common/themes/portlet_content.jsp中
<c:if test="<%= !portletDisplay.isAccess() %>">
<liferay-util:include page="/html/portal/portlet_access_denied.jsp" />
</c:if>
查找portal.portlet_access_denied
在portal/portal-web/docroot/WEB-INF/struts-config.xml文件中
<forward name="/portal/portlet_access_denied" path="portal.portlet_access_denied" />
查找/portal/portlet_access_denied
在Java文件portal/portal-ejb/src/com/liferay/portal/struts/PortletRequestProcessor.java中
private static final String _PATH_PORTAL_PORTLET_ACCESS_DENIED =
"/portal/portlet_access_denied";
查找_PATH_PORTAL_PORTLET_ACCESS_DENIED
也是在Java文件PortletRequestProcessor.java中,出现在第356行。在此设一个断点,看看是否是走这条线出现的问题。
经过测试,似乎没有断点没有生效,说明不是走这条线出现的问题。然后试图从另一条线开始检查。
检查com.liferay.portal.theme.PortletDisplay.isAccess()
这个地方比较麻烦,尝试了好几钟方法
1、 设置断点,并修改值。在isAccess()上设置断点,并设置条件为 _access==false,到这个点确实暂停。尝试将_access的值,从false改为true。但还是出现同样的问题,页面还是显示没有权限。
2、 还是设置断点,并设置条件。分别开两个窗口,一个登录,一个不登陆。分别刷新,看看是否都会停在断点上。
结果这两个方法,都没有发现什么有意义的线索。怀疑jsp中的portletDisplay并不是com.liferay.portal.theme.PortletDisplay的实例。
3、 修改JSP文件,显示一下portletDisplay.toString()。
7.2 重新整理思路,查看源代码
前 面的思路有点乱,重新检查。前面提到,有两种可能,分别在两个JSP里面显示没有权限的信息。简单期间,我在两个JSP里面放置了不同的内容,最终发现, 错误提示是从第一条线过来的,也就是在PortletRequestProcessor.java的第356行抛出了错误。
在这个函数里面设置了断点,分别用匿名用户和登录用户进行了测试,发现:如果是匿名用户,根本就不会执行processRoles()函数。对这一点的初步结论是:只有登录用户,才会调用processRoles()进行角色的判断。
回 到当前的这个问题上来,表面原因已经找到,跟我的业务相关:我想把在Calendar Portlet的基础之上进行必要的修改,但又不想动Liferay自己的东西。因此,我想的是,把JSP拷贝一份新的,做一个新的portlet。但可 能是某个地方还没设置对,在进行
if (!strutsPath.equals(portlet.getStrutsPath())) {
throw new PrincipalException();
}
判 断的时候,strutsPath="ext/calendar",而portlet.getStrutsPath()是"calendar"。因为路径的 原因导致的。最终检查发现是在liferay-portlet-ext.xml中定义struts-path 时,写成了<struts-path>calendar</struts-path>,修改为<struts- path>ext/calendar</struts-path>。重新发布启动测试,正常。
7.3 一个结论
通过我的一些开发碰到的情况,出现权限的问题,除了确实权限设置错误之外,一般情况都是struts路径的问题。有两点需要注意的:
1、 portal-ext.xml中定义的struts路径,同liferay-portlet-ext.xml中<struts-path> 的值能够对应起来。如portal-ext.xml里面是/ext/calendar/view,则liferay-portlet-ext.xml是 ext/calendar。掐头去尾之后,一定要一致。
2、 同一个portlet中用到的所有的Struts的Action,路径应该是一致的,也就是说掐头去尾之后,都应该是liferay-portlet-ext.xml中<struts-path>的值。
7.1 源代码分析
试图通过分析源代码,找出问题的原因。
查找资源文件
you-do-not-have-the-roles-required-to-access-this-portlet=您没有存取这portlet所需权限的角色 。
查找"you-do-not…"的位置
出现在文件portal-web/docroot/html/portal/portlet_access_denied.jsp 中
查找portlet_access_denied.jsp的出现位置
有两个出现位置
1、tiles-defs.xml
<definition name="portal.portlet_access_denied" extends="portlet">
<put name="portlet_content" value="/portal/portlet_access_denied.jsp" />
</definition>
2、portal/portal-web/docroot/html/common/themes/portlet_content.jsp中
<c:if test="<%= !portletDisplay.isAccess() %>">
<liferay-util:include page="/html/portal/portlet_access_denied.jsp" />
</c:if>
查找portal.portlet_access_denied
在portal/portal-web/docroot/WEB-INF/struts-config.xml文件中
<forward name="/portal/portlet_access_denied" path="portal.portlet_access_denied" />
查找/portal/portlet_access_denied
在Java文件portal/portal-ejb/src/com/liferay/portal/struts/PortletRequestProcessor.java中
private static final String _PATH_PORTAL_PORTLET_ACCESS_DENIED =
"/portal/portlet_access_denied";
查找_PATH_PORTAL_PORTLET_ACCESS_DENIED
也是在Java文件PortletRequestProcessor.java中,出现在第356行。在此设一个断点,看看是否是走这条线出现的问题。
经过测试,似乎没有断点没有生效,说明不是走这条线出现的问题。然后试图从另一条线开始检查。
检查com.liferay.portal.theme.PortletDisplay.isAccess()
这个地方比较麻烦,尝试了好几钟方法
1、 设置断点,并修改值。在isAccess()上设置断点,并设置条件为 _access==false,到这个点确实暂停。尝试将_access的值,从false改为true。但还是出现同样的问题,页面还是显示没有权限。
2、 还是设置断点,并设置条件。分别开两个窗口,一个登录,一个不登陆。分别刷新,看看是否都会停在断点上。
结果这两个方法,都没有发现什么有意义的线索。怀疑jsp中的portletDisplay并不是com.liferay.portal.theme.PortletDisplay的实例。
3、 修改JSP文件,显示一下portletDisplay.toString()。
7.2 重新整理思路,查看源代码
前 面的思路有点乱,重新检查。前面提到,有两种可能,分别在两个JSP里面显示没有权限的信息。简单期间,我在两个JSP里面放置了不同的内容,最终发现, 错误提示是从第一条线过来的,也就是在PortletRequestProcessor.java的第356行抛出了错误。
在这个函数里面设置了断点,分别用匿名用户和登录用户进行了测试,发现:如果是匿名用户,根本就不会执行processRoles()函数。对这一点的初步结论是:只有登录用户,才会调用processRoles()进行角色的判断。
回 到当前的这个问题上来,表面原因已经找到,跟我的业务相关:我想把在Calendar Portlet的基础之上进行必要的修改,但又不想动Liferay自己的东西。因此,我想的是,把JSP拷贝一份新的,做一个新的portlet。但可 能是某个地方还没设置对,在进行
if (!strutsPath.equals(portlet.getStrutsPath())) {
throw new PrincipalException();
}
判 断的时候,strutsPath="ext/calendar",而portlet.getStrutsPath()是"calendar"。因为路径的 原因导致的。最终检查发现是在liferay-portlet-ext.xml中定义struts-path 时,写成了<struts-path>calendar</struts-path>,修改为<struts- path>ext/calendar</struts-path>。重新发布启动测试,正常。
7.3 一个结论
通过我的一些开发碰到的情况,出现权限的问题,除了确实权限设置错误之外,一般情况都是struts路径的问题。有两点需要注意的:
1、 portal-ext.xml中定义的struts路径,同liferay-portlet-ext.xml中<struts-path> 的值能够对应起来。如portal-ext.xml里面是/ext/calendar/view,则liferay-portlet-ext.xml是 ext/calendar。掐头去尾之后,一定要一致。
2、 同一个portlet中用到的所有的Struts的Action,路径应该是一致的,也就是说掐头去尾之后,都应该是liferay-portlet-ext.xml中<struts-path>的值。