Home
Analytics
Accessing servlet context in the report
zszugyi
I'm wondering if it's possible to access the servlet context from either a scripted event handler
or by a report when executed from the ActuateJavaComponent's information console.
We're deploying the web app on JBoss and we're authenticating using JAAS and a custom login module.
The reports need to somehow access the user principal from the request in order to determine what
data the user has access to.
One way could be if the user name can be passed to the data source as a report parameter. Is that
possible or is there some other way to accomplish this?
We're using Actuate 10sp1F4.
Thanks!
Find more posts tagged with
Comments
averma
Hi zszugyi,
You can pass username as a hidden parameter or you can also use reportContext.getAppContext() for reading and modifying the context within the scripts.
Ashwini
zszugyi
<blockquote class='ipsBlockquote' data-author="'averma'" data-cid="66627" data-time="1279739243" data-date="21 July 2010 - 12:07 PM"><p>
Hi zszugyi,<br />
You can pass username as a hidden parameter or you can also use reportContext.getAppContext() for reading and modifying the context within the scripts.<br />
<br />
Ashwini<br /></p></blockquote>
<br />
Hi Ashwini, <br />
<br />
Thanks for the reply. <br />
I made a mistake in my original post, I did mean to write scripted data source instead of "event handler".<br />
I'd guess your reply still applies: I can specify an event handler for the data source which would populate the hidden parameter from reportContext.getAppContext(). Is that correct?<br />
<br />
Thanks,<br />
Zoltan
averma
Yes you can take that approach. You should also be able to use this script directly in your expression builder for any filter condition etc.
Ashwini
zszugyi
I've tried to add a dataset parameter and setting the default value to<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>reportContext.getHttpServletRequest().getUserPrincipal().getName()</pre>.<br />
<br />
WHen opening the report, I get the error message saying that the result of <pre class='_prettyXprint _lang-auto _linenums:0'>reportContext.getHttpServletRequest()</pre> is null.<br />
<br />
Searching online, it looks like other people have the same issue, for example:<br />
<a class='bbc_url' href='
https://jira.jboss.org/browse/JBIDE-4929'>https://jira.jboss.org/browse/JBIDE-4929</a><br
/>
<br />
Is there a way to fix this in the actuate viewer servlet?<br />
<br />
Thanks!
zszugyi
I have more information on this:<br />
If I put the following code in the beforeOpen of a scripted data set is used in <br />
cascading parameter group (where I would need it), the value of reportContext.getHttpServletRequest() <br />
is null and the appContext doesn't have anything useful either.<br />
Output:<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
17:37:56,661 INFO [ProductDataSetHandler] org.eclipse.birt.report.engine.script.internal.ReportContextImpl@6e1b83aa
17:37:56,661 INFO [ProductDataSetHandler] {org.eclipse.datatools.connectivity.oda.util_consumerResourceIds=org.eclipse.datatools.connectivity.oda.util.ResourceIdentifiers@5061465f, EXTENDED_ITEM_MAX_ROW=0, ServerUserName=anonymous, PARENT_CLASSLOADER=java.net.URLClassLoader@49e926fd, max_pool_size=10, AppRuntimeLocale=en_US, OdaConsumerId=com.actuate.data.oda.birt.propertyProvider, connection_time_out=3600, OdaConnPropertyContext={}, webapplication.projectclasspath=, org.eclipse.birt.data.query.ResultBufferSize=10,
birt.viewer.resource.path=C:\jboss-sw\server\scrumworks\.\deploy\ActuateJavaComponent.war\resources}
17:37:56,662 INFO [ProductDataSetHandler] servlet request = null
</pre>
<br />
If I put the the same code in the beforeOpen of the scripted dataset that provides the report data, <br />
the request is available and I can get the user name.<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
17:48:11,283 INFO [ReleaseBurnupReportDataSetEventHandler] {ReportParameters={product=-5.010744238007635986E18, username=administrator, forecast=false, release=-3.37001432750203367E17}, EXTENDED_ITEM_MAX_ROW=0, max_pool_size=10, ServerUserName=anonymous, AppRuntimeLocale=en_US, connection_time_out=3600, birt.viewer.resource.path=C:\jboss-sw\server\scrumworks\.\deploy\ActuateJavaComponent.war\resources, BIRT_VIEWER_HTTPSERVET_REQUEST=org.apache.catalina.connector.RequestFacade@276a0d23, org.eclipse.datatools.connectivity.oda.util_consumerResourceIds=org.eclipse.datatools.connectivity.oda.util.ResourceIdentifiers@76e88857, PARENT_CLASSLOADER=java.net.URLClassLoader@49e926fd, OdaConsumerId=com.actuate.data.oda.birt.propertyProvider, webapplication.projectclasspath=, OdaConnPropertyContext={}, org.eclipse.birt.data.query.ResultBufferSize=10}
17:48:11,283 INFO [ReleaseBurnupReportDataSetEventHandler] servlet request = org.apache.catalina.connector.RequestFacade@276a0d23
17:48:11,284 INFO [ReleaseBurnupReportDataSetEventHandler] username: ****
</pre>
<br />
Here's the code: <br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
l.info("beforeOpen");
l.info(reportContext);
l.info(reportContext.getAppContext());
l.info("servlet request = " + reportContext.getHttpServletRequest());
String userName = ((HttpServletRequest) reportContext.getHttpServletRequest()).getUserPrincipal().getName();
l.info("username: " + userName);
</pre>
<br />
I get the same result if I do the same thing in a JS event handler in the report designer.<br />
<br />
Is this a bug or is this the expected behavior? If so, does anyone know a workaround?<br />
<br />
Thanks,<br />
Zoltan
averma
Hi Zoltan,
Can you try binding your scripted data set to a table in the report? Make this table as the first report item in the design. You can set the visibility of the table to false to hide this table in the report output.
Ashwini
zszugyi
Hi Ashwini, <br />
<br />
I've tried, it does not work. When the data set is first opened to populate a parameter list, the request is null.<br />
When the data set is opened for the second time after clicking "Finish", the request is correctly populated.<br />
<br />
Thanks,<br />
Zoltan<br />
<br />
<blockquote class='ipsBlockquote' data-author="'averma'" data-cid="66783" data-time="1280250551" data-date="27 July 2010 - 10:09 AM"><p>
Hi Zoltan,<br />
Can you try binding your scripted data set to a table in the report? Make this table as the first report item in the design. You can set the visibility of the table to false to hide this table in the report output.<br />
<br />
Ashwini<br /></p></blockquote>
zszugyi
I'm wondering if it'd be possible subclassing AcGetFolderItemsAction or AcSubmitJobAction
to set "BIRT_VIEWER_HTTPSERVET_REQUEST" in the app context. If so, which methods in which classes
would have to do this?
Thanks,
Zoltan
PuckPuck
<span style='font-family: Courier New'>reportContext.getAppContext().get("ServerUserName")</span><br />
<br />
This will return you the username of the currently logged in user running the report. Going down the road of modifying the HttpServletContext passed to the report, is not recommended.
zszugyi
<blockquote class='ipsBlockquote' data-author="'PuckPuck'" data-cid="66813" data-time="1280330162" data-date="28 July 2010 - 08:16 AM"><p>
<span style='font-family: Courier New'>reportContext.getAppContext().get("ServerUserName")</span><br />
<br />
This will return you the username of the currently logged in user running the report. Going down the road of modifying the HttpServletContext passed to the report, is not recommended.<br /></p></blockquote>
<br />
We're using JAAS to authenticate the user, so ServerUserName is not populated. <br />
I'm not trying to modify the HttpServletRequest, I'm trying to figure out why it's not accessible from the<br />
reportContext of AppContext when selecting the report parameters.
PuckPuck
<blockquote class='ipsBlockquote' data-author="'zszugyi'" data-cid="66815" data-time="1280332279" data-date="28 July 2010 - 08:51 AM"><p>
We're using JAAS to authenticate the user, so ServerUserName is not populated. <br />
I'm not trying to modify the HttpServletRequest, I'm trying to figure out why it's not accessible from the<br />
reportContext of AppContext when selecting the report parameters.<br /></p></blockquote>
<br />
Actuate Java Components has a single sign-on extension module (called Security Adapter). This should be implemented to validate and accept the credentials from your web application. Once done, ServerUserName will have a value. This is how Actuate Java Component was intended to be used, as authentication needs to happen within the web application itself, not the application server context, which I assume is how you are using JAAS.
zszugyi
Thanks for the reply!<br />
<br />
I've created a class which extends the LocalSecurityAdapter and deployed it as per the instructions<br />
at <a class='bbc_url' href='
http://www.birt-exchange.org/org/wiki/index.php?title=Security_Integration_with_the_Actuate_BIRT_Viewers.'>http://www.birt-exchange.org/org/wiki/index.php?title=Security_Integration_with_the_Actuate_BIRT_Viewers.</a><br
/>
<br />
This is how it looks like:<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
public class SecurityAdapter extends LocalSecurityAdapter {
Logger logger = Logger.getLogger("birt");
private String userName;
/** {
@inheritDoc}
*/
@Override
public boolean authenticate(HttpServletRequest request) throws AuthenticationException {
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal == null) {
logger.info("no user principal");
logger.info(request);
logger.info(request.getAuthType());
}
this.userName = userPrincipal.getName();
logger.info("user name: " + userName);
return userPrincipal != null;
}
/** {
@inheritDoc}
*/
@Override
public String getUserName() {
logger.info("getUserName(): " + userName);
return userName;
}
}
</pre>
<br />
Looking at the log, it seems like authenticate() and getUserName() are both called and are correct.<br />
The ServerUserName is not set in the appContext correctly though, its value is "anonymous".<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
14:11:08,336 INFO [birt] user name: zoli
14:11:08,337 INFO [birt] getUserName(): zoli
14:11:30,759 INFO [DataSetHandler] beforeOpen
14:11:30,760 INFO [DataSetHandler] {org.eclipse.datatools.connectivity.oda.util_consumerResourceIds=org.eclipse.datatools.connectivity.oda.util.ResourceIdentifiers@6caf66c1, EXTENDED_ITEM_MAX_ROW=0, ServerUserName=anonymous, PARENT_CLASSLOADER=java.net.URLClassLoader@16394576, max_pool_size=10, AppRuntimeLocale=en_US, OdaConsumerId=com.actuate.data.oda.birt.propertyProvider, connection_time_out=3600, OdaConnPropertyContext={}, webapplication.projectclasspath=, org.eclipse.birt.data.query.ResultBufferSize=10, birt.viewer.resource.path=C:\jboss-sw\server\scrumworks\.\deploy\ActuateJavaComponent.war\resources}
</pre>
<br />
I've changed the following parameters in the web.xml:<br />
STANDALONE_REPOSITORY_FILE_AUTHENTICATION = true<br />
STANDALONE_ALLOW_ANONYMOUS = false<br />
<br />
Am I missing something?
zszugyi
I've also tried creating a custom LocalAccessManager to see if its authenticate() method is ever used but had no luck with it.
averma
You will also need to modify web.xml configuration parameters to point to your security adapters:
SECURITY_ADAPTER_CLASS
STANDALONE_ACCESS_MANAGER
Further details on customizing security are in Chapter 8 of the following document:
http://www.birt-exchange.com/be/documentation/Manuals10SP1/creating-custom-deployment-kit-apps.pdf
Ashwini