Support for Microsoft SQL Server 2016 Reporting Services does not work yet, see: https://github.com/RegionOrebroLan-Lab/.NET-ReportingServices-Extensions/issues/1/
However, you should be able to install Microsoft SQL Server 2017 Reporting Services and configure it with your SQL-Server-2016-Reporting-Services-databases.
Also - when this solution is considered stable this repository will move to https://github.com/RegionOrebroLan/.
This is a guide to set up Reporting Services with ADFS-authentication. This guide applies to:
This guide is written using the following environment:
Important! The trailing slash in https://reports.local.net/ReportServer/ is important when configuring AD FS and in Web.config.
To check your version you can check the version of the following assembly:
To check the version of a *.dll:
In the environment for this guide:
Generally:
Stop the windows service:
Howto generate a machine-key with IIS: Easiest way to generate MachineKey
Path: [INSTALLATION-PATH]\ReportServer\web.config
Add the following:
<configuration>
...
<system.web>
...
<machineKey decryption="AES" decryptionKey="[YOUR-DECRYPTION-KEY]" validation="AES" validationKey="[YOUR-VALIDATION-KEY]" />
...
</system.web>
...
</configuration>
Path: [INSTALLATION-PATH]\RSWebApp\Microsoft.ReportingServices.Portal.WebHost.exe.config
Add the following:
<configuration>
...
<system.web>
<machineKey decryption="AES" decryptionKey="[YOUR-DECRYPTION-KEY]" validation="AES" validationKey="[YOUR-VALIDATION-KEY]" />
</system.web>
...
</configuration>
Path: [INSTALLATION-PATH]\ReportServer\rsreportserver.config
Add the following child to /Configuration:
<Configuration>
...
<MachineKey Decryption="AES" DecryptionKey="[YOUR-DECRYPTION-KEY]" Validation="AES" ValidationKey="[YOUR-VALIDATION-KEY]" />
...
</Configuration>
The casing of the attributes is important!
Path: [INSTALLATION-PATH]\ReportServer\rsreportserver.config
Change from
<Configuration>
...
<Authentication>
<AuthenticationTypes>
<RSWindowsNTLM />
</AuthenticationTypes>
...
</Authentication>
...
</Configuration>
to
<Configuration>
...
<Authentication>
<AuthenticationTypes>
<Custom />
</AuthenticationTypes>
...
</Authentication>
...
</Configuration>
Change from
<Configuration>
...
<Extensions>
...
<Authentication>
<Extension Name="Windows" Type="Microsoft.ReportingServices.Authentication.WindowsAuthentication, Microsoft.ReportingServices.Authorization" />
</Authentication>
...
</Extensions>
...
</Configuration>
to
<Configuration>
...
<Extensions>
...
<Authentication>
<Extension Name="Windows" Type="RegionOrebroLan.ReportingServices.Authentication.WindowsAuthentication, RegionOrebroLan.ReportingServices" />
</Authentication>
...
</Extensions>
...
</Configuration>
Add the following as the first child to /Configuration/UI:
<Configuration>
...
<UI>
<CustomAuthenticationUI>
<PassThroughCookies>
<PassThroughCookie>.ASPXAUTH</PassThroughCookie>
<PassThroughCookie>FedAuth</PassThroughCookie>
<PassThroughCookie>FedAuth1</PassThroughCookie>
</PassThroughCookies>
</CustomAuthenticationUI>
...
</UI>
...
</Configuration>
<Configuration>
...
<UI>
<CustomAuthenticationUI>
<PassThroughCookies>
<PassThroughCookie>.ASPXAUTH</PassThroughCookie>
<PassThroughCookie>FedAuth</PassThroughCookie>
<PassThroughCookie>FedAuth1</PassThroughCookie>
</PassThroughCookies>
<UseSSL>False</UseSSL>
</CustomAuthenticationUI>
...
</UI>
...
</Configuration>
Path: [INSTALLATION-PATH]\ReportServer\rssrvpolicy.config
Allow full trust for the assemblies in Files.zip by adding the following elements under the IMembershipCondition-element of the nested code-group with class "FirstMatchCodeGroup":
<CodeGroup
Name="Log4Net-StrongName"
class="UnionCodeGroup"
Description="This code group grants Log4Net code full trust."
PermissionSetName="FullTrust"
version="1"
>
<IMembershipCondition class="StrongNameMembershipCondition" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100297dcac908e28689360399027b0ea4cd852fbb74e1ed95e695a5ba55cbd1d075ec20cdb5fa6fc593d3d571527b20558d6f39e1f4d5cfe0798428c589c311965244b209c38a02aaa8c9da3b72405b6fedeeb4292c3457e9769b74e645c19cb06c2be75fb2d12281a585fbeabf7bd195d6961ba113286fc3e286d7bbd69024ceda" version="1" />
</CodeGroup>
<CodeGroup
Name="RegionOrebroLan-StrongName"
class="UnionCodeGroup"
Description="This code group grants RegionOrebroLan code full trust."
PermissionSetName="FullTrust"
version="1"
>
<IMembershipCondition class="StrongNameMembershipCondition" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100d5b5f1623c455dd2ce7a24fcb9ad5db0f32a8793bf2925b82d4b4d43ea1058f5cfd6b8136b8cb850715e921a0256ea4188cfc3b257021125f2cf36b3a584eb6caa674831da70eba16f154ae4ca0dc4cd29dc02d8422e5a72416aeb6bcda9b2e9c06f19df1edb5f5403677345c8f06f2612d571628ef43d2bf6d877c91c94e4d3" version="1" />
</CodeGroup>
<CodeGroup
Name="StructureMap-StrongName"
class="UnionCodeGroup"
Description="This code group grants StructureMap code full trust."
PermissionSetName="FullTrust"
version="1"
>
<IMembershipCondition class="StrongNameMembershipCondition" PublicKeyBlob="00240000048000009400000006020000002400005253413100040000010001008d9a2a76e43cd9b1b1944b1f3b489a046b33f0bcd755b25cc5d3ed7b18ded38240d6db7578cd986c72d3feb4f94a7ab26fcfa41e3e4f41cf2c029fba91159db05c44d63f0b2bfac24353a07f4a1230dd3d4240340adafa2275277fa083c75958062cd0e60016701db6af7ae718efdf1e802a840595b49c290964255b3c60c494" version="1" />
</CodeGroup>
That is the IMembershipCondition-element, with zone "MyComputer", under the nested CodeGroup-element with description "This code group grants MyComputer code Execution permission.". Like this:
<configuration>
<mscorlib>
<security>
<policy>
<PolicyLevel version="1">
<CodeGroup class="FirstMatchCodeGroup" PermissionSetName="Nothing" version="1">
...
<CodeGroup class="FirstMatchCodeGroup" Description="This code group grants MyComputer code Execution permission. " PermissionSetName="Execution" version="1">
<IMembershipCondition class="ZoneMembershipCondition" version="1" Zone="MyComputer" />
<CodeGroup
Name="Log4Net-StrongName"
class="UnionCodeGroup"
Description="This code group grants Log4Net code full trust."
PermissionSetName="FullTrust"
version="1"
>
<IMembershipCondition class="StrongNameMembershipCondition" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100297dcac908e28689360399027b0ea4cd852fbb74e1ed95e695a5ba55cbd1d075ec20cdb5fa6fc593d3d571527b20558d6f39e1f4d5cfe0798428c589c311965244b209c38a02aaa8c9da3b72405b6fedeeb4292c3457e9769b74e645c19cb06c2be75fb2d12281a585fbeabf7bd195d6961ba113286fc3e286d7bbd69024ceda" version="1" />
</CodeGroup>
<CodeGroup
Name="RegionOrebroLan-StrongName"
class="UnionCodeGroup"
Description="This code group grants RegionOrebroLan code full trust."
PermissionSetName="FullTrust"
version="1"
>
<IMembershipCondition class="StrongNameMembershipCondition" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100d5b5f1623c455dd2ce7a24fcb9ad5db0f32a8793bf2925b82d4b4d43ea1058f5cfd6b8136b8cb850715e921a0256ea4188cfc3b257021125f2cf36b3a584eb6caa674831da70eba16f154ae4ca0dc4cd29dc02d8422e5a72416aeb6bcda9b2e9c06f19df1edb5f5403677345c8f06f2612d571628ef43d2bf6d877c91c94e4d3" version="1" />
</CodeGroup>
<CodeGroup
Name="StructureMap-StrongName"
class="UnionCodeGroup"
Description="This code group grants StructureMap code full trust."
PermissionSetName="FullTrust"
version="1"
>
<IMembershipCondition class="StrongNameMembershipCondition" PublicKeyBlob="00240000048000009400000006020000002400005253413100040000010001008d9a2a76e43cd9b1b1944b1f3b489a046b33f0bcd755b25cc5d3ed7b18ded38240d6db7578cd986c72d3feb4f94a7ab26fcfa41e3e4f41cf2c029fba91159db05c44d63f0b2bfac24353a07f4a1230dd3d4240340adafa2275277fa083c75958062cd0e60016701db6af7ae718efdf1e802a840595b49c290964255b3c60c494" version="1" />
</CodeGroup>
...
</CodeGroup>
...
</CodeGroup>
</PolicyLevel>
</policy>
</security>
</mscorlib>
</configuration>
The PublicKeyBlob-value depends on what strong-name-key-file you used to sign your assembly. To get the public-key from a strong-name-key-file:
Create a directory somewhere on your filesystem
Copy your *.snk file to the created directory
Create a "GetPublicKey.cmd" file in the same directory
Search your filesystem for "sn.exe" and copy the path of one of your hits (eg. "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\sn.exe")
Open the "GetPublicKey.cmd" file (right click and choose Edit)
Add the following to it:
@ECHO OFF
SET sn="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\sn.exe"
%sn% -p SomeName.snk SomeName.PublicKey
%sn% -tp SomeName.PublicKey
PAUSE
Save "GetPublicKey.cmd"
Run the "GetPublicKey.cmd" file (double click it)
Copy the displayed key and paste it, then remove any line breaks
To get the public-key from an assembly:
@ECHO OFF
SET sn="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\sn.exe"
%sn% -Tp "C:\Folder\Assembly.dll"
PAUSE
Download the file Files.zip and extract it. It has the following content:
If you download the files to the Reporting Services server directly they might be blocked and the assemblies will not be granted access. To resolve it you can right-click each downloaded file and choose properties. If it says: This file came from another computer and might be blocked to help protect this computer., unblock it.
Copy the following files to [INSTALLATION-PATH]\ReportServer:
Copy the following files to [INSTALLATION-PATH]\ReportServer\bin:
Copy the following files to [INSTALLATION-PATH]\ReportServer\bin:
Copy the following files to [INSTALLATION-PATH]\RSWebApp:
Copy the following files to [INSTALLATION-PATH]\RSWebApp\bin:
Copy the following files to [INSTALLATION-PATH]\ReportServer\bin:
Copy the following files to [INSTALLATION-PATH]\Portal:
Copy the following files to [INSTALLATION-PATH]\ReportServer\bin:
Copy the following files to [INSTALLATION-PATH]\Portal:
Copy the following files to [INSTALLATION-PATH]\PowerBI:
Copy [INSTALLATION-PATH]\ReportServer\bin\Microsoft.ReportingServices.Authorization.dll to [INSTALLATION-PATH]\PowerBI.
Path: [INSTALLATION-PATH]\ReportServer\web.config
To get the thumbprint value (/configuration/system.identityModel/identityConfiguration/issuerNameRegistry/trustedIssuers/add @thumbprint) run the following PowerShell-command on the ADFS-server:
Write-Host (Get-AdfsCertificate -CertificateType "Token-Signing").Thumbprint.ToLower();
Add the following parts to Web.config (change XX to 13, 14 or 15, depending on version):
<configuration>
...
<configSections>
<section name="structureMap" type="RegionOrebroLan.ReportingServices.StructureMap.Configuration.Section, RegionOrebroLan.ReportingServices, Version=XX.0.0.0, Culture=neutral, PublicKeyToken=520b099ae7bbdead" />
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
...
<runtime>
...
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
...
<dependentAssembly>
<assemblyIdentity name="StructureMap" culture="neutral" publicKeyToken="e60ad81abae3c223" />
<bindingRedirect newVersion="3.1.9.463" oldVersion="0.0.0.0-3.1.9.463" />
</dependentAssembly>
...
</assemblyBinding>
...
</runtime>
...
<structureMap>
<registries>
<add type="RegionOrebroLan.ReportingServices.StructureMap.Registry, RegionOrebroLan.ReportingServices, Version=XX.0.0.0, Culture=neutral, PublicKeyToken=520b099ae7bbdead" />
</registries>
</structureMap>
...
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="https://reports.local.net/ReportServer/" />
</audienceUris>
<certificateValidation certificateValidationMode="PeerOrChainTrust" />
<claimsAuthenticationManager type="RegionOrebroLan.ReportingServices.Security.Claims.WindowsFederationClaimsAuthenticationManager, RegionOrebroLan.ReportingServices, Version=XX.0.0.0, Culture=neutral, PublicKeyToken=520b099ae7bbdead" />
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add name="https://adfs.local.net/adfs/services/trust/" thumbprint="[THUMBPRINT-VALUE]" />
</trustedIssuers>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
...
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="true" />
<wsFederation issuer="https://adfs.local.net/adfs/ls/" passiveRedirectEnabled="true" realm="https://reports.local.net/ReportServer/" requireHttps="true" />
</federationConfiguration>
</system.identityModel.services>
...
<system.web>
...
<authorization>
<deny users="?" />
</authorization>
...
<httpModules>
<clear />
<add name="BootstrapperModule" type="RegionOrebroLan.ReportingServices.Web.BootstrapperModule, RegionOrebroLan.ReportingServices, Version=XX.0.0.0, Culture=neutral, PublicKeyToken=520b099ae7bbdead" />
<add name="CustomErrorHandlerModule" type="RegionOrebroLan.ReportingServices.Web.ErrorHandlerModule, RegionOrebroLan.ReportingServices, Version=XX.0.0.0, Culture=neutral, PublicKeyToken=520b099ae7bbdead" />
<add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!-- Must be declared after the SessionAuthenticationModule. -->
<add name="FederationAuthenticationModule" type="RegionOrebroLan.ReportingServices.Web.FederationAuthenticationModule, RegionOrebroLan.ReportingServices, Version=XX.0.0.0, Culture=neutral, PublicKeyToken=520b099ae7bbdead" />
</httpModules>
...
<identity impersonate="false" /><!-- Or remove the identity-element. -->
...
</system.web>
...
</configuration>
Start the windows service: