exchange邮箱系统增加验证码机制
首先背景是exchange的邮箱系统没有后台源代码。因为这个原因,生成验证码的机制放在aspx的runat="sever"后台代码里面。
首先需要找到iis中logon.aspx文件。在这里找到输入邮箱名和密码的input元素,对应增加上输入验证码的input和显示验证码图片的img元素。
需要增加两个文件:VerifyCode.aspx是用户输入进行输入的验证码验证操作的代码;GetImg.aspx是用于显示验证码图片的,即将之前添加的img的src设置为这个GetImg.aspx即可。至于点击img之后自动刷新,则属于体验性的改进。
代码具体执行逻辑是GetImg在load的时候,将随机生成的验证码加密之后,存在客户端浏览器的cookie中,同时创建一个Img对象,将4位验证码字符按顺序输出到img对象上,同时img随机分布一些点pixel,之后图片的stream返回到浏览器上。
而VerifyCode的验证则是则根据输入的内容和之前的cookie存的密文解密之后进行比较,如果一致,则通过验证。
VerifyCode.aspx代码如下:
<%@ Page Language="C#" AutoEventWireup="true" Debug="true" %> <%@ Import Namespace="System.Security.Cryptography" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Cookies["yzmCode"] != null && Request.QueryString["yzmc"] != null)
{
string code = Decrypt(Request.Cookies["yzmCode"].Value).ToUpper();
//Response.Write("code"+code+"\n");
//Response.Write("code"+code+"\n");
//Response.End();
string ucode = Request.QueryString["yzmc"].ToUpper();
if (code == ucode)
{
Response.Write("ok");
Response.End();
}
else
{
Response.Write("error");
Response.End();
}
}
else
{
Response.Write("error2");
Response.End();
}
}
public static string Decrypt(string Text)
{
string sKey = "Exchange";
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
int len;
len = Text.Length / ;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = ; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * , ), );
inputByteArray[x] = (byte)i;
}
des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(, ));
des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(, ));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, , inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
</script>
GetImg.aspx代码如下:
<%@ Page Language="C#" AutoEventWireup="true" %> <%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Security.Cryptography" %>
<script runat="server">
public static string Encrypt(string Text)
{
string sKey = "Exchange";
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(, ));
des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(, ));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, , inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}
public static string Decrypt(string Text)
{
string sKey = "Exchange";
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
int len;
len = Text.Length / ;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = ; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * , ), );
inputByteArray[x] = (byte)i;
}
des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(, ));
des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(, ));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, , inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
protected void Page_Load(object sender, EventArgs e)
{
int codeW = ;
int codeH = ;
int fontSize = ;
string chkCode = string.Empty;
Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
string[] font = { "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" };
char[] character = { '', '', '', '', '', '', '', 'a', 'b', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 'r', 'x', 'y', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', 'X', 'Y' };
Random rnd = new Random();
for (int i = ; i < ; i++)
{
chkCode += character[rnd.Next(character.Length)];
}
//Session["yzmCode"] = chkCode;
HttpCookie cook = new HttpCookie("yzmCode", Encrypt(chkCode));
cook.Expires = DateTime.Now.AddMinutes();
Response.Cookies.Add(cook);
Bitmap bmp = new Bitmap(codeW, codeH);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
for (int i = ; i < ; i++)
{
int x1 = rnd.Next(codeW);
int y1 = rnd.Next(codeH);
int x2 = rnd.Next(codeW);
int y2 = rnd.Next(codeH);
Color clr = color[rnd.Next(color.Length)];
g.DrawLine(new Pen(clr), x1, y1, x2, y2);
}
for (int i = ; i < chkCode.Length; i++)
{
string fnt = font[rnd.Next(font.Length)];
Font ft = new Font(fnt, fontSize);
Color clr = color[rnd.Next(color.Length)];
g.DrawString(chkCode[i].ToString(), ft, new SolidBrush(clr), (float)i * + , (float));
}
for (int i = ; i < ; i++)
{
int x = rnd.Next(bmp.Width);
int y = rnd.Next(bmp.Height);
Color clr = color[rnd.Next(color.Length)];
bmp.SetPixel(x, y, clr);
}
Response.Buffer = true;
Response.ExpiresAbsolute = System.DateTime.Now.AddMilliseconds();
Response.Expires = ;
Response.CacheControl = "no-cache";
Response.AppendHeader("Pragma", "No-Cache");
MemoryStream ms = new MemoryStream();
try
{
bmp.Save(ms, ImageFormat.Png);
Response.ClearContent();
Response.ContentType = "image/Png";
Response.BinaryWrite(ms.ToArray());
}
finally
{
bmp.Dispose();
g.Dispose();
}
}
</script>
注意:加密解密对应的sKey变量要一致。
判断验证码是否输入正确的js逻辑(简单点描述就是发起get请求,地址是上面提到的VerifyCode.aspx,参数和代码中对应上即可):
var codeVaule = $("#yzm").val();
if(codeVaule == ""){
$("#yzm-tip").html("验证码不能为空");
return false;
}else if(codeVaule.length!=4){
$("#yzm-tip").html("验证码位数不正确");
return false;
}else{
$.get("VerifyCode.aspx?yzmc="+codeVaule,{},function(data){
if(data=="ok"){
$("#yzm-tip").html("验证码正确");
//$(".btnSignin").click();
clkLgn();//登录逻辑
bo=true;
}else{
$("#yzm-tip").html("验证码错误!");
}
});
}
return bo;
(为了简单,使用了jquery,引用即可)
触发登录操作的js函数是clkLgn(),这个放在flogon.js这个脚本文件里面,由于存在点击登录按钮和直接回车(e.keyCode == 13)直接执行登录的两种场景,因此此处需要看清js代码。具体倒没什么难度。
可以修改clkLgn()的代码逻辑,直接在里面增加对输入验证码进行验证的逻辑,然后确定是否走真正的登录的代码。也可以在点击登录按钮或者回车的两处逻辑上分别走验证请求再处理。
本身加上验证码的目的只是为了防止密码撞库,快速达到要求即可。
点击验证码图片自动刷新的改进:
function refreshImg(){
$("#yzmImg")[0].src="GetImg.aspx?"+Math.random();
}
exchange邮箱系统增加验证码机制的更多相关文章
- web系统登陆页面增加验证码
传统登陆页面中包含两个输入项: • 用户名 • 密码有时为了防止机器人进行自动登陆操作,或者防止恶意用户进行用户信息扫描,需增加动态验证码功能.此时,登陆页面中包含了三个输入项: • 用户名 • 密码 ...
- Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...
- [转帖]实时流处理系统反压机制(BackPressure)综述
实时流处理系统反压机制(BackPressure)综述 https://blog.csdn.net/qq_21125183/article/details/80708142 2018-06-15 19 ...
- TODO:Laravel增加验证码
TODO:Laravel增加验证码1. 先聊聊验证码是什么,有什么作用?验证码(CAPTCHA)是"Completely Automated Public Turing test to te ...
- (3)MEF插件系统中通信机制的设计和实现
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 一般的WinForm中通过C#自带的Event机制便能很好的实 ...
- yii2增加验证码详细步骤
作者:白狼 出处:http://www.manks.top/article/yii2_captcha本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留 ...
- (原创)AD账户误删导致Exchange邮箱被删 莫苦恼
由于人员变动,离职人员AD账户和邮箱经常要删除.但是在删除AD账户的时候难免会犯错,将在用的用户给删除了,这是个痛苦的事情, 然后你会发现Exchange邮箱也会跟着删除,抓狂了..,还好,幸亏这里进 ...
- sharepoint获取exchange邮箱报错:该帐户无权模拟所请求的用户
现象: sharepoint获取exchange邮箱报错:该帐户无权模拟所请求的用户 处理办法: 1.Open the Exchange Management Shell 2.输入: New-Mana ...
- cas sso单点登录系列5_cas单点登录增加验证码功能完整步骤
转:http://blog.csdn.net/ae6623/article/details/8919718 本篇教程cas-server端下载地址:解压后,直接放到tomcat的webapp目录下就能 ...
随机推荐
- .NET-使用NPOI组件将数据导出Excel-通用方法
一.Excel导入及导出问题产生: 从接触.net到现在一直在维护一个DataTable导出到Excel的类,时不时还会维护一个导入类.以下是时不时就会出现的问题:导出问题: 如果是asp.net,你 ...
- Asp.net 在网页编写C#代码示例-- 一个简单的web MsSql 命令执行环境
在给一个客户做的系统上,因为要对数据库进行查看,但之前都是用TeamView来连接到客户的服务器进行数据库操作的 但最近客户那边的TeamView好像更改过密码导致我无法正常连接,而巧了客户的网官因为 ...
- (剑指Offer)面试题56:链表中环的入口结点
题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 1.哈希表 遍历整个链表,并将链表结点存入哈希表中(这里我们使用容器set),如果遍历到某个链表结点已经在set中,那么该点即为环的入口 ...
- 通过Intel XDK编写跨平台app(一)
Intel XDK 是一个新的跨平台手机应用开发工具.它努力把整个开发流程变的简单,尽可能把所有的平台都封装到一个包中,通过收集各种开发工具来使你的开发变的简单. 在这篇文章中,我将会向你介绍什么是I ...
- 推荐8款HTML5相关的特殊效果
HTML5是HTML的升级版,HTML5有两大特点:首先,强化了 Web 网页的表现性能.其次,追加了本地数据库等 Web 应用的功能.广义论及HTML5时,实际指的是包括HTML.CSS和JavaS ...
- C#应用视频教程3.1 USB工业相机测试
图像处理是工控很有价值的一个领域,比如人脸识别,车牌识别,还有产品的位置识别,瑕疵检测,对于个人学习来说,我们无法直接上手几万块的成熟工业相机(高端的康耐视要6万左右,而且是黑白的,要测试一些带颜色的 ...
- T-SQL 之 控制流语句
控制流语句也称为流程控制语句,是和高级编程语言中的类似功能一致的,引入控制流语句将使T-SQL代码有顺序执行转变为按控制执行. 批处理:一个批处理段是由一个或者多个语句组成的一个批处理,之所以叫批处理 ...
- poj 3311 Hie with the Pie dp+状压
Hie with the Pie Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4671 Accepted: 2471 ...
- unity3d GameCenter的使用
原地址:http://blog.sina.com.cn/s/blog_6b3661a901013zmh.html 因为开发的游戏需要支持GameCenter,老大把这活交给我来搞,于是俺就百度Goog ...
- hdu2444 The Accomodation of Students(推断二分匹配+最大匹配)
//推断是否为二分图:在无向图G中,假设存在奇数回路,则不是二分图.否则是二分图. //推断回路奇偶性:把相邻两点染成黑白两色.假设相邻两点出现颜色同样则存在奇数回路. 也就是非二分图. # incl ...