3

これを行う方法があるはずです。SQL 2008 (r2 ではない) レポート サーバーでレポートを表示しているユーザーの IP アドレス (またはコンピューター名 - ただし、IP の方が取得しやすいと思います) を公開する方法が必要です。これが私がすでに試したことです:

  1. レポート コード ブロックにコードを記述して、次のような IP アドレスを取得します。

    Public Function GetClientIP() As String
        Dim sReturn As String = ""
        Dim ipHost As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName())
    
        For i As int32 = 0 To ipHost.AddressList.Length - 1
            If (Not ipHost.AddressList(i) Is Nothing AndAlso ipHost.AddressList(i).ToString().Trim() <> "" AndAlso ipHost.AddressList(i).ToString().Length() <= 15) Then
                sReturn = ipHost.AddressList(i).ToString()
            End If
        Next i
    
        Return sReturn
    End Function
    

    最初、これによりあらゆる種類のセキュリティ許可エラーが発生しましたが、rssrvpolicy.config で Report_Expressions_Default_Permissions の PermissionSet を FullTrust に変更することで回避できました。

    <CodeGroup
      class="UnionCodeGroup"
      version="1"
      PermissionSetName="FullTrust"
      Name="Report_Expressions_Default_Permissions"
      Description="This code group grants default permissions for code in report expressions and Code element. ">
      <IMembershipCondition
      class="StrongNameMembershipCondition"
      version="1"
      PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100512C8E872E28569E733BCB123794DAB55111A0570B3B3D4DE3794153DEA5EFB7C3FEA9F2D8236CFF320C4FD0EAD5F677880BF6C181F296C751C5F6E65B04D3834C02F792FEE0FE452915D44AFE74A0C27E0D8E4B8D04EC52A8E281E01FF47E7D694E6C7275A09AFCBFD8CC82705A06B20FD6EF61EBBA6873E29C8C0F2CAEDDA2"
      />
    </CodeGroup>
    

    結局、クライアントではなくサーバーの IP アドレスを返していることがわかりました。それはこれこれが言うことではありません。

  2. 次のようなさまざまなASP.net変数を試しましHttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]

    1. 展開されたときにのみ機能し、デバッガーから実行するとエラーがスローされます (これは予想されることだと思います)。
    2. また、サーバーの IP アドレスのみを返します。

    実際、すべてのサーバー変数を取得してレポート画面に表示する簡単なスクリプトを作成しましたが、クライアントの IP アドレスは含まれていません。

    Public Function GetServerVariables() AS String
        Dim sReturn as String = ""
    
        for i as int32 = 0 to System.Web.HttpContext.Current.Request.ServerVariables.Count -1
            sReturn &=System.Web.HttpContext.Current.Request.ServerVariables.Keys(i).ToString & ": " & System.Web.HttpContext.Current.Request.ServerVariables.Item(i).ToString() & " - "
        next i
    
        Return sReturn
    End Function
    
  3. 上記の GetClientIP() 関数と基本的にまったく同じコードを実行する vb.NET でカスタム アセンブリを作成しようとしましたが、数日間試行した後、そのアセンブリでアクセス許可エラーを解決できませんでした。ほぼ同時に、ステップ (1) のレポート コードが機能し、それがサーバーの IP アドレスを返していたので、カスタム アセンブリが同じものを返すと想定したため、最終的にこれをあきらめました。

では、ここまでです。説明が長くなって申し訳ありませんが、できるだけ詳しく説明したいと思います。また、ユーザーの IP アドレスが必要な理由を知りたい方のために説明すると、これは実際には別の複雑な話であり、誰かが本当に知りたい場合は、別の投稿で説明します。

要するに、ブラウザでレポートを実行しているコンピュータの IP アドレスまたはコンピュータ名が必要です。ユーザー名やその他の詳細は、何らかの方法で IP アドレスを検索するために使用できない限り、十分ではありません。

4

4 に答える 4

1

アセンブリにstrongnameとfulltrustの許可を与える必要があります。

.netサービスを呼び出す前に、必要な権限を表明し、呼び出し後すぐにそれを元に戻す必要があります。

rssrvpolicy.configファイルでアセンブリ権限を付与します。
管理ツールでは、.net構成ツールを使用してコードグループと権限を管理します。カスタムアセンブリの新しいコードグループと権限を追加することをお勧めします。

アップデートを使用するには、レポートサービスを停止して再開する必要があります。

カスタムアセンブリを使用するレポートサービスの場合、カスタムアセンブリが完全に信頼されている必要があります。すべてのアクセス許可を設定すると、アセンブリが部分的に信頼された呼び出し元を許可しないというエラーメッセージが表示されます。

これを修正するには、assemblyinfo.vbファイルを編集して、次のコード行を追加します。

アセンブリ:AllowPartiallyTrustedCallers()

上記のコードを<...>でカプセル化します。エディターが行全体を削除し続けたため、これらを削除しました。

アクセス許可を修正したら、.net構成ツールを使用して、カスタムアセンブリをアセンブリキャッシュに追加できます。アセンブリに変更を加えるたびに、使用することを決定したディレクトリに.dllファイルをコピーする必要があることに注意してください。アセンブリをキャッシュから削除して、再度追加します。それ以外の場合は、常に古いバージョンのアセンブリを呼び出します。
レポートプロジェクトに参加しているときに、レポートに移動してから参照に移動します。アセンブリは、使用可能なアセンブリの.netリストに一覧表示されます。

また、Report_Expressions_Default_Permissionsに加えた変更には十分注意してください。フルトラストを与えると、サーバー上で実行されるすべてのコードが、レポートのフルトラストとアクセスの任意の式で、あなたまたはハッカーのフルアクセスになります。

rssrvpolicy.configの変更は、レポートマネージャーのrsmgrpolicy.configに対して行う必要があることに注意してください。

カスタムアセンブリに必要な権限を与える方が安全です。
コードは次のようになります。

    Dim SecurityPermission As New PermissionSet(PermissionState.Unrestricted)
    Try
        Dim SqlClientPermission As New SqlClientPermission(PermissionState.Unrestricted)

        SqlClientPermission.Assert()

        If pSqlCmd() <> vbNullString Then
            cmd = New System.Data.SqlClient.SqlCommand(pSqlCmd(), con)
        Else
            cmd = New System.Data.SqlClient.SqlCommand(sql, con)
        End If

    Catch ex As System.Data.SqlClient.SqlException
        SqlClientPermission.RevertAssert()
        SecurityPermission.Assert()
        Authorized = False
        pErrorMsg(ex.ToString())
    Catch ex As System.Security.SecurityException
        SqlClientPermission.RevertAssert()
        SecurityPermission.Assert()
        Authorized = False
        pErrorMsg(ex.ToString())
    Catch ex As Exception
        SqlClientPermission.RevertAssert()
        SecurityPermission.Assert()
        Authorized = False
        pErrorMsg(ex.ToString())
    Finally
        SqlClientPermission.RevertAssert()

    End Try

    The above code does not need SecurityPermission.   I am asserting it because the 
    exception handler assumes I do not have full access to the security system.  
    Its assumption means it gives me less information in the exception message.   By
    asserting SecurityPermission before accessing the exception message, I am able to 
    attain a full explaination of the error.   

    Note as well, that you are only allowed to make one permission assertion at a time.
    There are other methods available to add permissions to a permissionset and then
    assert that permission set.  That is why you see in the above code a RevertAssert
    to remove the current assertion before asserting another. 

   (*** There is no RevertAssert for SecurityPermission.Assert because its reverted when the 
        current routine ends ***)

    When I have time, I will write some documentation on this process.  I painfully worked 
    my way through it.  
于 2012-11-02T14:04:59.197 に答える
1

レポートを実行するときにユーザーの IP アドレスを見つけるためのより簡単な解決策を誰かに教えてもらいたいのですが、これは私が数週間で一緒にハックすることができた実用的な解決策です.

まず第一に、クライアントではなくサーバーの IP アドレスしか取得できなかったため、カスタム アセンブリやレポート コード ブロックをうまく処理できませんでした。代わりに、レポート マネージャーの aspx ページで jquery を使用して、面倒な作業を行うことにしました。

以下は、私ができる限り簡単な手順です。

1) Program Files\Microsoft SQL Server Reporting Server\MSRS10.Instancename\Reporting Services\ReportManager\Pages ディレクトリに GetClientIPAddress.aspx という名前の新しいファイルを作成します。GetClientIPAddress.aspx の内容は、次の 1 行です。

<%=Request.ServerVariables["REMOTE_ADDR"]%>

これは、実際にクライアントの IP アドレスを取得するページです。

2) 同じフォルダー内の Folder.aspx ファイルを編集し、ファイルの末尾に次の JavaScript コードを追加します。

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">
$(document.body).ready(function () {
    try {
        var sReportName = 'Name of report here'

        $("a").each(function() {
            if (this.innerText == sReportName  || this.textContent == sReportName)
            {
                this.href = this.href.replace('Report.aspx','ReportEx.aspx');
            }
        });
    }
    catch (e) { }
});
</script>

「レポートの名前」をレポートの名前に置き換えます。デフォルトのレポート名は、レポートのファイル名から拡張子を除いたものです。この値は、レポートの [プロパティ] タブ > [全般] サブタブ > [名前] フィールドで確認および変更できます。

3) 最後に、ReportEx.aspx という名前の新しいファイルを同じフォルダーに作成します。このファイルは Report.aspx ファイルに基づいており、同じヘッダーを使用しています。

<%@ Register TagPrefix="MSRS" Namespace="Microsoft.ReportingServices.UI" Assembly="ReportingServicesWebUserInterface" %>
<%@ Page language="c#" Codebehind="Report.aspx.cs" AutoEventWireup="false" Inherits="Microsoft.ReportingServices.UI.ReportWrapperPage" EnableEventValidation="false" %>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">
function getUrlVars()
{
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

$(document.body).ready(function () {
    try {
        var sItemPath = getUrlVars()["ItemPath"];
        var sSelectedTab = getUrlVars()["SelectedTabId"];

        if (sSelectedTab === undefined || sSelectedTab == 'ViewTab')
        {
            $("table.msrs-normal").each(function() {
                if (this.rows.length == 2 && this.rows[0].cells.length == 1)
                {
                    var sIPAddress = $.ajax({
                        type: "GET",
                        url: 'GetClientIPAddress.aspx',
                        async: false
                    }).responseText;

                    this.rows[1].cells[0].innerHTML = '<iframe style="width: 100%; height: 100%;" frameborder="0" src="http://servername/ReportServer/Pages/ReportViewer.aspx?'+sItemPath+'&rs:Command=Render&IPAddress='+sIPAddress+'"></iframe>';
                }
            });
        }
    }
    catch (e) { }
});
</script>

'servername' を、report/sql サーバーを実行しているサーバーの IP アドレスまたはコンピューター名に置き換えます。

この「ハック」は、レポートへのアンカー タグ href リンクを効果的に傍受し、Report.aspx ではなく ReportEx.aspx に移動するほぼ同一のリンクに置き換えることによって機能します。ReportEx ページで、GetClientIPAddress.aspx ページに対して ajax JavaScript 呼び出しが行われ、クライアント IP アドレスが返されます。レポートは、JavaScript によって効果的に非表示または消去され、まったく同じレポートの iframe に置き換えられます。唯一の違いは、今回はレポートに直接渡されるクエリ文字列パラメーターとして、新しいレポートに IP アドレスが設定されていることです。これにはもちろん、レポートに「IPAddress」というパラメーターを作成する必要があります。これにより、このすべての作業が完了したら適切に受け入れられるようになります。

では、ここまでです。誰かがこれを行うためのより良い方法、または私の手順の一部を簡素化する方法を考えることができれば、それについて聞いてみたいです! これは SQL Server 2008 で行われました。このソリューションは、以前のバージョンでも新しいバージョンでも機能すると思いますが、コードを少し変更する必要があります。この解決策は回り道ですが、これを行う方法を見つけようとして費やした私の時間と時間が他の誰かに利益をもたらすことを期待して、私はそれを提供しています!

于 2012-11-08T17:54:14.160 に答える
1

クライアント IP を返そうとするのにしばらく時間を費やしましたが、どちらも成功しませんでした。しかし、それがあなたにさらに何かを示唆した場合、またはあなたの環境が私の​​環境とは異なる場合に備えて、私が何をしたかをお話ししたいと思いました. SharePoint 統合モードで実行しています。

まず、IP をパラメーターとして渡すことでサーバーをバイパスすると考えたので、次の関数をカスタム コードとして記述しました。

Public Function GetIPAddress() As String
    Dim strHostName As String
    Dim strIPAddress As String
    strHostName = System.Net.Dns.GetHostName()
    strIPAddress = System.Net.Dns.GetHostByName(strHostName).AddressList(0).ToString()

    Return strIPAddress
End Function

次に、次の式のパラメーターがありました。

=Code.GetIPAddress()

素晴らしい理論で、ローカルでは見事に機能しましたが、展開すると、カスタム コードがサーバー上で評価され、ローカルではなく、Reporting Services サーバーの IP アドレスを取得しました。

それで、さまざまな変数で HttpContext を試してみましたが、少しは良くなりましたが、それほどではありませんでした:

Public Function GetClientIP() As String
    Dim IpAddress As String

    IpAddress = "UserHost: " + System.Web.HttpContext.Current.Request.UserHostAddress + " ClientIP: " + System.Web.HttpContext.Current.Request.ServerVariables("HTTP_CLIENT_IP") + " Remote: " + System.Web.HttpContext.Current.Request.ServerVariables("REMOTE_ADDR") +         " Forward: " + System.Web.HttpContext.Current.Request.ServerVariables("HTTP_X_FORWARDED_FOR")
   return IpAddress
End Function

UserHostAddress は SharePoint サーバーの IP、HTTP_CLIENT_IP は空白、REMOTE_ADDR は SharePoint サーバーの IP、HTTP_X_FORWARDED_FOR は空白でした。

そのため、実行できない場合があります。いずれの場合でも、非同期スレッド (レポートのレンダリングに使用される) や、Http 要求を使用して実行されないレポート サブスクリプションでは使用できないなど、レポートで HttpContext を使用しないようにするいくつかの理由があります。

とにかく、それが私が手に入れたところです-頑張ってください!

于 2012-10-26T05:16:15.363 に答える
-1

別のオプション:レポート サーバーの HTTP ログを有効にする

レポート サーバーの HTTP ログを構成するには、メモ帳を使用して ReportingServicesService.exe.config ファイルを変更します。構成ファイルは、\Program Files\Microsoft SQL Server\MSSQL.n\Reporting Services\ReportServer\Bin フォルダーにあります。HTTP サーバーを有効にするには、ReportingServicesService.exe.config ファイルの RStrace セクションに http:4 を追加する必要があります。他のすべての HTTP ログ ファイル エントリはオプションです。次の例にはすべての設定が含まれているため、セクション全体を RStrace セクションに貼り付けてから、不要な設定を削除できます。

   <RStrace>
     <add name="FileName" value="ReportServerService_" />
     <add name="FileSizeLimitMb" value="32" />
     <add name="KeepFilesForDays" value="14" />
     <add name="Prefix" value="tid, time" />
     <add name="TraceListeners" value="debugwindow, file" />
     <add name="TraceFileMode" value="unique" />
     <add name="HttpTraceFileName" value="ReportServerService_HTTP_" />
     <add name="HttpTraceSwitches" value="date,time,clientip,username,serverip,serverport,host,method,uristem,uriquery,protocolstatus,bytesreceived,timetaken,protocolversion,useragent,cookiereceived,cookiesent,referrer" />
     <add name="Components" value="all:3,http:4" />
   </RStrace>

フィールド ClientIp - レポート サーバーにアクセスするクライアントの IP アドレス。HttpTraceSwitches のコンマの後に空白があってはならないことに注意してください (空白がない場合、SSRS は黙って無視します)。

于 2014-10-20T04:59:01.200 に答える