簡體   English   中英

如何在報表服務中實現用戶模擬?

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

這個問題涉及的軟件是:

  • SQL Server報告服務2008 R2
  • SQL Server Analysis Services 2008 R2
  • SQL Server 2008 R2數據庫引擎
  • ASP.NET 4.5 Web表單
  • ReportViewer組件

我們有幾十個報告。 有些報告對我們的數據倉庫數據庫使用T-SQL查詢,而有些報告對我們的SSAS多維數據集使用MDX查詢。

Active Directory安全組可保護用戶可以在報表服務器上訪問的報表。

此外,我們還使SSAS角色具有維度權限,從而有效地確保了每個用戶可以訪問的數據。 我們使用AMO代碼來生成和維護這些角色和成員身份,原因是存在的角色和成員身份並不重要,並且與問題無關。

我知道SSAS有一個稱為EffectiveUserName的功能,我們可以將其傳遞給多維數據集以進行模擬。

但是,我們如何在SSRS中模擬用戶,以便僅看到該用戶有權訪問的報告?

我們目前正在嘗試使用ASP.NET並使用ReportViewer組件來設計自定義報表管理器的軟件設計。 我們想顯示一個文本框或下拉至管理員,以允許他們放入或選擇員工並有效地以該員工身份運行。

因此,換句話說,即使我以DOMAIN \\ User1身份通過ASP.NET Report Manager站點進行身份驗證,但是如果我以管理員身份在報表服務器上擔當角色,我仍希望能夠在文本框中鍵入用戶名(例如User2),並能夠像DOMAIN \\ User2一樣查看報告服務器上的所有報告。

感謝您提供的任何建議或答案。

一些東西:

  1. 根據我的經驗,您需要使用代碼進行此操作。
  2. 您需要一個“ ReportViewer”對象。
  3. 我相信,如果您托管的話,則需要引用“ Microsoft.ReportViewer.WinForms” dll。

我使用的代碼是通過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>

您得到的重要部分是,我的代碼后面有一個名為“ reportViewer”的“ ReportViewer”對象。 ASP.NET具有與此對象等效的功能,但您也將需要別名為“ rv”或類似名稱的dll。 該代碼的工作與此類似:

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();
        }

我從未使用過您提到的服務,但我希望以下內容能以某種方式為您提供幫助。

我使用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

現在,在代碼中的適當位置使用它,例如:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM