Implementing Custom SSRS Authentication
Let`s start working on the implementation.
Step 1: Creating the UserAccounts Database
Create the tables exactly how it`s shown in the Database Model Section explained earlier
Step 2: Building the Sample
Microsoft provides a sample project that implements custom authentication. It can be downloaded from https://github.com/microsoft/Reporting-Services/tree/master/CustomSecuritySample2016
If you have not already created a strong name key file, generate the key file using the following instructions in this link https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-sign-an-assembly-with-a-strong-name
Before compiling the sample, let`s make a small change on it.
- Open the Logon.aspx file
- Remove the Register button from the file
In our example users will be registered based on the AD FS claims
To compile the sample using Visual Studio
- Open CustomSecuritySample.sln in Microsoft Visual Studio.
- In Solution Explorer, select the CustomSecuritySample project.
- Look at the CustomSecuritySample project’s references. If you do not see Microsoft.ReportingServices.Interfaces.dll, then complete the following steps:
- On the Project menu, click Add Reference. The Add References dialog box opens.
- Click the .NET tab.
- Click Browse, and find Microsoft.ReportingServices.Interfaces on your local drive. By default, the assembly is in the <install>\ReportServer\bin directory. Click OK. The selected reference is added to your project.
- On the Build menu, click Build Solution.
Debugging
To debug the extension, you might want to attach the debugger to both ReportingServicesService.exe and Microsoft.ReportingServices.Portal.Webhost.exe. And add breakpoints to the methods implementing the interface IAuthenticationExtension2.
Step 3: Deployment and Configuration
The basic configurations needed for custom security extension are the same as previous releases. Following changes are needed in for web.config and rsreportserver.config present in the ReportServer folder. There is no longer a separate web.config for the reportmanager, the portal will inherit the same settings as the reportserver endpoint.
To deploy the sample
- Copy the Logon.aspx page to the <install>\ReportServer directory.
- Copy Microsoft.Samples.ReportingServices.CustomSecurity.dll and Microsoft.Samples.ReportingServices.CustomSecurity.pdb to the <install>\ReportServer\bin directory.
- Copy Microsoft.Samples.ReportingServices.CustomSecurity.dll and Microsoft.Samples.ReportingServices.CustomSecurity.pdb to the <install>\RSWebApp\bin directory.
If a PDB file is not present, it was not created by the Build step provided above. Ensure that the Project Properties for Debug/Build is set to generate PDB files.
Modify files in the ReportServer Folder
To modify the RSReportServer.config file.
- Open the RSReportServer.config file with Visual Studio or a simple text editor such as Notepad. RSReportServer.config is located in the <install>\ReportServer directory.
- Locate the <AuthenticationTypes> element and modify the settings as follows:
<Authentication>
<AuthenticationTypes>
<Custom/>
</AuthenticationTypes>
<RSWindowsExtendedProtectionLevel>Off</RSWindowsExtendedProtectionLevel>
<RSWindowsExtendedProtectionScenario>Proxy</RSWindowsExtendedProtectionScenario>
<EnableAuthPersistence>true</EnableAuthPersistence>
</Authentication>
- Locate the <Security> and <Authentication> elements, within the <Extensions> element, and modify the settings as follows:
<Security>
<Extension Name=”Forms” Type=”Microsoft.Samples.ReportingServices.CustomSecurity.Authorization, Microsoft.Samples.ReportingServices.CustomSecurity” >
<Configuration>
<AdminConfiguration>
<UserName>username</UserName>
</AdminConfiguration>
</Configuration>
</Extension>
</Security>
<Authentication>
<Extension Name=”Forms” Type=”Microsoft.Samples.ReportingServices.CustomSecurity.AuthenticationExtension,Microsoft.Samples.ReportingServices.CustomSecurity” />
</Authentication>
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 file.
- Open the RSSrvPolicy.config file located in the <install>\ReportServer directory.
- 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. Make sure to change the below path according to your ReportServer installation directory:
<CodeGroup
class=”UnionCodeGroup”
version=”1″
Name=”SecurityExtensionCodeGroup”
Description=”Code group for the sample security extension”
PermissionSetName=”FullTrust”>
<IMembershipCondition
class=”UrlMembershipCondition”
version=”1″
Url=”C:\Program Files\Microsoft SQL Server\MSRS13.MSSQLSERVER\Reporting Services\ReportServer\bin\Microsoft.Samples.ReportingServices.CustomSecurity.dll”/>
</CodeGroup>
To modify the Web.config file for Report Server
- Open the Web.config file in a text editor. By default, the file is in the <install>\ReportServer directory.
- Locate the <identity> element and set the Impersonate attribute to false.
<identity impersonate=”false” />
- Locate the <authentication> element and change the Mode attribute to Forms. Also, add the following <forms> element as a child of the <authentication> element and set the loginUrl, name, timeout, and path attributes as follows:
<authentication mode=”Forms”>
<forms loginUrl=”logon.aspx” name=”sqlAuthCookie” timeout=”60″ path=”/” domain=”.yourDomain” enableCrossAppRedirects=”true” ></forms>
</authentication>
- Add the following <authorization> element directly after the <authentication> element.
<authorization>
<deny users=”?” />
</authorization>
This will deny unauthenticated users the right to access the report server. The previously established loginUrl attribute of the <authentication> element will redirect unauthenticated requests to the Logon.aspx page.
Step 4: Some of the other changes required in the web.config file and Microsoft.ReportingServices.Portal.WebHost.exe.config
Adding Machine Keys
- In <RSPATH>\ReportServer\web.config, add under <system.web>
<machineKey validationKey=”[YOUR KEY]” decryptionKey=”[YOUR KEY]” validation=”SHA1″ decryption=”AES” compatibilityMode=”Framework45″/>
- Then <RSPATH>\RSWebApp\Microsoft.ReportingServices.Portal.WebHost.exe.config, add under <configuration>
<system.web> <machineKey validationKey=”[YOUR KEY]” decryptionKey=”[YOUR KEY]” validation=”AES” decryption=”SHA1″ compatibilityMode=”Framework45″ /></system.web>
Our example is a little bit different from Microsoft`s example, we are setting he decryption to SHA1 and compatibility mode to Framework 4.5 in order to share cookies between our Ladining Page ( MVC APP ) and SSRS
Step 5: Configure Passthrough cookies
The new portal and the reportserver communicate using internal soap APIs for some of its operations. When additional cookies are required to be passed from the portal to the server the PassThroughCookies properties is still available. More Details: https://msdn.microsoft.com/en-us/library/ms345241.aspx In the rsreportserver.config file add following under <UI>
<UI> <CustomAuthenticationUI> <PassThroughCookies> <PassThroughCookie>sqlAuthCookie</PassThroughCookie> </PassThroughCookies> </CustomAuthenticationUI></UI>
Integrating MVC with SSRS
Once the focus of this post is to show how to authenticate with SSRS I will not go through of how to communicate with AD FS.
Supposing that your AD FS integration is done and working let`s see below how to implement the User Registration Process
Step 1: Creating the Authentication Class
- Add the SSRS Service web reference. The Web Service url is <Your_SSRS_ReportServerURL>/ReportService2010.asmx
- Add a new class to your MVC project named AuthenticationHelper
- This class needs to implement the Singleton pattern to avoid losing policies when setting policies using the SSRS WS. See below the Singleton implementation
The class must have the following methods:
- private List<OrgGroupRole> GetOrgGroups(int orgId)
- This method will query for the Organization Roles
- Query: SELECT * FROM OrgGroupRole WHERE OrganizationId = @orgId
- private void CreateUser(string userName, int orgId)
- This method will create a new User
- Query: INSERT INTO Users VALUES(@userName, @organizationId)
- public Organization GetOrgId(string orgName)
- This method will find the OrgId based on the Organization name
- Query: SELECT * FROM Organization WHERE UPPER(OrganizationName) = UPPER(@orgName)
- private bool IsUserRegistered(string username, int orgId)
- This method will check if the user already exists
- Query: SELECT 1 FROM Users WHERE UserName = @userName and OrganizationId = @orgId
- private List<string> GetSSRSRoleNames(List<int> ids)
- This method will get the SSRS roles that are mapped to the Organization roles
- Query: $”SELECT DISTINCT SSRSRoleName FROM OrgGroupRoleSSRS Where OrgGroupRoleId in ({string.Join(“, “, ids)})”
For simplicity the methods above are described only with the signature and the query you need to execute to return the data.
The methods below contain the full implementation:
SetPolicies Method
This method will call the SSRS Web Service to set policies for the user that is being registered based on the path used as parameter.
AddUserRoles Method
This method will call the SetPolicies Method passing the SSRS Root Folder and Report Builder Role as parameters (You can use the Role that works better for you in the Root Folder) and will call again the SetPolicies Method using the Organization Folder Path
ExecuteUserBasedAuthenticationFlow Method
This method will execute the Authentication flow using the ADFS claims as input parameters.
Step 2: Creating a filter to register users
Once the authentication happens in AD FS and the MVC executes the actions the user authentication flow will be executed.
To do it create an Action Filter and override the OnActionExecuting method as below:
The filter will get the necessary claims, run the authentication flow and if the flow succeed the Forms Authentication Cookies will be created allowing you to access SSRS Reports.
The SSRS cookie name, domain and claims are set in the web.config file, check below:
The domain and cookie names need to match with the ones used in the SSRS setup.
The claims need to match the claim names returned by the AD FS, change it if you need.