在请求进入到MVC的处理mcvHandler之前,请求先到达HttpModule,因此可以利用HttpModule做全局的用户验证。

HttpModule

MVC5之前的版本基于system.web.dll库,MvcApplication继承自HttpApplication,以Http管道的方式运行,HttpApplication是整个ASP.NET基础架构的核心,HttpApplication处理请求的整个生命周期是一个相对复杂的过程,在该过程的不同阶段会触发相应的事件

名称

描述

BeginRequest

HTTP管道开始处理请求时,会触发BeginRequest事件

AuthenticateRequest,PostAuthenticateRequest

ASP.NET先后触发这两个事件,使安全模块对请求进行身份验证

AuthorizeRequest,PostAuthorizeRequest

ASP.NET先后触发这两个事件,使安全模块对请求进程授权

ResolveRequestCache,PostResolveRequestCache

ASP.NET先后触发这两个事件,以使缓存模块利用缓存的直接对请求直接进程响应(缓存模块可以将响应内容进程缓存,对于后续的请求,直接将缓存的内容返回,从而提高响应能力)。

PostMapRequestHandler

对于访问不同的资源类型,ASP.NET具有不同的HttpHandler对其进程处理。对于每个请求,ASP.NET会通过扩展名选择匹配相应的HttpHandler类型,成功匹配后,该实现被触发

AcquireRequestState,PostAcquireRequestState

ASP.NET先后触发这两个事件,使状态管理模块获取基于当前请求相应的状态,比如SessionState

PreRequestHandlerExecute,PostRequestHandlerExecute

ASP.NET最终通过一请求资源类型相对应的HttpHandler实现对请求的处理,在实行HttpHandler前后,这两个实现被先后触发

ReleaseRequestState,PostReleaseRequestState

ASP.NET先后触发这两个事件,使状态管理模块释放基于当前请求相应的状态

UpdateRequestCache,PostUpdateRequestCache

ASP.NET先后触发这两个事件,以使缓存模块将HttpHandler处理请求得到的相应保存到输出缓存中

LogRequest,PostLogRequest

ASP.NET先后触发这两个事件为当前请求进程日志记录

EndRequest

整个请求处理完成后,EndRequest事件被触发

HttpApplication提供了基于事件的扩展机制,允许程序员借助于处理管道中的事件进行处理过程扩展。在Asp.net中,提供了两种方式来解决这个问题:IHttpModule方式和golbal.asax方式。这两种方式的核心都是IHttpModule接口。

从功能上讲,HttpModule之于ASP.NET,就好比ISAPI Filter之于IIS一样。IIS将接收到的请求分发给相应的ISAPI Extension之前,注册的ISAPI Filter会先截获该请求。

当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。

public class BasicAuthenticationHttpModule : IHttpModule
{
private static IAuthenticationService _authenticationService;
public static void SetBasicAuthenticationValidator(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
} public void Init(HttpApplication context)
{
//核心:用户认证事件处理
context.PostAuthenticateRequest += ContextOnAuthenticateRequest;
} private static void ContextOnAuthenticateRequest(object sender, EventArgs eventArgs)
{
if (_authenticationService == null ||
HttpContext.Current == null ||
HttpContext.Current.User == null ||
HttpContext.Current.User.Identity.IsAuthenticated)
return;
try
{
IPrincipal principal = null;
var headers = HttpContext.Current.Request.Headers;
var authValue = headers[HttpRequestHeader.Authorization.ToString()];
//if no Basic header, don't prompt for it
if (authValue == null ||
string.IsNullOrWhiteSpace(authValue) ||
!authValue.StartsWith("Basic"))
{
return;
}
//try to parse for it
var parsedCredentials = ParseAuthorizationHeader(authValue);
if (parsedCredentials != null)
{
principal = _authenticationService.ValidateCredentials(
parsedCredentials.Item1, parsedCredentials.Item2);
} if (principal == null)
{
Unauthorized(HttpContext.Current);
return;
}
SetPrincipal(principal);
}
catch (SecurityException)
{
throw;
}
catch (Exception ex)
{
throw new SecurityException("Unexpected error. See inner exception for details.", ex);
}
} private static void Unauthorized(HttpContext context)
{
Trace.TraceWarning("Unauthorized basic credentials");
context.Response.Headers.Add("WWW-Authenticate", "Basic");
context.Response.StatusCode = ;
context.Response.StatusDescription = "Invalid credentials";
context.ApplicationInstance.CompleteRequest();
} private static Tuple<string, string> ParseAuthorizationHeader(string authHeader)
{
try
{
string base64Credentials = authHeader.Substring();
var credentials = Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials))
.Split(new[] { ':' });
if (credentials.Length != ||
string.IsNullOrEmpty(credentials[]) ||
string.IsNullOrEmpty(credentials[]))
{
return null;
} return new Tuple<string, string>(credentials[], credentials[]);
}
catch (Exception exception)
{
Trace.TraceError("BasicAuthentication: ParseHeader " + exception);
throw;
}
} private static void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = Thread.CurrentPrincipal;
} public void Dispose()
{
}
}

进行注册

<system.webServer>
<modules>
<add name="BasicAuthenticationHttpModule" type="WebApplication1.BasicAuthenticationHttpModule" />
</modules>
</system.webServer> Global.asax void Application_Start(object sender, EventArgs e)
{
BasicAuthenticationHttpModule.SetBasicAuthenticationValidator(new AuthenticationService());
}
 

最新文章

  1. HTML5 canvas绘图
  2. 只有图片拼接的html页面图片之间有白条的解决方法
  3. webstrom 中启用emmet插件的方法
  4. Only one instance of a ScriptManager can be added to the page.
  5. Sqlmap下载安装与基础命令使用
  6. vs2015中ctrl+shift+F进行“在文件中查找”,有时候无效?
  7. 判断Http请求由手机端发起,还是有电脑端发起
  8. CXF详细介绍
  9. Helloworld with c
  10. javascript-无间缝滚动,封装
  11. 创建第一个Android应用程序 HelloWorld
  12. win10 uwp MVVM入门
  13. django事务处理
  14. SQL遇到的问题
  15. 浅谈JS中String()与 .toString()的区别
  16. 005. Asp.Net Routing与MVC 之三: 路由在MVC的使用
  17. winform版的dota改键器
  18. 1037C_ Equalize(字符串)
  19. tomcat 的自问自答与总结
  20. 关于 redis 报错 :JsonParseException: Unrecognized token &#39;xxx&#39;: was expecting (&#39;true&#39;, &#39;false&#39; or &#39;null&#39;)

热门文章

  1. 微软发布WCF教程及大量示例
  2. java代码=--数组复制
  3. 011. 解决VS2015中CS1528: Expected ; or = (cannot specify constructor arguments in declaration)
  4. windows下配置protobuf2.6.1
  5. TIMEQUEST学习之黑金动力(三)
  6. python2 encode和decode函数说明
  7. Py修行路 python基础 (三)字典
  8. js处理数值和日期本地化
  9. delphi 天气预报
  10. FatMouse&#39; Trade(Hdu 1009)