Being new to Sql Server Reporting Services, I was facing lot of problems to implement Single sign on with Forms authentication and understand its working model. I am writing this post to convey my learning so that it would be useful for some one who starts new. I would like to include detailed implementation in this post.
I have implemented SSRS forms authentication using SSRS 2012 and VS 2012.
Let me first start explaining my scenario, I was needed to implement Single Sign on to reports from a WPF application, The reports would be deployed in a report server and the WPF application needs to access reports directly instead of asking for login.
I developed this for a product so I required a prototype for the above scenario and show the Single sign on Implementation.
Lets get started, The below link gives you a clear picture of SSRS Reporting services with Forms authentication.
Forms Authentication Setup
Lets Start Action
SSRS by default, supports Windows authentication mode. If you want to have interaction with other domain you need to configure forms authentication. There is a forms authentication sample provided by Microsoft.
The sample can be downloaded here http://msftrsprodsamples.codeplex.com/wikipage?title=SS2008R2!Security%20Extension%20Sample
The above link provide details regarding the deployment of sample to SSRS. Make sure that you manipulate the code changes in the above site.
Note: Check that you build the sample with complete version of Visual Studio, I initially build the security extension sample with VS 2012 Dev Express and the deployment was not behaving as expected. However, when performed in professional edition it worked. I really don't know why.
Also, be sure you don't change the targetframework version of custom security extension which you download from the above. For some reasons the dlls were not picked up by the reporting server when I modified the target framework to 4.0.
I would be repeating the same steps as mentioned in the above website, However would be pointing out the areas where you would go wrong, since I went wrong :P.
Make sure you performed all the changes that need to be done in code before you begin building the sample.
Hoping you downloaded, build the sample with key. We will dive into configurations, which is the vital part of Implementation.
Make back up copies of all your configuration changes before you proceed with changes.
<InstallLocation> is considered as "C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services" below. This is the default location for default instance MSSQLSERVER.
REPORT SERVER FILES MODIFICATION:
To modify the RSReportServer.config file:
RsReportServer.config file can be found
<InstallLocation>\ReportServer. Locate the
<AuthenticationTypes> element and modify the settings as follows:
<Authentication> elements, within the
<Extensions> element, and modify the settings as follows:
<Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.Authorization, Microsoft.Samples.ReportingServices.CustomSecurity">
<Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.AuthenticationExtension, Microsoft.Samples.ReportingServices.CustomSecurity"/>
<UI> element and update it as follows
Note: If you are running the sample security extension in a development environment that does not have a Secure Sockets Layer (SSL) certificate installed, you must change the value of the
<UseSSL> element to False in the above configuration.
To modify the RSSrvPolicy.config file:
You will need to add a code group for your custom security extension that grants
FullTrust permission for your extension.
You do this by adding the code group to the RSSrvPolicy.config
Open the RSSrvPolicy.config file located in the
Add the following
<CodeGroup> element after the existing code group in the security policy file that has a URL membership of
$CodeGen as indicated below and then add an entry as follows to RSSrvPolicy.config:
Description="Code group for the sample security extension"
Url="C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services\ReportServer\bin\Microsoft.Samples.ReportingServices.CustomSecurity.dll"
The Modified code looks like below:
version="1"<span style="font-size: 9pt;">
To modify the Web.config file for Report Server
Open the Web.config file in a text editor. By default, the file is located in the
element and set the Impersonate attribute to false.
<identity impersonate="false" />
<authentication> element and change the Mode attribute to Forms.
Add the following
<forms> element as a child of the
<authentication> element and set the
loginUrl, name, timeout, and path attributes as follows:
<forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="60"
<identity impersonate="false" />
Add the following
<authorization> element directly after the
This will deny unauthenticated users the right to access the report server. The defined
loginUrl attribute of the
<authentication> element will redirect unauthenticated requests to the Logon.aspx page.
REPORT MANAGER FILES MODIFICATION:
To modify the RSMgrPolicy.config file
Open the Report Manager policy file, RSMgrPolicy.config, located in the <InstallLocation>\ReportManager directory.
Locate the following code group in RSMgrPolicy.config and change the
PermissionSetName attribute from Execution to
FullTrust as follows:
Description="This code group grants MyComputer code Execution permission. ">
To use Forms Authentication, you need to modify the Web.config files for Report Manager and Report Server.
To modify the Web.config file for Report Manager
Open the Web.config for Report Manager. It is located in the
<InstallLocation>\ReportManager directory. Disable impersonation by locating the section
<identity impersonate= "true" /> and changing it to the following:
<identity impersonate="false" />. Locate the <authentication> element and change the Mode attribute to Forms.
<authentication mode="Forms" />
Add the following keys to the
<add key="ReportServer" value="<Server Name>"/>
<add key="ReportServerInstance" value="<Instance Name>"/>
<Server Name> value to the name of the report server and the
<Instance Name> value to the name of the instance the report server is associated with.
<add key="ReportServer" value="hpprobook4440s"/>
<add key="ReportServerInstance" value="RS_MSSQLSERVER"/>
<Instance Name> for a default instance is
RS_MSSQLSERVER. It is mandatory to prefix
RS_ <ReportServerName> for the sample to recognize report server instance.
Example: If you are have installed another instance of Reporting server say "
SQLEXPRESS", then you would require to mention your
ReportServerInstance as "
Once the configuration changes are done, restarting the report server service is required.
Go to start=>services.msc
Identify the service "SQL Server Reporting Services (MSSQLSERVER)" right click on the service and restart. The mentioned service is the default service created when installed SSRS.
CREATING USER ACCOUNTS DATABASE:
You could find the below SQL script in downloaded solution under set up folder.
Execute "CreateUserStore.sql" file in SQL Server Management Studio.
Verify User Accounts Database is created.
You must make sure that report service has access to newly created database, follow the steps below to provide access.
Providing Permissions to User Accounts for Report Server Service:
Go to Databases-> UserAccounts->Security->Users
Right Click Users select "New User"
- Select "Windows User" under UserType dropdown.
- Enter "NT SERVICE\ReportServer" for Username.
- Enter "NT SERVICE\ReportServer" for Password.
- Enter "NT SERVICE\ReportServer" for Default Schema.
Access to NT Service\ReportServer to UserAccounts Database is given.
DEBUGGING THE SAMPLE:
For debugging the sample
- Make sure you copy .pdb files along with the dll's.
- VisualStudioRibbon-> Debug-> Attach to Process-> ReportingServicesService.exe attach to process.(make sure you attach correct instance)
- Open Reporting services configuration and navigate to report manager url keeping break point in GetUserInfo().
- You should be able to debug cheers
REMOVING THE SAMPLE EXTENSTION:
While not generally recommended, it is possible to revert back to Windows Authentication after you have tried out the sample.
To revert to Windows security
Restore the following files from your backup copies: Web.config and RSReportServer.config. This should set the authentication and authorization methods for the report server to the default Windows security. This should also remove any entries you made for your extension in the Report Server configuration file.
After the configuration information is removed, your security extension is no longer available to the report server. You should not have to remove any security descriptors that were created while you were running the report server under the sample security extension. The report server automatically assigns the System Administrator role to the BUILTIN\Administrators group on the computer hosting the report server when Windows Authentication is enabled. However, you will have to manually re-apply any role-based security for your Windows users.
Note that reverting back to Windows Authentication after migrating to a different security extension is generally not recommended. If you do, you may experience errors when you attempt to access items in the report server database that have custom security descriptors, but no Windows Authentication security descriptors.
SINGLE SIGN ON SOURCE CODE:
I have attached the custom security extension sample with the code changes and the configuration files for reference.
Note: Never replace the the configuration files directly, since it might affect other existing configurations. Only modify the changes manually by using a text editor.
Sample WPF Application Code:
Once the set up is done, Single Sign on for Forms authentication works obtaining authToken(Cookie) by passing the validation credentials. So we need to reference the reporting service and call
LogonUser(). Once the validation is successful the method returns
authcookie which needs to be captured and passed along with the next request header. The below code gives a clear picture of implementation.
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool InternetSetCookie(string lpszUrlName, string lpszCookieName, string lpszCookieData);
private void GetAuthToken(string username, string password)
ReportServerProxy2010 rsProxy = new ReportServerProxy2010();
rsProxy.Url = string.Format(ReportServerUrl, ReportServer);
Cookie authCookie = rsProxy.AuthCookie;
if (authCookie != null)
InternetSetCookie(Url, null, authCookie.ToString());
catch (Exception ex)
Enjoy Coding :)