HttpServletRequest.isUserInRole() returns wrong value
-----------------------------------------------------
Key: GERONIMO-6057
URL: https://issues.apache.org/jira/browse/GERONIMO-6057
Project: Geronimo
Issue Type: Bug
Security Level: public (Regular issues)
Components: console, security
Affects Versions: 3.0
Environment: Tomcat
Reporter: Shenghao Fang
Assignee: Shenghao Fang
HttpServletRequest.isUserInRole("admin") always returns false in Admin Console
although loginned by 'system'. (eg. welcomeNormal.jsp:59)
I did some investigation and found that current implementation in
JACCRealm.hasRole uses wrapper.getName() to get the servlet name.
{code:title=JACCRealm.java|borderStyle=solid}
public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
AccessControlContext acc = ContextManager.getCurrentContext();
String name = wrapper.getName();
/**
* JACC v1.0 secion B.19
*/
if (name == null || name.equals("jsp")) {
name = "";
}
try {
acc.checkPermission(new WebRoleRefPermission(name, role));
return true;
} catch (AccessControlException e) {
return false;
}
}
{code}
But implementation in previous version uses currentRequestWrapperName.get() to
get the servlet name.
{code:title=JACCRealm.java|borderStyle=solid}
public boolean hasRole(Principal principal, String role) {
AccessControlContext acc = ContextManager.getCurrentContext();
String name = currentRequestWrapperName.get();
/**
* JACC v1.0 secion B.19
*/
if (name == null || name.equals("jsp")) {
name = "";
}
try {
acc.checkPermission(new WebRoleRefPermission(name, role));
return true;
} catch (AccessControlException e) {
return false;
}
}
{code}
currentRequestWrapperName is a ThreadLocal variable and is set by
DispatchListener.beforeDispatch()
{code:title=DispatchListener|borderStyle=solid}
private void beforeDispatch(GeronimoStandardContext webContext,
ServletRequest request, ServletResponse response) {
BeforeAfter beforeAfter = webContext.getBeforeAfter();
if (beforeAfter != null) {
Stack<BeforeAfterContext> stack = currentContext.get();
BeforeAfterContext beforeAfterContext = new
BeforeAfterContext(webContext.getContextCount() + 2);
String wrapperName = getWrapperName(request, webContext);
beforeAfterContext.contexts[webContext.getContextCount()] =
JACCRealm.setRequestWrapperName(wrapperName);
beforeAfterContext.contexts[webContext.getContextCount() + 1] =
PolicyContext.getContextID();
PolicyContext.setContextID(webContext.getPolicyContextId());
beforeAfter.before(beforeAfterContext, request, response,
BeforeAfter.DISPATCHED);
stack.push(beforeAfterContext);
}
}
private String getWrapperName(ServletRequest request,
GeronimoStandardContext webContext) {
MappingData mappingData = new MappingData();
Mapper mapper = webContext.getMapper();
MessageBytes mb = MessageBytes.newInstance();
String dispatchPath = (String)
request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);
mb.setString(webContext.getName() + dispatchPath);
try {
mapper.map(mb, mappingData);
StandardWrapper wrapper = (StandardWrapper) mappingData.wrapper;
return wrapper.getName();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
}
{code}
It looks to me that wrapper.getName() returns the name of the initial servlet
instead of the current servlet.
I thought using currentRequestWrapperName.get() leads to the right behavior.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira