Report Builder and Forms Authenticaton in SQL Server Reporting Services 2005


I’ve had a fair number of questions from my customers around the use of Forms Authentication in conjunction with Report Builder. The basic thing people want to know is “does it work?”.


As a matter of fact, it does. It functions the same way as with Windows Auth except for one behavior: Basically, there is no way to pass the Forms Auth cookie that was generated when a user logged into your application (or Report Manager) along to Report Builder. This is a limitation of ClickOnce applications.


Since we can’t pass the auth cookie to Report Builder, it must deal with the authorization process itself…so the client will pop up a simple logon dialog to your users. Double logon prompts are a bit messy, but I think it’s a fair trade-off in order to be able to use Report Builder with all security mechanisms in SSRS.


 


Comments (45)

  1. barnold says:

    I have successfully gotten formsAuthentication working with SQL Server 2005 with the exception(so far) being that the Reprot Builder log in sends a user account of "" to the Custom Security Extension. Is there a configuration that needs to be changed so that the credentials are passed to the Security Extension?

    Thanks

  2. russch says:

    I’ve never seen anyone run into this problem before…When you enter your credentials into Report Builder, they go right to the security extension, so I don’t see how they could change to a zero-length string. How did you determine that "" was getting sent?

  3. Tim Larson says:

    I’m getting the same problem with Forms auth.  I know that ” is being sent because the "Microsoft Report Server Login" window, which is asking for credentials for Report Builder, has an error in red that says this:

    System.Web.Services.Protocols.SoapException:  The permissions granted to user ” are insufficient for performing this operation.

    —<Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException:  The permissions granted to user ” are insufficient for performing this operation.

    And then there is the big long stack trace (it’s not all visible in the Login Window, but I picked it out using Ethereal).

    I gave anonymous access to the entire ReportBuilder folder in IIS, but I still have to give the forms auth username/password/domain in IE before it lets me run the application.  The application manifest loads and the application starts (I see the ReportBuilder splash screen), but I can’t get past the ReportBuilder logon box.

    Any ideas?  Thanks!

  4. russch says:

    I need to see the stack trace? I’m guessing your ASPWebHosting Permission is being denied, but have to see the stack.

  5. chucho says:

    Hello Russell,

    I’m getting the same problem, i.e. "The permissions granted to user ” are insufficient" with Report Builder.

    Did you find a resolution for Tim Larson & barnold?

    Thanks!ch

  6. russch says:

    Hi…

    No, I asked for the complete stack trace whch I never got. If you could post it I’d be happy to take a look…Paste entire (long) stack trace in…

  7. chucho says:

    Hello Russell,

    I picked the following out using tcptrace:

    <faultcode>soap:Client</faultcode><faultstring>System.Web.Services.Protocols.SoapException: The permissions granted to user ” are insufficient for performing this operation. —&gt; Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException: The permissions granted to user ” are insufficient for performing this operation.

      at Microsoft.ReportingServices.Library.RSService._GetItemType(String item, Byte[]&amp; secDesc)

      at Microsoft.ReportingServices.Library.RSService.GetItemType(String item)

      at Microsoft.ReportingServices.WebServer.ReportingService2005.GetItemType(String Item, ItemTypeEnum&amp; Type)

      — End of inner exception stack trace —

      at Microsoft.ReportingServices.WebServer.ReportingService2005.GetItemType(String Item, ItemTypeEnum&amp; Type)</faultstring><faultactor>http://erlaptop:8080/ReportServer/ReportService2005.asmx</faultactor&gt;

    Any ideas?

    Thanks!

  8. russch says:

    If you go into IIS Manager, what are the directory security settings (auth and access controls) for the ReportServer vdir? What about the /ReportBuilder folder under the ReportServer vdir?

  9. chucho says:

    Both the ReportServer and /ReportBuilder virtual directories have anonymous access enabled, using the IUSER account

  10. rajeeb says:

    I am getting an error "The attempt to connect to the report server failed.  Check your connection information and that the report server is a compatible version." , when I enter valid login and password. I am running June CTP, is this the problem??

  11. russch says:

    Could be — perhaps you added a service pack and/or changed the credentials that you used to connect to the server?

  12. rajeeb says:

    I have uninstalled CTP and installed RTM, now the error is,

    System.Web.Services.Protocols.SoapException: The permissions granted to user ” are insufficient for performing this operation. —> Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException: The permissions granted to user ” are insufficient for performing this operation.

      at Microsoft.ReportingServices.Library.ListChildrenAction.PerformActionNow()

      at Microsoft.ReportingServices.Library.RSSoapAction.Execute()

      at Microsoft.ReportingServices.WebServer.ReportingService2005.ListChildren(String Item, Boolean Recursive, CatalogItem[]& CatalogItems)

      — End of inner exception stack trace —

      at Microsoft.ReportingServices.WebServer.ReportingService2005.ListChildren(String Item, Boolean Recursive, CatalogItem[]& CatalogItems)

    This error ocurred, after I click on File->Open in Report Builder window. First of all, the Report Builder didnt prompt the "Microsoft Report Server Login" window, opened directly.

  13. Tim Larson says:

    The response from the server looked like this (I can’t seem to submit it verbatim – the blog rejects it, so I’ve abbreviated it):

    Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException: The permissions granted to user ” are insufficient for performing this operation.

    — End of inner exception stack trace —

    at Microsoft.ReportingServices.WebServer.ReportingService2005.GetItemType(String Item, ItemTypeEnum&amp; Type)

    Fault actor:http://vmsql03.mtw.int/ReportServer/ReportService2005.asmx

    ErrorCode: rsAccessDenied

    HttpStatus: 400

    Message: The permissions granted to user ” are insufficient for performing this operation.

    HelpLink: http://go.microsoft.com/fwlink/?LinkId=20476&amp;EvtSrc=Microsoft.ReportingServices.Diagnostics.Utilities.ErrorStrings&amp;EvtID=rsAccessDenied&amp;ProdName=Microsoft%20SQL%20Server%20Reporting%20Services&amp;ProdVer=9.00.1399.00

    ProductName: Microsoft SQL Server Reporting Services

    ProductVersion: 9.00.1399.00

    ProductLocaleId: 127

    OperatingSystem: OsIndependent

    CountryLocaleId: 1033

    Source: ReportingServicesLibrary

  14. Tim Larson says:

    I’m making progress on this… I think.

    The error I’m dealing with is that I can’t get Report Builder to authenticate when using Forms authentication.  I can log in just fine at UILogon.aspx and Logon.aspx and see all sorts of fun stuff.

    I have discovered some interesting facts:

    ReportBuilder uses the ReportService2005.asmx web service to talk to the report server.

    The ReportService2005.asmx web service will only give data out if either the LogonUser function is called or if there are NetworkCredentials (basic auth) attached to the web request.  

    Report Builder doesn’t seem to be interested in calling the LogonUser function, so we need to coax it into attaching Basic Auth to its web request.  Report Builder will send the basic auth to the ReportService2005.asmx web service, but only if it gets a ‘401 unauthorized’ error first (my guess is that when it gets a ‘400 – Bad Request’ error, it assumes it is authorized and doesn’t bother to send credentials).

    If I set the ReportService2005.asmx web service to allow anonymous access in IIS, Report Builder will never send the basic auth because it gets 400 errors.  Report Builder looks at the HTTP header to see if it is unauthorized or not – it doesn’t look inside the SOAP packet and see that it is unauthorized.

    If I set the ReportService2005.asmx to disable anonymous access in IIS, and only allow basic auth, the 401 error will get sent back to Report Builder, Report Builder will then send the username and password as basic auth, but IIS will still respond with a 401 error, becuase the username and password are not valid for basic auth.  Kindof.  I think what is happening here is that IIS rejects the basic auth because it’s not a windows user (or something), whereas if ReportService2005.asmx gets it’s hands on the HTTP request, it opens up the basic auth and is happy.

    Is it possible that I have my rssrvpolicy.config file set up wrong?  (I have no idea what I’m doing in that file…)

    Is there a way to get Report Builder to call the LogonUser function in the ReportService2005.asmx web service?

    Is there a way to get Report Builder to send basic auth to ReportService2005.asmx, even if anonymous access is allowed on that web service?

    Or how can I set up IIS so that it will return a 401 error if no basic auth is included, but so that when basic auth is there, it will somehow authorize it at the IIS level based on the Forms auth, even though there is no call to any kind of function that can set the using forms auth rather than basic auth?  (this is where I think the rssrvpolicy.config file might come into play, but I really don’t know)

    Or am I completely missing something obvious here?

    Thanks for reading my continued rambling difficulties.

       Tim Larson

       Mission to the World

  15. Robert Campbell says:

    How are you progressing with this issue. I and it seems may other developers on the web are having similar problems, but I’ve yet to see any definitive solution and work around.

    In my instance it’s further complicated by the customer using Windows Home edn, ( would you credit it!) on some of their laptops.

  16. Tim Larson says:

    I developed a workaround.  Ugly, but it works.

    I created an HTTP Filter and applied it to the ReportServer IIS application.  Anytime an HTTP request is made to the ReportServer application on the ReportService2005.asmx web service, the HTTPFilter does the following:

    If the string <I>"permissions granted to user ” are insufficient"</I> is found in the response, then I change the response so that it has the following:

    – Status: 411 Unauthorized

    – StatusCode: 411

    – StatusDescription: Unauthorized

    – AppendHeader("WWW-Authenticate", "Basic realm="www.myserver.com"")

    This response ends up going back to the ClickOnce ReportBuilder application.  Since Report Builder now gets a 411, it knows to send the username and password as basic authentication.  It sends the basic auth (based on what you typed in the username/pw/domain boxes), and Report Server is happy (so long as your iAuthenticationExtension is happy).

    Gotcha:  There’s one more annoying thing you have to watch out for.  You can type in the username, password and domain.  Report Server can authenticate you based on the username, password and domain.  But Report Server can only do authorization based on the username and password – no the domain.  Yuck.  

    Why should we care?  When you are developing your iAuthorizationExtension for your forms auth, it is impossible to use the domain when trying to determine if a user is authorized to use a particular resource.  Why?  Because after authentication, Report Server stores the username but not the domain.

    There is a workaround for this, but it is ugly.  When I log into Report Builder, I type my username as "XXmyDomaintlarson".  Report Server will then treat "XX" as the Domain and "myDomaintlarson" as the username.  I have to build my iAuthenticationExtension to ignore the Domain and parse the "myDomaintlarson" properly.  After authentication, ReportServer will forget "XX" and remember "myDomaintlarson" as the username.  So when authorization time comes around, Report Server will hand my iAuthorizationExtension a username of "myDomaintlarson".  I can then parse that string to get the correct domain and username and then determine authorization for multiple domains correctly.

    Figuring that out was defintely a challenge.  Let me know if this doesn’t make sense – it’s very possible that I didn’t describe this well.

  17. russch says:

    Great workaround, Tim….One other thing you might want to try is use Soap Trace and/or Pocket Soap to see if a cookie is indeed even being passed TO the SSRS server by Report Builder…

  18. Si Downes says:

    I’m getting an authentication problem only slightly further along.

    Using the HTTPfilter workaround I can authenticate forms users to open, build and save reports to the report server, however, when they attempt to view the report through report builder this results in the error:

    The permissions granted to user <forms username> are insufficient for performing this operation. (rsAccessDenied)

    In logfile:

    Info: Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException:

    The permissions granted to user <forms username> are insufficient for performing this operation.

    Any suggestions?  There’s a thread on google groups to try to resolve this at: http://groups.google.co.uk/group/microsoft.public.sqlserver.reportingsvcs/browse_thread/thread/44ec99075e21f3c3?hl=en

  19. Vince Bossio says:

    Can someone post the code for the HTTP filter workaround?

    I am trying to pass authentication info from my app. to Report Builder and have not written any HTTP filters before.

    Thanks in advance…

  20. Tim Larson says:

    Here is the code for the Filter.  I hope that it comes out formatted properly on the blog…

    To make this filter apply, go to the web.config file for the Report Server and add this under the system.web section.  Make sure the DLL (compiled from the code below) is in the Bin directory for the Report Server application (in my case, it is MTW.PPSSTR.SSRSHTTPFilter.dll).

    ——————————————–

    web.config addition:

    ——————————————–

    <httpModules>

     <add type="MTW.PTSSRS.SSRSHTTPFilter.SSRSServerFilter,MTW.PTSSRS.SSRSHTTPFilter" name="MTW.PTSSRS.SSRSHTTPFilter"/>

    </httpModules>

    ——————————————–

    Filter Code:

    ——————————————–

    #region Copyright © 2006 Mission to the World

    /============================================================================

     File:     SSRSFilter.cs

     Summary:  An HTTPFilter to change the contents of the HTML coming out of

               Report Server.  Specifically, it is used to change this error:

                   HTTP/1.1 500 Internal Server Error …

                   The permissions granted to user ” are insufficient for performing this operation.

               To this error:

                   HTTP/1.1 401 Unauthorized

                   WWW-Authenticate: Basic realm="vmsql03.mtw.int"

                   The permissions granted to user ” are insufficient for performing this operation.

               Why do this?  Because when ReportBuilder sees the first error, it doesn’t

               think to send the authentication as basic authentication, which is

               what the Report Server is expecting.  The 401 error will trigger

               ReportBuilder to send authentication as Basic Auth, which the report

               server will accept

    ——————————————————————–

       

    THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF

    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO

    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A

    PARTICULAR PURPOSE.

    05/06/2006 – SSRSServerFilter Created by Tim Larson, tlarson@mtw.org

    Resources for learning about HTTP Filters:

      http://www.ondotnet.com/lpt/a/4236

      http://www.dotnet2themax.com/ShowContent.aspx?Type=freeware&ID=35efbee1-d8cd-4720-9eb2-83fc9a4033bb

      http://www.users.bigpond.com/conceptdevelopment/Localization/HttpFilter/,

      http://www.devx.com/vb2themax/Article/19901

      http://www.ondotnet.com/pub/a/dotnet/2003/10/20/httpfilter.html

      http://www.users.bigpond.com/conceptdevelopment/Localization/HttpFilter/code.html

      http://authors.aspalliance.com/aspxtreme/sys/Web/HttpResponseClassFilter.aspx

      http://www.aspnetresources.com/articles/CustomErrorPages.aspx

      http://www.aspnetresources.com/articles/HttpFilters.aspx

      http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q307985

    ===========================================================================/

    #endregion

    using System;

    using System.IO;

    using System.Text;

    using System.Web;

    using System.Text.RegularExpressions;

    namespace MTW.PTSSRS.SSRSHTTPFilter

    {

       public class SSRSServerFilter : System.Web.IHttpModule

       {

           public void Init(System.Web.HttpApplication application)

           {

               // Set our function as an event handler for the

               // ReleaseRequestState event in the ASP processing chain

               application.ReleaseRequestState += new System.EventHandler(InstallSSRSServerFilter);

               // We’ll also use it as an event handler for the PreSendRequestHeaders

               // (which is actually dealing with the response, not the request)

               // in case the Page flushes its content prior to everything being ready

               application.PreSendRequestHeaders += new System.EventHandler(InstallSSRSServerFilter);

           }

           public void InstallSSRSServerFilter(Object sender, EventArgs e)

           {

               HttpApplication application = (HttpApplication)sender;

               HttpContext context = application.Context;

               // if the filter has not been installed yet, create a new

               // instance of it, and install it

               const string INSTKEY = "SSRSServerFilterInstalled";

               if (!context.Items.Contains(INSTKEY))

               {

                   HttpResponse currResponse = context.Response;

                   HttpRequest currRequest = context.Request;

                   string s1 = currResponse.ContentType;

    //                bool b1 = currResponse.ContentType.Contains("text/xml");

                   Uri u1 = currRequest.Url;

                   string s2 = currRequest.Url.ToString();

                   bool b2 = currRequest.Url.ToString().Contains("ReportService2005.asmx");

                   // Add our filter to the page, but only if we are encountering

                   // a text/xml content type, and only if we are viewing the

                   // ReportService2005.asmx page

                   if (

                           (currResponse != null) && (currRequest != null) && (currResponse.ContentType != null)

                           &&

                           (currResponse.ContentType.Contains("text/xml"))

                           &&

                           (currRequest.Url.ToString().Contains("ReportService2005.asmx"))

                      )

                   {

                       // Add a filter to the current response

                       SSRSServerStream ms = new SSRSServerStream(currResponse.Filter);

                       ms.SSRSServerStream_Init(currResponse, currRequest.Url.Host);

                       currResponse.Filter = ms;

                       context.Items.Add(INSTKEY, new object());

                   }

               }

           }

           public void Dispose()

           {

           }

       }

       public class SSRSServerStream : System.IO.Stream

       {

           // The stream that goes to the client

           private Stream repStream;

           // Used to write the stream to the client

           private StreamWriter repSR;

           private bool isDone = false;

           private StringBuilder _htmlBuffer = new StringBuilder();

           private string sReportServerHost;

           private string s1NewStatusDescription, s1CheckValue;

           private int i1NewStatusCode;

           private string s1NewHeaderName, s1NewHeaderValue;

           private HttpResponse currResponse;

           public SSRSServerStream(System.IO.Stream stream)

           {

               // Save the stream that is going back to the client

               repStream = stream;

               // Create a StreamWriter

               repSR = new StreamWriter(repStream);

           }

           public void SSRSServerStream_Init(HttpResponse ResponseToChange, string sHost)

           {

               currResponse = ResponseToChange;

               sReportServerHost = sHost;

               CreateReplaceStrings();

           }

           private void CreateReplaceStrings()

           {

               s1NewHeaderName = "WWW-Authenticate";

               s1NewHeaderValue = "Basic realm="" + sReportServerHost + """;

               // Old Status: HTTP/1.1 500 Internal Server Error

               i1NewStatusCode = 401;

               s1NewStatusDescription = "Unauthorized";

               s1CheckValue = "permissions granted to user ” are insufficient";

           }

           // The Write function is where all of the filtering happens

           public override void Write(byte[] buffer, int offset, int count)

           {

               if (isDone)

               {

                   repSR.Write(System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count));

                   repSR.Flush();

               }

               else

               {

                   string buf = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);

                   this._htmlBuffer.Append(buf);

                   // If the </soap:Envelope> closing tag is found, this is the end

                   // of the file, so let’s do the replace work

                   if (Regex.IsMatch(buf, "</soap:Envelope>", RegexOptions.IgnoreCase))

                   {

                       string html = this._htmlBuffer.ToString();

                       StringBuilder result = new StringBuilder();

                       // Replace the text (here is where all the magic happens)

                       if (html.Contains(s1CheckValue))

                       {

                           currResponse.Status = i1NewStatusCode.ToString() + " " + s1NewStatusDescription;

                           currResponse.StatusCode = i1NewStatusCode;

                           currResponse.StatusDescription = s1NewStatusDescription;

                           currResponse.AppendHeader(s1NewHeaderName, s1NewHeaderValue);

                       }

                       // write the resulting string to the response stream

                       repSR.Write(html);

                       isDone = true;

                       repSR.Flush();

                   }

               }

           }

           #region StreamFunctionStubs

           // The following functions are overridden to fulfill the

           // implementation of the stream class.

           public override bool CanRead

           { get { return false; } }

           public override bool CanSeek

           { get { return false; } }

           public override bool CanWrite

           { get { return true; } }

           public override long Length

           { get { throw new NotSupportedException(); } }

           public override long Position

           {

               get { throw new NotSupportedException(); }

               set { throw new NotSupportedException(); }

           }

           public override int Read(Byte[] buffer, int offset, int count)

           { throw new NotSupportedException(); }

           public override long Seek(long offset, System.IO.SeekOrigin direction)

           { throw new NotSupportedException(); }

           public override void SetLength(long length)

           { throw new NotSupportedException(); }

           public override void Close()

           { repStream.Close(); }

           public override void Flush()

           { repStream.Flush(); }

           #endregion

       }

    }

  21. Vince Bossio says:

    Thanks, Tim.

    I got the filter running but then realized it did not address my issue.  I am trying to "pass" authentication to Report Builder so I am not prompted for login a 2nd time (using forms authentication).  Everything I have seen says this can’t be done.  At this point I am looking for a workaround.  If anyone has done this please let me know.

  22. russch says:

    Hi Vince. There is no way to accomplish what you want. The only way to avoid a prompt from a ClickOnce application (therefore, ReportBuilder) is if you are using Windows Credentials. ClickOnce apps don’t know / don’t understand / don’t look for cookies, so there’s not too much (or the Reporting Services team) can do in this scenario. The ClickOnce guys have been asked to consider adding additional functionality to help in this scenario, but who knows what will happen.

  23. chucho says:

    For the record, I got the custom authentication extension up and running after a lot of weeping and gnashing of teeth.

    I started from scratch on a clean development machine. I also read all the material I could find before embarking on my second attempt.

    Knowing WHY I was carrying out steps in the examples rather than just slavishly following them as I was the first time around made a difference as there were several aspects that were particular to the application I’m working on.

    I’ve just discovered that Microsoft are running a Tech-Net event on RS next week near where I’m based – talk about bad timing! Could have done with it a few months ago!

    Eugene

  24. Klaus E. Frederiksen says:

    Hi

    I have been working with Forms Authentication in RS2005 and the Report Builder and have tried to implement the Filter that Tim Larson has descriped.

    I have succesfully got the Report Builder working now and as it turned out I actually got it to work without the filter. I noticed that when Report Builder is calling the LoginUser method the userName and password is empty strings. Because I just implemented my test LoginUser method, always returning true, the Report Builder is believing that the user is OK. Instead if I changed the code to test if the useName is empty, and returns false, if so, the Report Builder now have to prompt the user for a username and passsword, and this solved my problems. Maybe someone else missed that, if they were always returning true from the LoginUser method during test. So every thing is working for me now, also without the filter that Tim Larson has implemented.

  25. JK says:

    Sorry I still dont get it..

    I have forms auth for my website that allows users to view RS reports, and that workds fine.

    When a user clicks the Report Builder button, they get the login box and then the insuffiecient permissions message.  

    I have given this user access to the ReportServer directory, and clicked the "windows auth" button in IIS.  So why dont they authenticate?  I would expect that their windows credentials are used to automatically log them in when report builder starts.  And why does the login dialog say insufficient permissions when they eneter their correct credentials?

    I gave the user access by adding them to the ReportingServicesWebServiceUser group and giving that group read, read + execute and list folder contents permissions to the program filesmicrosoft sql servermssql.1reporting services directory.  Is this the correct permissions, users and folder?

    Confused, JK.

  26. JK says:

    You said:

    "Since we can’t pass the auth cookie to Report Builder, it must deal with the authorization process itself…so the client will pop up a simple logon dialog to your users. Double logon prompts are a bit messy, but I think it’s a fair trade-off in order to be able to use Report Builder with all security mechanisms in SSRS."

    • Why doesnt it automatically try the credentials of the logged in user? I thought thats what intergrated windows authentication meant?  If the logged on user’s credentials dont work, then it should show the login dialog, right?  Or am I still missing something? :)

    JK

  27. russch says:

    JK, not enough info in your problem description. Is SSRS configured to use Forms Auth, too? How? Are you sharing the same user store?

    It sounds like you want to mix authentication modes – Forms Auth sometimes, Windows auth others. You can’t do this.

  28. JK says:

    Hi Russell, thanks for replying.  Because I am confused I am probably not describing the situation too well :)

    My website uses forms auth for authenticating access to the website only. RS is configured for windows auth only.

    When a report is run the ReportViewer.ServerReport.ReportServerCredentials is set to a IReportServerCredentials that returns new NetworkCredentials(configured username, configured pwd). This works fine, and all reports run using the same windows auth credentials saved in web.config.  

    Our website also has a Report Builder button for ad-hoc reports, that launches the Report Builder app.  This pops up the login dialog even though RS has been configured for windows auth, and the logged on user has permissions to use RS.

    So I am using windows auth all the way, and it works for the user who has permission to run the reports, but not for the user who has permission to run the report builder.  I have tried to make the permissions for both users the same.

    I am guessing that I have not correctly set the permissions for the report builder.  In my first post I described the permissions used  – are those permissions correct for allowing someone to run report builder using windows auth? (ie no login dialog)

    Thanks,

    JK

  29. JK says:

    Another way of looking at it…

    I know how to make the /ReportServer webservice use windows auth, just click the windows auth checkbox in IIS on the Directory Security tab for the /ReportServer website.

    But my attempts to allow windows auth for the ReportBuilder click once app have failed.  I have tried changing the ACL of the ReportServer windows folder – with no success.  What access permissions are required, and on what object(s)?  

    Thanks,

    JK.  

  30. russch says:

    This should work out of the box with no problems…Let’s forget about your application altogether.

    From your machine(which I assume has a trust relationship with the server and is part of the server’s domain), type:

    http://<servername>/reportserver/reportbuilder/reportbuilder.application

    Does RB launch? If so, your app is doing something odd with authentication.

  31. JK says:

    Sorry for my delayed response.

    The button in my web app is in fact just a hyperlink to http://<servername>/reportserver/reportbuilder/reportbuilder.application, so I have already tried that :)

    It is a large and complicated network with many domains and users.  

    I tried to give the user access by adding them to the ReportingServicesWebServiceUser group and giving that group read, read + execute and list folder contents permissions to the program filesmicrosoft sql servermssql.1reporting services directory.  Is this the correct permissions, users and folder?

    I will have to check if the user is part of the same domain.  However I did use domainuser when adding them to the ACL.  It also turns out that admin users of the domain can access the RB application – so does this suggest that the ACL is wrong?

    Thanks for continuing to help .. I am pretty stuck.

    JK

  32. russch says:

    Are you able to even launch the ClickOnce App, or are you prevented from getting into the /ReportBuilder folder itself to get at the application?

  33. JK says:

    ReportBuidler.application launches and shows the login dialog. This seems to indicate that the user has permission to view the folder, but not to run the exe, however am I gave them the "Read and Execute" permission (actually I gave the permission to the RS$WebServiceUser and RS$ReportUser groups and added the user to those groups).

  34. JK says:

    They can launch the reportbuilder.application click once app.  It just shows its own login dialog (different from the normal windows login dialog).

    If the user tries to browse to the folder in windows explorer using (server)(path)report serverreportbuilder, they get an error: "Access to the resource (server)(path)etc has been disallowed"

    JK

  35. Pat O'S says:

    That fact that you can’t have a single sign on for Report Builder is a fairly serious flaw. As far as the end user is concerned they have logged in. Forget about the the complications from a developers point of few.

  36. russch says:

    JK, is an error actually thrown at any point when the user supplies credentials?

  37. JK says:

    Hi Russell,

    If you enter the credentials into the Report Builder login dialog it says "The permissions granted to user (domain)(user) are insufficient for performing this operation".

    JK.

  38. DS says:

    Hi,

    Was anyone been able to skip entering credentials on Report Builder launch in Forms mode of authentication of SSRS?

    If not is it possible to customize the authentication failure message that this Report Builder prompt throws on entering invalid credentials?

    Please reply if you have slightest of the clue about the possible solutions to these issues.

    Any advice would be much appreciated. Thanks!

    DS

  39. Deveshd says:

    Is it possible to use the Report Builder in a Software as a Service Model?

    We want the users to be authenticated based on their user id, password and company name, stored in one of the tables in database.

    We don’t want the users to be provided the login credentials of the Report Server.

    Once the user has logged on to our website they can click the Report Builder and it will launch the application and get data only for the company they are logged into

  40. russch says:

    Deveshd: Yes, you can do this using the sample Forms Authentication security extension (however you’ll only provide a user name and password, not a company name).

  41. taersious says:

    Russell,

    I have SP and PWA working on intranet (uses Win Auth) – now I want Reporting Services – turned out to not be as easy as SP and PWA config.  I can only aceess reportserver with anonymous turned on.  Had this working when ReportingServices database ran under Network Service instead of Local Service and was able to see directories under server:port/reportserver/Reports etc. But doing that broke the relationship between SP and RS. Keep getting entries in my logfiles like:

    w3wp!ui!1!4/25/2008-11:40:10:: Unhandled exception: System.Web.HttpException: The file ‘/ReportService2005.asmx’ does not exist.

      at System.Web.UI.Util.CheckVirtualFileExists(VirtualPath virtualPath)

      at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)

      at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)

      at System.Web.Compilation.BuildManager.GetVPathBuildResult(HttpContext context, VirtualPath virtualPath)

      at System.Web.UI.WebServiceParser.GetCompiledType(String inputFile, HttpContext context)

      at System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath)

      at System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig)

      at System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

      at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

    w3wp!ui!6!4/25/2008-11:40:11:: e ERROR: The attempt to connect to the report server failed.  Check your connection information and that the report server is a compatible version.

    w3wp!ui!6!4/25/2008-11:40:11:: e ERROR: HTTP status code –> 500