惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
博客园_首页
人人都是产品经理
人人都是产品经理
博客园 - 聂微东
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
博客园 - 三生石上(FineUI控件)
A
About on SuperTechFans
V
Visual Studio Blog
小众软件
小众软件
MyScale Blog
MyScale Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Exploit Database - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
T
Threat Research - Cisco Blogs
AWS News Blog
AWS News Blog
T
Tor Project blog
Jina AI
Jina AI
GbyAI
GbyAI
C
Comments on: Blog
IT之家
IT之家
Apple Machine Learning Research
Apple Machine Learning Research
A
Arctic Wolf
有赞技术团队
有赞技术团队
SecWiki News
SecWiki News
L
Lohrmann on Cybersecurity
Security Latest
Security Latest
Webroot Blog
Webroot Blog
C
Cisco Blogs
雷峰网
雷峰网
云风的 BLOG
云风的 BLOG
博客园 - 叶小钗
K
Kaspersky official blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
宝玉的分享
宝玉的分享
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
H
Hacker News: Front Page
D
Darknet – Hacking Tools, Hacker News & Cyber Security
D
Docker
P
Palo Alto Networks Blog
The Register - Security
The Register - Security
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志

博客园 - Koven

如何拓展你的人脉关系 所谓职业(转载) 期待已久的一本电子书出来了:Applying Domain-Driven Design and Patterns: With Examples in C# and .NET 搜索引擎相关站点收集(转载) 中文搜索引擎系统架构(转载) 中文搜索引擎网络蜘蛛(转载) 中文搜索引擎中的排序技术(转载) 中文分词介绍(转载) 转载一篇不错的关于.NET中内存使用的文章 Data Type Performance Tuning Tips for Microsoft SQL Server(转载) 怎么在ASP.NET 2.0中使用Membership (转载) ASP.NET服务器控件与组件基础概念——HttpHandler (转载) ASP.NET服务器控件与组件基础概念——HttpModule(转载) Tips to improve the performance of ASP.Net Application Best practices for .Net Performance - I HTTP运行期与页面执行模型(转载) XML格式的网站配置文件常见读写方案比较(转载) ASP.NET应用中十大常见的潜在问题(转载) 微软研发75条心得(转载)
HttpModule 示例(转载)
Koven · 2006-08-11 · via 博客园 - Koven

概述

从前面的章节我们知道HTTP Handler提供了类似于ISAPI Server Extention的功能,而HttpModule实现了类似于ISAPI Filter的功能。使用自定义的Handler会覆盖系统默认的Handler,而Module是可以多个同时存在的。

HttpHandlerHttpModule简单来说其实都是对一个请求上下文的处理,但它们两个所处的功能角色是完全不一样的。我暂时还想不出一个既简单又能体现HttpHandler优点的场景来,其实Page类就是一个实现了IHttpHandler的类,在Ajax中也有相关的实现,以及Asp.Net Forums V2中有两个比较简单的实现(AvatarHttpHandlerVCardHttpHandler),大家可以去参考一下。

下面是一个检查用户是否登录及模块授权的HttpModule示例。

场景

一个网站,有一个首页(Default.aspx),一个登录页面(Login.aspx),两个模块(模块1和模块2)。

一、               当用户在未登录的情况下访问网站的任一个页面都会跳转到登录页面要求用户登录,登录完成后跳转到网站首页并在每个页面上显示欢迎词。

二、               假设有两个用户,一个“文野”,一个“stwyhm”,文野可以访问模块1stwyhm可以访问模块2,当他们访问各自有权访问的模块时,显示模块给出的欢迎词,如果访问的模块没有访问权限,给出错误提示。其它用户只能访问指定模块以后的页面。

示例

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

namespace AuthorizationModule

{

    /// <summary>

    /// 说明:检查用户登录的Module

    /// 作者:文野

    /// 联系:stwyhm.cnblogs.com

    /// </summary>

    public class UserAuthorizationModule : IHttpModule

    {

        #region IHttpModule 成员

        public void Dispose()

        { }

        public void Init(HttpApplication context)

        {

            context.AcquireRequestState += new EventHandler(context_AcquireRequestState);

        }

        void context_AcquireRequestState(object sender, EventArgs e)

        {

            // 获取应用程序

            HttpApplication application = (HttpApplication)sender;

            // 检查用户是否已经登录

            if (application.Context.Session["UserName"] == null || application.Context.Session["UserName"].ToString().Trim() == "")

            {

                // 获取Url

                string requestUrl = application.Request.Url.ToString();

                string requestPage = requestUrl.Substring(requestUrl.LastIndexOf('/') + 1);

                // 如果请求的页面不是登录页面,刚重定向到登录页面。

                if (requestPage != "Login.aspx")

                    application.Server.Transfer("Login.aspx");

            }

            else

            {

                // 已经登录,向每个请求的页面打印欢迎词。

                application.Response.Write(string.Format("欢迎您!{0}", application.Context.Session["UserName"]));

            }

        }

        #endregion

    }

    /// <summary>

    /// 说明:检查用户是否有权使用模块的Module

    /// 作者:文野

    /// 联系:stwyhm.cnblogs.com

    /// </summary>

    public class SystemModuleAuthorizationModule : IHttpModule

    {

       #region IHttpModule 成员

        public void Dispose()

        {

        }

        public void Init(HttpApplication context)

        {

            context.AcquireRequestState += new EventHandler(context_AcquireRequestState);

        }

        void context_AcquireRequestState(object sender, EventArgs e)

        {

            HttpApplication application = (HttpApplication)sender;

            // 如果用户未登录,则无需检查模块授权,因为请求会被用户登录Module重定向到登录页面。

            if (application.Session["UserName"] == null)

                return;

            // 获取用户名和Url

            string userName = application.Session["UserName"].ToString();

            string url = application.Request.Url.ToString();

            // 如果用户没有被授权,请求被终止,并打印提示信息。

            if (!Validator.CanUseModule(userName, url))

            {

                application.CompleteRequest();

                application.Response.Write(string.Format("对不起!{0},您无权访问此模块!", userName));

            }

        }

        #endregion

    }

    public class Validator

    {

       /// <summary>

        /// 检查用户是否被授权使用模块。

        /// 文野可以使用模块,stwyhm可以使用模块,所有用户都可以请求限定模块以外的页面

        /// </summary>

        /// <param name="userName"></param>

        /// <param name="url"></param>

        /// <returns></returns>

        public static bool CanUseModule(string userName, string url)

        {

            if (!url.Contains("模块"))

                return true;

            else if (userName == "文野" && url.Contains("模块1"))

                return true;

            else if (userName == "stwyhm" && url.Contains("模块2"))

                return true;

            else

                return false;

        }

    }

}

页面中除了简单的登录保存用户名到Session的代码及一些Html呈现代码外无任何代码。

执行结果

第一步:打开网站首页,因示登录被跳转到登录页面


 

第二步:登录成功后跳转到首面。


 

第三步:访问有权进入的模块1


 

第四步:访问无权进入的模块2


 

开发注意点

    无论是通过Url发出请求,还是一个按钮引起的页面回发,对IIS来说是一样的,都是一次请求。而HttpModule中的事件一般都在页面事件前,特别是控件事件,所以如果在HttpModule的事件中对请求进行过滤处理后就不会执行到页面事件或控件事件,这就是上面示例的UserAuthorizationModule代码中为什么要对请求页面是否是Login.aspx进行判断的原因了。

总结

这里两个自定义的HttpModule实现了它们各自所要达到的过滤请求的功能,一个限制用户登录,一个限制模块访问,当然实际应用中比这要复杂许多。这样的验证方式是简单的、安全的,代码在修改时只要修改相应的HttpModule就可以了,无需在每个页面都写相同的验证代码,也不会发生在Url地址栏里输入一段Url就可以跳过登录及其它验证的情况了。在这两个HttpModule中,因为都要涉及到对Session的访问,所有都使用了AcquireRequestState事件,大家可以根据实际情况使用不同的事件,可以参考我前面文章中的那副HttpModule生命周期图。

相关文章

一点一点学ASP.NET之基础概念——HTTP运行期与页面执行模型
    一点一点学ASP.NET之基础概念——HttpModule
    一点一点学ASP.NET之基础概念——HttpHandler

本文源码

    下载