HTTPS跳转框架HTTP Security--Asp.net和ASP.NET MVC下可自由配置URL的HTTPS跳转框架
来源:互联网 发布:形状优化设计 编辑:程序博客网 时间:2024/06/05 20:27
简介
一个简单易扩展的HTTP跳转HTTPS的框架。由配置文件配置规则,然后在HTTPMODULE里截获请求进行规则验证是否跳转HTTPS.
组成:
- web.config,用来配置规则
- HttpsConfiguration,用于读取配置文件
- HttpSecurityModule,用来截获请求触发规则验证
- RequestProcessor,用既有规则验证请求
- PathsMatcher,多路径(URL)匹配器
- PathMatcher,单URL路径匹配器
- PathMatcherFactory,用于创建StartsWith或Exact具体URL路径,可进行更多扩展,如正则表达式匹配。
- SecureRedirection,跳转HTTPS
WEB.CONFIG
<configSections> <section name="HttpsConfiguration" type="ICStars2_0.Common.ConfigSections.HttpsConfiguration, ICStars2_0.Common, Version=1.0.0.0, Culture=neutral" /> </configSections> <HttpsConfiguration mode="On"> <paths> <add path="/Test" /> <add path="/Account" security="Ignore" /> <add path="/Account/Check.aspx" matchType="Exact" /> <add path="/Member" matchType="StartsWith" /> </paths> </HttpsConfiguration>
mode选项On/Off, 开启或不开启HTTPS跳转
<add path=""/>, 添加一个URL验证规则。 默认security="Secure"并且matchType="StartsWith"
<add path="" security="" matchType="" />,添加一个URL验证规则并设置具体选项。security选项Secure/Ignore,进行HTTPS跳转或忽略当前设置。matchType选项Exact/StartsWith,进行完全匹配或仅匹配开始字串。
HttpsConfiguration
namespace ICStars2_0.Common.ConfigSections{ public enum Mode { On, Off } public enum RequestSecurity { Secure, Ignore } public enum PathMatchType { Exact, StartsWith } internal sealed class ElementNames { internal const string Mode = "mode"; internal const string Paths = "paths"; internal const string MatchType = "matchType"; internal const string Path = "path"; internal const string Security = "security"; } public class HttpsConfiguration : ConfigurationSection { [ConfigurationProperty(ElementNames.Mode, DefaultValue = Mode.On)] public Mode Mode { get { return this[ElementNames.Mode] is Mode ? (Mode) this[ElementNames.Mode] : Mode.On; } } [ConfigurationProperty(ElementNames.Paths, IsRequired = true)] public HttpsPathCollection Paths { get { return this[ElementNames.Paths] as HttpsPathCollection; } } } public class HttpsPathCollection:ConfigurationElementCollection { public HttpsPath this[int index] { get { return base.BaseGet(index) as HttpsPath; } set { if (base.BaseGet(index) != null) { base.BaseRemoveAt(index); } this.BaseAdd(index, value); } } protected override ConfigurationElement CreateNewElement() { return new HttpsPath(); } protected override object GetElementKey(ConfigurationElement element) { return ((HttpsPath)element).Path; } } public class HttpsPath:ConfigurationElement { [ConfigurationProperty(ElementNames.Path)] public string Path { get { return this[ElementNames.Path] as string; } } [ConfigurationProperty(ElementNames.MatchType, DefaultValue=PathMatchType.StartsWith)] public PathMatchType MatchType { get { return this[ElementNames.MatchType] is PathMatchType ? (PathMatchType) this[ElementNames.MatchType] : PathMatchType.Exact; } } [ConfigurationProperty(ElementNames.Security,DefaultValue=RequestSecurity.Secure)] public RequestSecurity Security { get { return this[ElementNames.Security] is RequestSecurity ? (RequestSecurity) this[ElementNames.Security] : RequestSecurity.Secure; } } }}用于读取相应WEB.CONFIG中的信息。
HttpSecurityModule
<httpModules> <add name="SecuritySwitchModlue" type="ICStars2_0.Framework.HttpSecurity.HttpSecurityModule, ICStars2_0.Framework, Version=1.0.0.0, Culture=neutral" /> </httpModules>
namespace ICStars2_0.Framework.HttpSecurity{ public class HttpSecurityModule : IHttpModule { private HttpsConfiguration _config { get; set; } public void Init(HttpApplication context) { _config = ConfigurationManager.GetSection("HttpsConfiguration") as HttpsConfiguration; ; if (_config == null || _config.Mode == Mode.Off) { return; } context.BeginRequest += context_AcquireRequestState; } void context_AcquireRequestState(object sender, EventArgs e) { var application = sender as HttpApplication; if (application.Context.Request.IsSecureConnection) return; RequestProcessor rp=new RequestProcessor(application.Context,_config); rp.Process(); } public void Dispose() { } }}
配置HTTPMODULE,读取HTTPS跳转框架配置信息HttpsConfiguration,把截获的请求和读取的配置文件传递给请求处理器RequestProcessor。如果当前请求是HTTPS,则忽略。
RequestProcessor
namespace ICStars2_0.Framework.HttpSecurity{ internal class RequestProcessor { public HttpContext Context { get; set; } public HttpsConfiguration Config { get; set; } public RequestProcessor(HttpContext context,HttpsConfiguration config) { Context = context; Config = config; } public void Process() { IEnumerable<HttpsPath> pathLIst = Config.Paths.Cast<HttpsPath>(); var ignorePaths = pathLIst.Where(p => p.Security == RequestSecurity.Ignore); var securePaths = pathLIst.Where(p => p.Security == RequestSecurity.Secure); PathsMatcher ignoreMatcher = new PathsMatcher(Context,ignorePaths); if (ignoreMatcher.IsMatch()) return; PathsMatcher secureMatcher = new PathsMatcher(Context, securePaths); if (!secureMatcher.IsMatch()) return; SecureRedirection secureRedirection=new SecureRedirection(Context,null); secureRedirection.Go(); } }}
var ignorePaths = pathLIst.Where(p => p.Security == RequestSecurity.Ignore);获取需要被忽略的URL规则集合
var securePaths = pathLIst.Where(p => p.Security == RequestSecurity.Secure);获取需要进行HTTPS跳转的URL规则集合
PathsMatcher ignoreMatcher = new PathsMatcher(Context,ignorePaths); if (ignoreMatcher.IsMatch()) return;创建忽略规则匹配器并使用需要被忽略的URL规则集合初始化,如果当前求匹配到任何一个忽略规则,则不进行HTTPS跳转。
PathsMatcher secureMatcher = new PathsMatcher(Context, securePaths); if (!secureMatcher.IsMatch()) return; SecureRedirection secureRedirection=new SecureRedirection(Context,null); secureRedirection.Go();创建需要进行HTTPS跳转的URL规则匹配器并初始化, 如果当前请求匹配到任何一个安全规则,则由SecureRedirection进行HTTPS跳转。
PathsMatcher
namespace ICStars2_0.Framework.HttpSecurity{ class PathsMatcher { public HttpContext Context { get; set; } public IEnumerable<HttpsPath> Paths { get; set; } public PathsMatcher(HttpContext context, IEnumerable<HttpsPath> paths) { Context = context; Paths = paths; } public bool IsMatch() { return Paths.Any(p => PathMatcherFactory.CreatePathMatcher(Context.Request.Url.AbsolutePath, p).IsMatch()); } }}
多路径匹配器
PathMatcher
namespace ICStars2_0.Framework.HttpSecurity{ interface IPathMatcher { bool IsMatch(); }}namespace ICStars2_0.Framework.HttpSecurity{ internal class ExactPathMatcher:IPathMatcher { public string Path { get; set; } public string Pattern { get; set; } public ExactPathMatcher(string path, string pattern) { Path = path; Pattern = pattern; } public bool IsMatch() { return Path.Equals(Pattern, StringComparison.InvariantCultureIgnoreCase); } }}internal class StartsWithPathMatcher:IPathMatcher { public string Path { get; set; } public string Pattern { get; set; } public StartsWithPathMatcher(string path, string pattern) { Path = path; Pattern = pattern; } public bool IsMatch() { return Path.StartsWith(Pattern, StringComparison.InvariantCultureIgnoreCase); } }
单一路径匹配器,可扩展更多的匹配器
PathMatcherFactory
internal class PathMatcherFactory { public static IPathMatcher CreatePathMatcher(string path, HttpsPath httpsPath) { switch (httpsPath.MatchType) { case PathMatchType.StartsWith: return new StartsWithPathMatcher(path, httpsPath.Path); case PathMatchType.Exact: return new ExactPathMatcher(path, httpsPath.Path); } return null; } }
匹配器工厂
SecureRedirection
internal class SecureRedirection { public HttpContext Context { get; set; } public string TargetUrl { get; set; } public SecureRedirection(HttpContext context, string targetUrl) { Context = context; TargetUrl = targetUrl; } public void Go() { Context.Response.StatusCode = 301; Context.Response.RedirectLocation = TargetUrl ?? Context.Request.Url.AbsoluteUri.Replace("http://", "https://"); Context.Response.End(); } }
将HTTP请求301重定向成HTTPS请求
总结
如果面对复杂的使用HTTPS的需求,这个框架能基本满足所有需要。当然由于我没有需求使用正则表达式验证,所以没有添加。但非常简单,可以在matchType里加一个“Regex"选项,创建一个新PathMather并在IsMatch中实现正则验证就行了。
另外,这个框架意在结构清晰,职责分明,用户可以明确地扩展任何一部分。有人提出性能问题,这个框架肯定可以再改善。如果网站HTTPS的部分日PV上亿,任何一点小小的优化都是很大的性能提升。有些夸张,我的实际情况只是一个几十人使用的后台部分,性能损耗可以忽略不计。更何况,第一次由HTTP跳到HTTPS后,后续的访问都已转变成HTTPS,也就不会再跳进这个框架里请求处理的部分。
if (application.Context.Request.IsSecureConnection) return;
更进一步,有些浏览器已经把301重定向缓存起来,第一次HTTP跳转到HTTPS后,浏览器会把后续的跳转完成。
关于性能,是一个很大的话题,不在本文的范围之内。
- HTTPS跳转框架HTTP Security--Asp.net和ASP.NET MVC下可自由配置URL的HTTPS跳转框架
- asp.net mvc && asp.net 页面跳转
- ASP.NET mvc下action的跳转方式
- ASP.NET mvc下action的跳转方式
- ASP.NET mvc下action的跳转方式
- asp.net框架内进行页面跳转的问题
- asp.net后台实现另一个框架的跳转
- ASP.NET MVC的跳转攻击问题
- ASP.NET的 MVC框架
- ASP.NET的MVC框架
- asp.net的跳转
- ASP.NET MVC 框架
- ASP.NET MVC 框架
- ASP.NET MVC框架
- ASP.NET MVC框架
- ASP.NET MVC框架
- ASP.NET MVC框架
- 【asp.net】MVC框架
- Django 学习笔记(十二)
- Code First Entity Framework和Lambda表达式First/Where可能会组成的陷阱
- Django 学习笔记(十三)
- 解决Python扩展程序编译安装的error: command 'mt.exe' failed with exit status 31
- LeetCode(3) Longest Substring Without Repeating Characters
- HTTPS跳转框架HTTP Security--Asp.net和ASP.NET MVC下可自由配置URL的HTTPS跳转框架
- Page directive: illegal to have multiple occurrences of contentType with different values
- 一道DFS的小题: 部分和问题
- MySQL数据库引擎ISAM MyISAM HEAP InnoDB的区别
- IOS项目总结之Highcharts——统计图神器
- 两层交换机上划分VLAN借助三层交换机路由功能实现跨网段互访
- 【Devexpress】GridControl之CardView
- 为什么选择golang写手机游戏服务器
- 【博文汇总】linux下多任务编程