简体   繁体   English

如何在报表服务中实现用户模拟?

[英]How to implement user impersonation in reporting services?

Software involved in this question is: 这个问题涉及的软件是:

  • SQL Server Reporting Services 2008 R2 SQL Server报告服务2008 R2
  • SQL Server Analysis Services 2008 R2 SQL Server Analysis Services 2008 R2
  • SQL Server 2008 R2 Database Engine SQL Server 2008 R2数据库引擎
  • ASP.NET 4.5 Web Forms ASP.NET 4.5 Web表单
  • ReportViewer component ReportViewer组件

We have several dozen reports. 我们有几十个报告。 Some reports use T-SQL queries to our Data Warehouse database and some use MDX queries to our SSAS Cube. 有些报告对我们的数据仓库数据库使用T-SQL查询,而有些报告对我们的SSAS多维数据集使用MDX查询。

Active Directory Security Groups secure which reports a user can access on the Report Server. Active Directory安全组可保护用户可以在报表服务器上访问的报表。

We additionally have made SSAS Roles that have Dimension Permissions on them which effective secures which data each user can access. 此外,我们还使SSAS角色具有维度权限,从而有效地确保了每个用户可以访问的数据。 We used AMO code to generate and maintain these roles and membership due to how many there are but that is beside the point and unrelated to the question. 我们使用AMO代码来生成和维护这些角色和成员身份,原因是存在的角色和成员身份并不重要,并且与问题无关。

I understand that there is a feature of SSAS called EffectiveUserName that we can pass to the cube for impersonation. 我知道SSAS有一个称为EffectiveUserName的功能,我们可以将其传递给多维数据集以进行模拟。

However, how can we impersonate a user within SSRS such that we will see only the reports that that user has access to? 但是,我们如何在SSRS中模拟用户,以便仅看到该用户有权访问的报告?

We are currently trying to work out the software design of a custom report manager with ASP.NET and using the ReportViewer component. 我们目前正在尝试使用ASP.NET并使用ReportViewer组件来设计自定义报表管理器的软件设计。 We would like to expose a text box or drop down to Administrators that allows them to put in or select employees and effectively run as that employee. 我们想显示一个文本框或下拉至管理员,以允许他们放入或选择员工并有效地以该员工身份运行。

So in other words, even though I am authenticated into the ASP.NET Report Manager site as DOMAIN\\User1, if I am in some role on the report server as an Administrator, I want to be able to type into a text box a username like User2 and be able to view all reports on the report server as DOMAIN\\User2 would see them. 因此,换句话说,即使我以DOMAIN \\ User1身份通过ASP.NET Report Manager站点进行身份验证,但是如果我以管理员身份在报表服务器上担当角色,我仍希望能够在文本框中键入用户名(例如User2),并能够像DOMAIN \\ User2一样查看报告服务器上的所有报告。

Thanks for any advice or answers you can offer. 感谢您提供的任何建议或答案。

A few things: 一些东西:

  1. You need to do this in code behind in my experience. 根据我的经验,您需要使用代码进行此操作。
  2. You want a 'ReportViewer' object. 您需要一个“ ReportViewer”对象。
  3. I believe if you are hosting you need a reference to 'Microsoft.ReportViewer.WinForms' dll. 我相信,如果您托管的话,则需要引用“ Microsoft.ReportViewer.WinForms” dll。

The code I used was done with xaml for WPF hosting a ReportViewer (abridged): 我使用的代码是通过Xaml完成的,用于WPF托管ReportViewer(节略):

< Window x:Class="WPFTester.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms"
    >
  ......
<WindowsFormsHost Grid.Row="2">
        <rv:ReportViewer x:Name="reportViewer"></rv:ReportViewer>
    </WindowsFormsHost>
......
</Window>

The important part you get is that I have a 'ReportViewer' Object named 'reportViewer' for my code behind. 您得到的重要部分是,我的代码后面有一个名为“ reportViewer”的“ ReportViewer”对象。 ASP.NET has some equivalent of this object but you also will also need the dll in the alias of 'rv' or similar. ASP.NET具有与此对象等效的功能,但您也将需要别名为“ rv”或类似名称的dll。 The code works similar to this: 该代码的工作与此类似:

private void ResetReportViewer(ProcessingMode mode)
        {
            this.reportViewer.Clear();
            this.reportViewer.LocalReport.DataSources.Clear();
            this.reportViewer.ProcessingMode = mode;
        }


        private void ReportViewerRemoteWithCred_Load(object sender, EventArgs e)
        {
            ResetReportViewer(ProcessingMode.Remote);
            reportViewer.ServerReport.ReportServerUrl = new Uri(@"(http://myservername/ReportServer");
            reportViewer.ServerReport.ReportPath = "/Test/ComboTest";

            DataSourceCredentials dsCrendtials = new DataSourceCredentials();
            dsCrendtials.Name = "DataSource1";  // default is this you may have different name
            dsCrendtials.UserId = "MyUser";  // Set this to be a textbox
            dsCrendtials.Password = "MyPassword";  // Set this to be a textbox
            reportViewer.ServerReport.SetDataSourceCredentials(new DataSourceCredentials[] { dsCrendtials });

            reportViewer.RefreshReport();
        }

I never worked with services you have mentioned but I hope, following stuff will help you in some way. 我从未使用过您提到的服务,但我希望以下内容能以某种方式为您提供帮助。

I used kernal32.dll and advapi32.dll to impersonate user as under: 我使用kernal32.dll和advapi32.dll来模拟用户,如下所示:

Imports System.Security.Principal
Imports System.Runtime.InteropServices

Public Class UserImpersonation
<DllImport("advapi32.dll")> _
Public Shared Function LogonUserA(ByVal lpszUserName As [String], ByVal lpszDomain As [String], ByVal lpszPassword As [String], ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, ByRef phToken As IntPtr) As Integer
End Function

<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function DuplicateToken(ByVal hToken As IntPtr, ByVal impersonationLevel As Integer, ByRef hNewToken As IntPtr) As Integer
End Function

<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function RevertToSelf() As Boolean
End Function

<DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function

Public Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Public Const LOGON32_PROVIDER_DEFAULT As Integer = 0

Private impersonationContext As WindowsImpersonationContext

Private Const UserName As String = "USER_ID"
Private Const Password As String = "USER_DOMAIN_PASSWORD"
Private Const Domain As String = "USER_DOMAIN_NAME"

Public Function ImpersonateValidUser() As Boolean
    Dim tempWindowsIdentity As WindowsIdentity
    Dim token As IntPtr = IntPtr.Zero
    Dim tokenDuplicate As IntPtr = IntPtr.Zero
    If RevertToSelf() Then
        If LogonUserA(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
            If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
                tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
                impersonationContext = tempWindowsIdentity.Impersonate()
                If impersonationContext IsNot Nothing Then
                    CloseHandle(token)
                    CloseHandle(tokenDuplicate)
                    Return True
                End If
            End If
        End If
    End If
    If token <> IntPtr.Zero Then
        CloseHandle(token)
    End If
    If tokenDuplicate <> IntPtr.Zero Then
        CloseHandle(tokenDuplicate)
    End If
    Return False
End Function

Public Sub UndoImpersonation()
    If impersonationContext IsNot Nothing Then
        impersonationContext.Undo()
    End If
End Sub

End Class

Now, consume it at appropriate place in your code like: 现在,在代码中的适当位置使用它,例如:

Public SomeOtherClass
Public Function ReadFile() As CalFileInfo
    Try
        Dim objImpersonation As New UserImpersonation()
        If (objImpersonation.ImpersonateValidUser()) Then
            'Do necessary stuff....
            objImpersonation.UndoImpersonation()
        Else
            objImpersonation.UndoImpersonation()
            Throw New Exception("User do not has enough permissions to perform the task")
        End If
    Catch ex As Exception
        ''MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    End Try

    Return CalFileInformation
End Function
End Class

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 SignInManager 为 Blazor WebAssembly 实现模拟? - How to implement impersonation using SignInManager for Blazor WebAssembly? 如何检查Windows用户是否可以通过模拟访问(Windows集成安全性身份验证)SQL Server Analysis Services(SSAS)服务器 - How to check if a windows user has access (Windows Integrated Security authentication) to SQL Server Analysis Services (SSAS) Server via impersonation 如何在 .net core 中使用微软报告服务 - How to use microsoft reporting services with .net core MS Reporting服务-如何传递单元格颜色 - MS Reporting services - How to pass cell color UWP用户模拟 - UWP User Impersonation 为用户模拟存储密码 - Storing a password for user impersonation PHP中的Windows用户模拟? - Windows user impersonation in PHP? 如何实现可移植HttpClient的进度报告 - How to implement progress reporting for Portable HttpClient 如何防止用户登录仅用于模拟的帐户? - How to prevent user from logon of an account used for impersonation only? 如何检查[UserName]和[Password]的用户是否是[DomainName]的域管理员而没有模拟? - How to check if user with [UserName] and [Password] is domain administrator of [DomainName] without impersonation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM