【问题标题】:Configuring ELMAH with SQL Server logging with encrypted connection string使用带有加密连接字符串的 SQL Server 日志记录配置 ELMAH
【发布时间】:2011-08-24 07:35:33
【问题描述】:

我正在尝试使用 SQL Server 2008 R2 在 ASP.NET 4 应用程序中配置 ELMAH 错误日志记录。有什么方法可以告诉 ELMAH 在我们提供的连接字符串上调用我们的内部解密函数?我需要修改 ELMAH 源并重新构建吗?

<configSections>
  <sectionGroup name="elmah">
    <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
    <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
    <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
    <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
  </sectionGroup>
</configSections>

<elmah>
  <security allowRemoteAccess="1" />
  <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" />
</elmah>

<connectionStrings>
  <add name="ELMAH" connectionString="EncryptedConnectionString" providerName="System.Data.SqlClient" />
</connectionStrings>

<system.webServer>
  <handlers>
    <add name="Elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
  </handlers>
  <modules>
    <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
  </modules>
</system.webServer>

【问题讨论】:

    标签: .net asp.net sql-server iis elmah


    【解决方案1】:

    您不能只告诉 ELMAH 对您的连接字符串做某事。但是,您可以做的是告诉 ELMAH 在需要 ErrorLog 时给您回电,让您在运行时获得更多控制权。然后,您可以读取加密的连接字符串,使用您的内部函数对其进行解密并返回一个用它初始化的 SqlErrorLog。

    为此,您需要提供一种兼容的方法 ServiceProviderQueryHandler 代表。这是定义:

    public delegate IServiceProvider ServiceProviderQueryHandler(object context); 
    

    方法的实现必须返回一个实现IServiceProvider的对象的实例。如果您不想自己编写一个开始,您可以从 .NET Framework 免费获得一个。见System.ComponentModel.Design.ServiceContainer。服务提供者的GetService 必须响应ErrorLog 类型的请求,然后您可以返回一个SqlErrorLog 对象,该对象已使用在运行时操作的连接字符串进行了初始化。这是一个可能的实现:

    var parent = ServiceCenter.Current;
    ServiceCenter.Current = context => { 
        var container = new ServiceContainer(parent(context)); 
        var connectionSettings = ConfigurationManager.ConnectionStrings["FOOBAR"];
        var connectionString = Decrypt(connectionSettings.ConnectionString);
        var log = new SqlErrorLog(connectionString); 
        container.AddService(typeof(ErrorLog), log); 
        return container; 
      } ;
    

    这会捕获当前服务点并安装您自己的服务点。 lambda/delegate 创建的传递服务请求到捕获的服务点时,它不能 直接满足它,从而创建一个链。您可以通过在应用程序初始化期间在某处设置 ServiceCenter.Current 来告诉 ELMAH 您的实现,以便上面的代码需要放置。

    请记住,这是一个非常简单的实现,但它应该足以让您开始并在以后需要时进行优化。

    在addition in 1.2 之前,做类似事情的唯一方法需要子类化和其他体操,但仍然产生了部分结果。现在您只需要实现一个方法并将其交给 ELMAH,它会根据对象的服务类型简单地响应来自 ELMAH 的对象查询。

    【讨论】:

      【解决方案2】:

      作为 Atif Aziz 帖子的补充,这里是 VB.NET 版本(InitializeElmah_VB9 for the .NET 2.0 version [without lamdda],InitializeElmah for VB.NET for .NET 4.0)

      Imports System.Web.SessionState
      
      Public Class Global_asax
          Inherits System.Web.HttpApplication
      
      
          Public Overrides Sub Init()
              MyBase.Init()
      
              InitializeElmah_VB9()
              'InitializeElmah()'
          End Sub
      
          Public parent As Elmah.ServiceProviderQueryHandler = Nothing
      
          Sub InitializeElmah_VB9()
              ' TODO: Create Table + Functions '
              parent = Elmah.ServiceCenter.Current
              Elmah.ServiceCenter.Current = AddressOf ElmahCallback
          End Sub
      
          Function ElmahCallback(objContext As Object) As System.IServiceProvider
              Dim container As New System.ComponentModel.Design.ServiceContainer(parent(objContext))
              Dim connectionSettings As System.Configuration.ConnectionStringSettings = ConfigurationManager.ConnectionStrings("FOOBAR")
      
              Dim strConnectionString As String = connectionSettings.ConnectionString
      
              Dim x As New System.Data.SqlClient.SqlConnectionStringBuilder(strConnectionString)
              x.Password = CryptStrings.DeCrypt(x.Password)
      
              strConnectionString = x.ConnectionString
      
              Dim log As Elmah.SqlErrorLog = New Elmah.SqlErrorLog(strConnectionString)
              container.AddService(GetType(Elmah.ErrorLog), log)
              Return container
          End Function
      
          Sub InitializeElmah()
              ' TODO: Create Table + Functions '
              Dim parent As Elmah.ServiceProviderQueryHandler = Elmah.ServiceCenter.Current
              Elmah.ServiceCenter.Current = Function(context)
                    Dim container As New System.ComponentModel.Design.ServiceContainer(parent(context))
                    Dim connectionSettings As System.Configuration.ConnectionStringSettings = ConfigurationManager.ConnectionStrings("Foobar")
                    Dim connectionString As String = connectionSettings.ConnectionString
      
                    Dim x As New System.Data.SqlClient.SqlConnectionStringBuilder(connectionString)
      
                    x.Password = CryptStrings.DeCrypt(x.Password)
      
                    connectionString = x.ConnectionString
      
                    Dim log As Elmah.SqlErrorLog = New Elmah.SqlErrorLog(connectionString)
                    container.AddService(GetType(Elmah.ErrorLog), log)
      
                    Return container
                End Function
      
          End Sub
      
      
          Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
              ' Wird beim Starten der Anwendung ausgelöst
          End Sub
      
      
          Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
              ' Wird beim Starten der Sitzung ausgelöst
          End Sub
      
      
          Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
              ' Wird zu Beginn jeder Anforderung ausgelöst
          End Sub
      
      
          Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
              ' Wird beim Versuch der Benutzerauthentifizierung ausgelöst
          End Sub
      
      
          Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
              ' Wird bei einem Fehler ausgelöst
          End Sub
      
      
          Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
              ' Wird beim Beenden der Sitzung ausgelöst
          End Sub
      
      
          Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
              ' Wird beim Beenden der Anwendung ausgelöst
          End Sub
      
      
      End Class
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-30
        • 1970-01-01
        • 2016-08-09
        • 2019-09-02
        • 2016-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多