Elmah 简述

ELMAH(The Error Logging Modules And Handlers),直译过来就是“错误日志模块和处理”,它提供了一个用于集中记录和通知错误日志的机制。它是专用于ASP.NET的完全可热插拔的错误日志记录工具。其特点就是无需ASP.NET程序重新编译,即可通过配置web.config(或machine.config)来实现整个应用程序甚至是IIS中所有ASP.NET应用程序的错误日志记录工作。它支持日志的多种存储方式(各种数据库、XML、内存存储),除了提供一个界面用于查询日志详细信息外,还可以通过E-MAIL、RSS订阅或Twitter发布方式通知错误信息给相关人员。

Elmah框架,添加日志文件访问权限

Elmah 配置

web.config 代码块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<configSections>
<!-- Elmah日志记录插件 配置 -->
<sectionGroup name="elmah">
<section name="security" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" type="Elmah.ErrorLogSectionHandler, Elmah"/>
<!-- <section name="errorMail" type="Elmah.ErrorMailSectionHandler, Elmah"/> -->
<!-- <section name="errorFilter" type="Elmah.ErrorFilterSectionHandler, Elmah"/> -->
</sectionGroup>
</configSections>
<!-- Elmah日志记录插件 配置 -->
<elmah>
<!-- 是否允许远程访问。0代表否、1代表是 <security allowRemoteAccess="1" /> -->
<!-- 错误邮件发送 配置 from: 用于发送的邮箱 to: 发送到的终端邮箱地址,多个用','分隔 subiect: 标题 async: 是否异步方式 smtpPort: SMTP端口 smtpServer: SMTP服务地址 userName: 邮箱账号 password: 邮箱密码 noYsod: 邮件中是否包含附件 --> <!-- <errorMail from="test@test.com" to="huangyuan413026@163.com,364965519@qq.com" subject="系统出错...." async="true" smtpPort="25" smtpServer="mail.test.com" userName="test@test.com" password="*****" noYsod="true|false" /> </elmah> -->
<errorLog type="Elmah.AccessErrorLog, Elmah" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Elmah.mdb"/>
</elmah>

请求处理配置:

1
2
3
4
5
6
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
</httpModules>
<httpHandlers>
<add verb="POST,GET,HEAD" path="webLog.axd" type="Elmah.ErrorLogPageFactory, Elmah"/>
</httpHandlers>

这个时候就能通过 ~/webLog.axd 这个请求URL 来让Elmah框架处理,入口是Elmah.ErrorLogPageFactory !

这个时候因为Elmah没有做权限验证,只要访问 ~/webLog.axd 都能看到日志信息,所以这样很不安全。

解决方案1:在IIS配置URL访问权限,只有服务器本机的指定帐号才能访问该路径。

解决方案2:
在web.config配置URL权限访问限制:

1
2
3
4
5
6
7
<location path="webLog.axd">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>

拒绝所有匿名用户访问webLog.axd

在Global.asax文件里面Application_AuthenticateRequest (处理权限验证促发)事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
// 判断是否已经登录
if (Request.IsAuthenticated && !Request.IsStaticFile())
{
// IOC注入:登录用户服务实例
var identityService = ServiceLocator.Current.GetInstance<IIdentityService>();
// 分配当前上下文用户
Context.User = identityService.GetCurrentUser();
}
// 处理日志权限问题
if (Request.Url.ToString().Contains("webLog.axd"))
{
// 获取当前访问用户
var user = Context.User as UserPrincipal;
// 业务逻辑,如果用户不为超级管理员则无法访问该请求数据
if (user == null || (user.UserRole & UserRole.SuperAdmin) == 0)
{
Response.Write("无权限访问");
Response.End();
}
}
}

完毕!!! 这样只要访问webLog.axd 时候都会促发权限验证事件,这个时候就能进行访问的权限控制…

参考资料