1

I am trying to write a Java application that will show reports from SSRS 2012. I set up my web services proxy and I have this code to try to log in to the server:

try
{
    ReportExecutionServiceSoapStub service = getService();
    System.out.println("ADP1N: Test.main, Checkpoint Bravo...");
    service.logonUser("CAMPUSAD/<username>", "<password>", "");
} catch (Exception e)
{
    e.printStackTrace();
}

But I keep getting this error:

Apr 29, 2013 3:29:32 PM org.apache.commons.httpclient.HttpMethodDirector authenticate
SEVERE: Credentials cannot be used for NTLM authentication:         org.apache.commons.httpclient.UsernamePasswordCredentials
org.apache.commons.httpclient.auth.InvalidCredentialsException: Credentials cannot be used for NTLM authentication: org.apache.commons.httpclient.UsernamePasswordCredentials
at org.apache.commons.httpclient.auth.NTLMScheme.authenticate(NTLMScheme.java:331)
at org.apache.commons.httpclient.HttpMethodDirector.authenticateHost(HttpMethodDirector.java:281)
at org.apache.commons.httpclient.HttpMethodDirector.authenticate(HttpMethodDirector.java:233)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:169)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
at org.apache.axis.transport.http.CommonsHTTPSender.invoke(CommonsHTTPSender.java:196)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.microsoft.schemas.sqlserver._2005._06._30.reporting.reportingservices.ReportExecutionServiceSoapStub.logonUser(ReportExecutionServiceSoapStub.java:1893)
at Test.main(Test.java:29)
Apr 29, 2013 3:29:32 PM org.apache.commons.httpclient.HttpMethodDirector processWWWAuthChallenge
INFO: Failure authenticating with NTLM <any realm>@ais-fgnk3k1:80
AxisFault
 faultCode: {http://xml.apache.org/axis/}HTTP
 faultSubcode: 
 faultString: (401)Unauthorized
 faultActor: 
 faultNode: 
 faultDetail: 
    {}:return code:  401

    {http://xml.apache.org/axis/}HttpErrorCode:401

(401)Unauthorized
    at org.apache.axis.transport.http.CommonsHTTPSender.invoke(CommonsHTTPSender.java:218)
    at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
    at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
    at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
    at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
    at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
    at org.apache.axis.client.Call.invoke(Call.java:2767)
    at org.apache.axis.client.Call.invoke(Call.java:2443)
    at org.apache.axis.client.Call.invoke(Call.java:2366)
    at org.apache.axis.client.Call.invoke(Call.java:1812)
    at com.microsoft.schemas.sqlserver._2005._06._30.reporting.reportingservices.ReportExecutionServiceSoapStub.logonUser(ReportExecutionServiceSoapStub.java:1893)
    at Test.main(Test.java:29)

I even tried this code and got the same results:

ExecutionInfo info = service.loadReport("http://usys-dbd1.dev.ais.msu.edu/ReportServer/Pages/ReportViewer.aspx?%2fUSYS%2fAdvisor+Scheduling%2fAdvisor_Scheduling_Report&amp;rs:Command=Render", null);

My rsreportserver.config file has these authentication entries:

<Authentication>
    <AuthenticationTypes>
         <RSWindowsNegotiate />
         <RSWindowsKerberos />
         <RSWindowsNTLM />
    </AuthenticationTypes>
    <RSWindowsExtendedProtectionLevel>Off</RSWindowsExtendedProtectionLevel>
    <RSWindowsExtendedProtectionScenario>Proxy</RSWindowsExtendedProtectionScenario>
    <EnableAuthPersistence>true</EnableAuthPersistence>
</Authentication>

I am not sure what I am doing wrong here.

Jeroen
  • 60,696
  • 40
  • 206
  • 339
Michael Robinson
  • 1,106
  • 3
  • 13
  • 40

2 Answers2

1

Without seeing what the method 'GetService()' and that there are a few things that you need to do to authenticate to the service. I would first see if you can test a bit of code locally with a user you know has admin privledges to the site in question. I have written code to talk to SSRS but only in C# .NET but I am uncertain about Java. Now there are a few ways I know of to get data from SSRS traditionally:

  1. Just view the URL from the webservice directly: http:// (servername)/ReportServer/Pages/ReportViewer.aspx(Path)&rs:Command=Render

  2. Populate an HTML form object from the web service. I Similar to above but:

    <form id="ssrsform" action="(link above or similar)" method="post" target="_self" >
     .....(options and settings)....
    </form>
    
  3. Create a .NET project that has a 'report' control and you can contact the SSRS server directly instead of having a local report under options.

  4. Do the creation of the server RDL objects completely in code from a proxy class: I had another thread here: Programmatically Export SSRS report from sharepoint using ReportService2010.asmx on how to do it with C# and .NET, some of it may apply to Java but I am not certain. The key part would be to test this top portion:

    ReportExecutionService rs = new ReportExecutionService();
    rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
    rs.Url = "http://myserver/reportserver/ReportExecution2005.asmx";
    

You need to have a proxy class, or web service if you want to go that route, generally to call the SSRS server. You need to get authenticated. You need to ensure you are contacting the right point or it will just hang up on you.

EDIT 5-3-13:

On most hosted reports solution in native mode that I know of on versions 2008, 2008 R2, 2012(never used SSRS on 2005), you should see something similar to below on section 'C' from a dropdown shown in the below pic. If you say your credentials are in the report you should be able to alter them EVEN once they are hosted. SSRS's web service contacts it's database that holds all your settings and you can change them freely after deployment. That is one of the things I actually really like about SSRS, if it is a small change you can change the hosted object, and not have to redeploy the object. The issue appears that you are being prompted and in every case I have ever seen that is the default behavior when the option 'Credentials supplied by the user running the report' is set and NOT credentials stored.

However you may not be able to see these settings if another setting is not set. If you are just a browser, you DO NOT have rights to change things. If you are not seeing settings, that is a majority of the problem as you are not able to set them. When you first set up SSRS one of the very first steps is to have the default admin go into the local install's web location and set up users that need admin access. Generally you go into site settings, add an 'System Administrator', then SSRS in it's glory has another security setting for actual traversin of objects on the 'Folder Settings'. You need to set those security settings as well. You need to ensure for your proxy account you have 'Content Manager' rights (or potentially lesser if you are strict, Content Manager is the highest). Honestly SSRS's security is very confusing in my opinion and a great source of complaints for many and justifiably so IMHO.

Generally speaking rights inherit down a tree structure and if you publish a report under 'reports' named 'report1.rdl' It is generally Home/Reports/report1.rdl and you have rights to view the home folder, the reports folder, and the report object. However... someone that is an admin can override any part of this chain and break it. At the company I work for it is a spaghetti mess that I inherited where everything was set one object at a time because they did not set up AD groups correctly and do everything in an Organizational unit structure one directory at a time. If you know TSQL well you can query permission directly form the database structure by Sql management Studio and the default is 'ReportServer' for the DB and the table that most object are in I believe is CATALOG.

Here is a pic for better explanation, my environment shown I believe is SSRS 2008R2 but 2008 and 2012 are very similar. enter image description here

Community
  • 1
  • 1
djangojazz
  • 14,131
  • 10
  • 56
  • 94
  • 1
    I do have links in my jsp pages that refer to the report as you have in bullet #1. The problem is that it then asks for a login. I'm trying to find a way to automatically log in as eventually the report portal will be secured by our local security and I don't think the clients will like to log in twice. – Michael Robinson Apr 30 '13 at 13:52
  • 1
    That is handled by SSRS Server more than likely then. When you go to the link directly you need to handle the data source as self contained by setting the data source to reference a set user and password. Are you doing that? Or is it set to 'Use Windows Authentication'? You can choose 'Use this name and password' when building the reports and they will reference credentials contained in the connection string itself. – djangojazz May 01 '13 at 16:31
  • 1
    I'm not trying to authenticate the data sources, that's already handled in the report itself. What I want to do is bypass the login window that comes up when I click the link. This link is within an application that users will have already logged into and I think they'd be annoyed if they had to login yet again to view a report. – Michael Robinson May 02 '13 at 13:33
  • 1
    If I go to http:// (servername)/(reportpath) it does not require authentication unless the datasource is not set up to use an embedded authentication when using IE. Otherwise the report just comes up. Are you trying to use a browser other than IE? My suggestion since this is all authentication related is try to potentially hit the root node potentially first. If you cannot get to http:// (servername)/ReportServer with authentication it may relate to a user not having permissions set up on the site. Is your user in code tested to go to the site manually under AD permissions? – djangojazz May 02 '13 at 16:02
  • 1
    The datasource passwords are stored in the report itself. The web app is on a different server and no matter what browser we use, we get the request for a username and password. What we want to do is create a username/password that the web app will pass to the report server and bypass the whole log in panel. This is the problem I'm trying to tackle. – Michael Robinson May 02 '13 at 20:08
  • 1
    I am sorry I cannot help you then, if your datasource has the value stored directly I have never ran into a case where it still prompts you for a password. Generally in SSRS you go: Report>Properties>Data Sources> You have two options: 'A shared data source', 'a custom data source'. Either way you set 'Credentials supplied by the user running the report' or 'Credentials stored securely in the report server'. I always set the credentials to be stored so that the user can just run the report. Everytime this is set I have never ran into a registered user being prompted. – djangojazz May 02 '13 at 20:27
  • 1
    I don't see that option. My report menu has "Report Properties", which leads me to a panel where I can change the page layout and such. Don't see anything for data sources. I could be looking in the wrong place though. I'll look into this. – Michael Robinson May 03 '13 at 12:55
  • 1
    Actually it is a subset of 'manage' not 'properties' technically. Are you accessing the reports from Http:// (reportserver)/Reports and then finding the report > Clicking the dropdown and then 'Manage' > There should be categories on the left pane if you have 'Content Manager' rights or higher. What version of SQL Server is this SSRS install for and are these hosted reports? See my pic on edit to see further info. – djangojazz May 03 '13 at 15:57
  • 1
    It took me a while, but I found what you were referring to. all my reports' datasources are secured in the report server (that is, I set up the user name/password when I created the report in the Visual Studio interface). – Michael Robinson May 03 '13 at 19:31
  • 1
    You should not be prompted when you got to a report then. The default behavior of SSRS is to allow a user that has 'browser' access to a report viewing ability right away with out a prompt unless that option is chosen. You have a deeper issue if you cannot even in a browser get a qualified user to see a report at its path without being prompted. – djangojazz May 03 '13 at 19:50
  • 1
    Ok, I think then the problem is that when the user clicks a link in a web page to the report server, the server doesn't know who's accessing this report, hence the log in prompt. My goal is to somehow log into the report server, passing a predefined username/password, without the log in prompt showing up. – Michael Robinson May 06 '13 at 14:23
1

If you are invoking the report from Windows 7, you may have to use NTLM V2 Authentication as explained below. We have implemented the same logic(removed only logs) and able to resolve the issue.

http://devsac.blogspot.com/2010/10/supoprt-for-ntlmv2-with-apache.html.

san242
  • 127
  • 1
  • 1
  • 4