65.9K
CodeProject 正在变化。 阅读更多。
Home

SSRS 2012 表单身份验证

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (10投票s)

2013年10月31日

CPOL

7分钟阅读

viewsIcon

129242

downloadIcon

8050

SQL Server Reporting Services 表单身份验证实现。

介绍 

初次接触 SQL Server Reporting Services,我遇到了很多关于实现单点登录(SSO)和表单身份验证(Forms authentication)的难题,也不太理解其工作模型。我写这篇帖子是想分享我的学习心得,希望能对新手有所帮助。我将详细介绍实现过程。 

我使用 SSRS 2012 和 VS 2012 实现 SSRS 表单身份验证。 

首先,让我解释一下我的场景。我需要为 WPF 应用程序实现报表单点登录。报表将部署在报表服务器上,WPF 应用程序需要直接访问报表,而无需再次登录。

我为某个产品开发了此功能,因此我需要一个原型来演示上述场景和单点登录实现。  

背景 

让我们开始吧。下面的链接将清晰地展示 SSRS 报表服务与表单身份验证的结合。

http://msdn.microsoft.com/en-us/library/aa902691.aspx 

表单身份验证设置  

开始动手吧 微笑 | :)

SSRS 默认支持 Windows 身份验证模式。如果您需要与其他域进行交互,则需要配置表单身份验证。微软提供了一个表单身份验证的示例。

该示例可在此处下载:http://msftrsprodsamples.codeplex.com/wikipage?title=SS2008R2!Security%20Extension%20Sample 

上面的链接提供了将示例部署到 SSRS 的详细信息。请确保您根据上面的网站进行代码修改。 

注意: 请确保您使用完整版的 Visual Studio 构建示例。我最初使用 VS 2012 Dev Express 构建安全扩展示例,但部署行为不符合预期。然而,在专业版中 it worked。我真的不知道为什么。 

另外,请确保不要更改您从上述位置下载的自定义安全扩展的目标框架版本。由于某些原因,当我将目标框架修改为 4.0 时,报表服务器无法加载 dll。 

我将重复上面网站上提到的相同步骤,但会指出您可能出错的地方,因为我也犯过同样的错误 :P。 

在开始构建示例之前,请确保您已完成代码中的所有必要更改。 

希望您已下载并带有密钥构建了示例。 我们将深入探讨配置,这是实现的关键部分。 

重要 

在进行任何更改之前,请备份所有配置更改的副本。 

下面的示例将“C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services”视为“<InstallLocation>”。这是默认实例 MSSQLSERVER 的默认位置。 

报表服务器文件修改  

修改 RSReportServer.config 文件:  

RsReportServer.config 文件位于<InstallLocation>\ReportServer。找到<AuthenticationTypes> 元素,并将设置修改为如下: 

<Authentication>
<AuthenticationTypes>
<Custom/>
</AuthenticationTypes>
<EnableAuthPersistence>true</EnableAuthPersistence>
<RSWindowsExtendedProtectionLevel>Off</RSWindowsExtendedProtectionLevel>
<RSWindowsExtendedProtectionScenario>Proxy</RSWindowsExtendedProtectionScenario>
</Authentication> 

<Extensions> 元素中,找到<Security> 和<Authentication> 元素,并将设置修改为如下: 

<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> 

找到<UI> 元素并更新如下:

<UI>
<CustomAuthenticationUI>
<loginUrl>/Pages/UILogon.aspx</loginUrl>
<UseSSL>True</UseSSL>
</CustomAuthenticationUI>
<ReportServerUrl>http://servername/ReportServer</ReportServerUrl>
</UI>

注意:如果您在没有安装安全套接字层 (SSL) 证书的开发环境中运行示例安全扩展,则必须在上述配置中将<UseSSL> 元素的值更改为 False。 

修改 RSSrvPolicy.config 文件: 

您需要为自定义安全扩展添加一个代码组,该代码组授予您的扩展FullTrust 权限。 

您可以通过将代码组添加到RSSrvPolicy.config 文件来执行此操作。 

打开位于<InstallLocation>\ReportServer 目录中的RSSrvPolicy.config 文件。 

在安全策略文件中,找到 URL 成员身份为$CodeGen 的现有代码组,在其后添加以下<CodeGroup> 元素,然后向RSSrvPolicy.config 中添加一个条目,如下所示: 

<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\MSRS11.MSSQLSERVER\Reporting Services\ReportServer\bin\Microsoft.Samples.ReportingServices.CustomSecurity.dll"
/>
</CodeGroup> 

修改后的代码如下:  

<CodeGroup
class="UnionCodeGroup"
version="1" 
PermissionSetName="FullTrust">
<IMembershipCondition
class="UrlMembershipCondition" 
version="1" 
Url="$CodeGen$/*"/>
</CodeGroup> 
<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\MSRS11.MSSQLSERVER\Reporting Services\ReportServer\bin\Microsoft.Samples.ReportingServices.CustomSecurity.dll"/></CodeGroup> 

修改报表服务器的 Web.config 文件

在文本编辑器中打开Web.config 文件。默认情况下,该文件位于<InstallLocation>\ReportServer 目录。 

找到<identity> 元素,并将 Impersonate 属性设置为 false。  <identity impersonate="false" /> 

找到<authentication> 元素,并将 Mode 属性更改为 Forms。 

将以下<forms> 元素作为<authentication> 元素的子项添加,并按如下方式设置loginUrl、name、timeout 和 path 属性: 

<authentication mode="Forms">
   <forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="60"
   path="/"></forms>
  </authentication>
  <identity impersonate="false" />  

将以下<authorization> 元素直接添加到<authentication> 元素之后:

<authorization>
<deny users="?"/>
</authorization> 

这将拒绝未经验证的用户访问报表服务器的权限。 loginUrl 属性(在<authentication>元素中)会将未经身份验证的请求重定向到 Logon.aspx 页面。 

报表管理器文件修改:  

修改 RSMgrPolicy.config 文件

打开报表管理器策略文件RSMgrPolicy.config,该文件位于<InstallLocation>\ReportManager 目录。 

RSMgrPolicy.config 中找到以下代码组,并将PermissionSetName 属性从 Execution 更改为FullTrust,如下所示:

<CodeGroup
class="FirstMatchCodeGroup"
version="1"
PermissionSetName="FullTrust"
Description="This code group grants MyComputer code Execution permission. ">
<IMembershipCondition
class="ZoneMembershipCondition"
version="1"
Zone="MyComputer" /> 

要使用表单身份验证,您需要修改报表管理器和报表服务器的 Web.config 文件。 

修改报表管理器的 Web.config 文件 

打开报表管理器的 Web.config 文件。它位于<InstallLocation>\ReportManager 目录。通过找到<identity impersonate= "true" /> 部分并将其更改为<identity impersonate="false" /> 来禁用模拟。找到 <authentication> 元素并将 Mode 属性更改为 Forms。 <authentication mode="Forms" /> 

将以下键添加到<appSettings> 元素。 
<add key="ReportServer" value="<Server Name>"/>
<add key="ReportServerInstance" value="<Instance Name>"/> 

<Server Name> 值更改为报表服务器的名称,将<Instance Name> 值更改为报表服务器所属实例的名称。 

示例 

<add key="ReportServer" value="hpprobook4440s"/>
<add key="ReportServerInstance" value="RS_MSSQLSERVER"/>

注意:默认实例的<Instance Name> 是RS_MSSQLSERVER。为了让示例识别报表服务器实例,必须以RS_ <ReportServerName> 作为前缀。 

示例:如果您安装了另一个报表服务器实例,例如“SQLEXPRESS”,那么您的ReportServerInstance 将需要设置为“RS_SQLEXPRESS”。  

完成配置更改后,需要重启报表服务器服务。 

转到开始=>services.msc 

找到服务“SQL Server Reporting Services (MSSQLSERVER)”,右键单击该服务并重新启动。上面提到的服务是在安装 SSRS 时创建的默认服务。

创建用户帐户数据库

您可以在下载的解决方案的 setup 文件夹下找到以下 SQL 脚本。 

在 SQL Server Management Studio 中执行“CreateUserStore.sql”文件。 

验证用户帐户数据库已创建。 

您必须确保报表服务能够访问新创建的数据库,请按照以下步骤提供访问权限。 

为报表服务器服务提供用户帐户权限

 转到 Databases-> UserAccounts->Security->Users 

右键单击 Users,选择“New User”

概述

  1. 在 UserType 下拉列表中选择“Windows User”。 
  2. 为 Username 输入“NT SERVICE\ReportServer”。 
  3. 为 Password 输入“NT SERVICE\ReportServer”。 
  4. 为 Default Schema 输入“NT SERVICE\ReportServer”。 

在 Membership 中

勾选 db_owner 

已授予 NT Service\ReportServer 对 UserAccounts 数据库的访问权限。 

调试示例

调试示例

  1. 确保将 .pdb 文件与 dll 一起复制。 
  2. VisualStudioRibbon-> Debug-> Attach to Process-> ReportingServicesService.exe 附加到进程。(确保您附加的是正确的实例)
  3. 打开 Reporting services configuration 并导航到报表管理器 URL,在 GetUserInfo() 中设置断点。 
  4. 您应该能够进行调试 微笑 | :) 祝贺 微笑 | :)

移除示例扩展

虽然通常不推荐,但在尝试完示例后,您可以恢复到 Windows 身份验证。 

恢复到 Windows 安全性

从备份副本中恢复以下文件:Web.config 和 RSReportServer.config。这将把报表服务器的身份验证和授权方法设置为默认的 Windows 安全性。这应该也会移除您在报表服务器配置文件中为扩展添加的任何条目。 

在移除配置信息后,您的安全扩展将不再可用于报表服务器。您不应该需要移除在示例安全扩展下运行报表服务器时创建的任何安全描述符。当启用 Windows 身份验证时,报表服务器会自动将系统管理员角色分配给托管报表服务器的计算机上的 BUILTIN\Administrators 组。但是,您需要为您的 Windows 用户手动重新应用任何基于角色的安全。 

请注意,在迁移到不同的安全扩展后恢复到 Windows 身份验证通常不被推荐。如果您这样做,当您尝试访问报表服务器数据库中具有自定义安全描述符但没有 Windows 身份验证安全描述符的项目时,可能会遇到错误。 

单点登录源代码

我已将带有代码更改的自定义安全扩展示例和配置文件附上作为参考。 

注意:切勿直接替换配置文件,因为这可能会影响其他现有配置。仅使用文本编辑器手动修改更改。 

示例 WPF 应用程序代码

设置完成后,通过传递验证凭据来获取 authToken(Cookie),表单身份验证的单点登录即可工作。因此,我们需要引用报表服务并调用LogonUser()。一旦验证成功,该方法将返回authcookie,需要捕获此 cookie 并将其与下一个请求头一起传递。以下代码清楚地展示了实现过程。 

[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)
{
// Step1: Add reference to report service either by directly referencing the reportinservice.asmx service of by converting wsdl to class file.

 ReportServerProxy2010 rsProxy = new ReportServerProxy2010();
//Step2: Assign the report server service eg:"http://<servername>/ReportServer/ReportService2010.asmx";
 
              rsProxy.Url = string.Format(ReportServerUrl, ReportServer);
try
              {
                rsProxy.LogonUser(username,password, null);
                Cookie authCookie = rsProxy.AuthCookie;
if (authCookie != null)
                {
//Internet Set Cookie is a com method which sets the obtained auth token to internet explorer

                  InternetSetCookie(Url, null, authCookie.ToString());
                }
              }
catch (Exception ex)
              {
              }
            }
//When navigating now, the auth token is accepted and report manager page is displayed directly without asking for login credentials.
WebBrowserControl.Navigate(new Uri("");} 

谢谢,

编码愉快:) 

© . All rights reserved.