ASP.NET中impersonate验证失败案例分析
作者:techmango 日期:2010-08-31
首先,介绍一下,ASP.NET中与impersonate相关的背景知识:
ASP.NET中的impersonate跟Internet Information Services (IIS)中的Integrated Windows authentication (NTLM)的功能是类似的,它可以通过内部网络中的domain用户登录信息来确定用户是否具有Windows identity,从而可以确定一个Web应用程序是否可以访问微软Windows平台上的资源,例如一些通过使用Access Control List (ACL)而受到保护的文件,或者某台数据库服务器.
默认情况下,ASP.NET是被设置为Windows authentication模式,这样就可以将Windows identity应用到当前的HttpContext对象中去(注意,当使用anonymous identification 匿名验证时,HttpContext对象中用户名Name是空白的).但是,这不是用于某一个页面,而是为一个Web应用程序提供访问权限,从而可以访问某一个文件或是网络资源.
要使用ASP.NET的impersonate,我们可以在Web.config 文件中配置impersonate属性,例如下面所示:
<configuration>
<system.web>
<identity impersonate="true" userName="***" password="***" />
</system.web>
</configuration>
Tags: ASP.NET impersonate
探索Asp.net的Postback机制
作者:techmango 日期:2010-03-10
__doPostBack作为在asp.net中一个很核心很重要的部分,我们有必要深入了解一下.
其实,__doPostBack是一个很简单的脚本函数.代码如下:
//__doPostBack
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
控件排序事件中用DataView及DataTable排序
作者:techmango 日期:2010-01-08
在做ASP.NET页面开发时,经常要用到dataset(或者DataTable),绑定到DataGrid或GridView上要进行重新排序,排序规则按照数组fids元素的顺序进行。本文将介绍如何在排序事件用DataView及DataTable实现排序功能.
一般人的做法是用DataView排序,关键代码如下:
DataView dv = dt.DefaultView;
dv.Sort = "dis,发布日期 desc";
然后把dv绑定到DataGird输出。
不过问题又来了,如果我们需要分页功能,在翻页时,我们需要ViewState等控件来保存状态啊.那么我们还是需要用到DataTable或DataSet, DataView本身不能被序列化,而DataView中的Table属性是未经排序的,所以它在这里不起作用.
于是有个菜鸟级土解决方法如下(只使用了简单的循环):
private DataTable SortTable(DataTable dt,string[] pids)
{
DataTable dt0 = dt.Clone(); //复制原表结构
for(int i=0;i<pids.Length;i++)
{
if(pids[i] != string.Empty)
{
DataRow[] drs = dt.Select("pos_id=" + pids[i]);
if(drs.Length > 0)
{
foreach(DataRow dr in drs)
{
dt0.Imp
}
}
}
}
return dt0;
}
说明:就是对排序的数组循环,在datatable中找对应的行,然后复制到新表中。
该方法的效率还是可以的,不过如果交集次数大于20,000,000的时候,就会有效率问题.
其实啊,新近版的.NET类库里的DataRow[]集合对象中已经有个CopyToDataTable方法可以解决DataTable排序问题,在控件的排序事件中实现如下代码:
string currentSortColumn = this.SortColumn;//封闭ViewState变量的属性
this.SortColumn = e.SortExpression;
if (currentSortColumn == this.SortColumn)
this.SortAscending = !this.SortAscending;//封闭ViewState变量的属性
else
this.SortAscending = false;
DataTable dt = (DataTable)ViewState["DataSource"];
DataRow[] filter = dt.Select("",this.SortColumn + " " + (this.SortAscending? "ASC" : "DESC"));
DataTable newTable = filter.CopyToDataTable();
ViewState["DataSource"] = newTable;
this.BindDateGrid();
但我们却不知道CopyToDataTable的效率是否足够好.
ViewState基本原理完全解析
作者:techmango 日期:2009-12-17
ViewState是ASP.NET中用来保存WEB控件回传时状态值一种机制。在WEB窗体(FORM)的设置为runat="server",这个窗体(FORM)会被附加一个隐藏的属性_VIEWSTATE。_VIEWSTATE中存放了所有控件在ViewState中的状态值。
ViewState是类Control中的一个域,其他所有控件通过继承Control来获得了ViewState功能。它的类型是system.Web.UI.StateBag,一个名称/值的对象集合。
当请求某个页面时,ASP.NET把所有控件的状态序列化成一个字符串,然后做为窗体的隐藏属性送到客户端。当客户端把页面回传时,ASP.NET分析回传的窗体属性,并赋给控件对应的值。当然这些全部是由ASP.NET负责的,对用户来说是透明的。
使用ViewState的条件
如果要使用 ViewState,则在 ASPX 页面中必须有一个服务器端窗体标记 (<form runat=server>)。窗体字段是必需的,这样包含 ViewState 信息的隐藏字段才能回传给服务器。而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时,ASP.NET 页面框架才能添加隐藏的字段。
Page 的 EnableViewState 属性值为 true。
控件的 EnableViewState 属性值为 true。
页面本身将 20 字节左右的信息保存在 ViewState 中,用于在回传时将 PostBack 数据和 ViewState 值分发给正确的控件。因此,即使该页面或应用程序禁用了 ViewState,仍可以在 ViewState 中看到少量的剩余字节。
设置ViewState
ViewState可以在控件,页,程序,全局配置中设置。缺省情况下 EnableViewState 为 true 。如果要禁止所有页面 ViewState 功能,可以在程序配置中把 EnableViewState 设为 false 。
在控件中:
<asp:DataGridEnableViewState="false"%>
或
DataGrid1.EnableViewState= false;
在页中:
<%@ PageEnableViewState="false" %>
或
Page.EnableViewState= false;
在程序中:
在web.config中加入
<pages enableViewState="false" />
在全局配置:
在machine.config中修改
<pages enableViewState="false" />
EnableViewState优先级别:
全局配置 < 程序 < 页< 控件
注意:下列服务器控件不能禁止ViewState
Textbox
Checkbox
Checkbox List
RadioButtonList
上面控件的状态通过IPostBackEventHandler 和 IPostBackDataHandler接口处理,而不是ViewState的机制,所以EnableViewState没有效果。
ViewState对象
在页面回传间通信,ASP中一般利用窗体的属性和 session 来存放数据,在 ASP.NET 中也可以使用 ViewState 对象来做同样的处理。
在ViewState存放数据:
ViewState[key]= value;
或
ViewState.Add(key,value);
取出数据:
TempStr =ViewState[key];
key不存在时返回空。
不能通过ViewState对象来访问控件的值。
动态建立控件的ViewState:
当需要动态地建立一个服务器控件,如下建立了一个 RadioButton 控件并加入到窗体控件集合中:
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.Add(pc);
上面的代码增加一个控件到控件集合末,同样也可以插入到已有控件中的任何位置。
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.AddAt(1,pc);
通常,这些动态生成的控件的状态也需要生成到 ViewState 中去,但这个功能并没有完全实现,特别是生成的控件插入到已有的控件中时。
当动态生成控件和已有控件并存时 ViewState 的结果是不可预料的。在页面回传时,首先非动态生成的控件在ASPX页中被生成,并在 Page_Init 和 Page_Load 事件中读取 ViewState。当页面的控件读取 ViewState 的值时,那些动态生成的控件却还没有被生成,所以当动态生成的控件被
生成时,页面就会省略掉ViewState或者以剩下或许错误的 ViewState 来填充控件。
所以,当需要插一个动态生成的控件到已有控件中去时,最好把这个控件的 ViewState 通过EnableViewState禁止掉。
提醒:
1. 当存在页面回传时,不需要维持控件的值就要把 ViewState 禁止。
2. ViewState的索引是大小写敏感的。
3. ViewState不是跨页面的。
4. 为了能包存在 ViewState 中,对象必须是可流化或者定义了 TypeConverter。
5. 控件 TextBox 的 TextMode 属性设置为 Password时,它的状态将不会被保存在 ViewState 中,这应该是出于安全性的考虑。
6. 在页面没有回传 或 重定向 或 在回传中转到(transfer)其他页面时不要使用 ViewState。
7. 在动态建立控件时要小心它的 ViewState。
8. 当禁止一个程序的 ViewState 时,这个程序的所有页面的 ViewState 也被禁止了。
9. 只有当页面回传自身时ViewState 才是持续的。
在ASP.NET中使用AjaxPro
作者:techmango 日期:2009-09-10
AjaxPro是首家支持以各种方式通过javascript访问服务端.net的免费库,类似于SAJAX。它能把Javascript请求发送到.NET方法,服务端传回给Javascript,甚至包括串行化自定义类。其主要特点如下:
可以在Javascript中访问Session和Application数据;
缓存查询结果
免费使用源代码
所有类支持Javascript客户端返回数据,可以在Javascript中使用DataSet
使用HtmlControls组件访问和返回数据
页面无需重载,用事件代理(数据访问层)
因为只提供一个调用接口方法,所以服务端CPU占用非常少。
下面就交您如何使用AjaxPro:
一、配置
Ajax.net有AjaxPro.dll和Ajax.dll两个版本,这两个版本使用上虽然差不多,但还是有区别的,主要的区别如下:
(1)web.config配置文件不一样
Ajax.dll的配置文件写法为
<add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax" />
AjaxPro.dll的配置文件写法为
<add verb="*" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro"/>
(2)调用服务器方法的时候方式不一样,有很多朋友就是因为这个原因,发现命名空间找不到或者对象未定义
引用Ajax.dll的时候,调用服务器方法不要加命名空间,
应用AjaxPro.dll的时候,调用服务器方法需要加命名空间
例如当页面设置为这种设置的时候
<%@ Page language="c#" Codebehind="Test.aspx.cs" AutoEventWireup="false" Inherits="Web.Test" %>
(3)客户端调用方式不一样
Ajax.dll为
var response=Test.GetServerMethod();
alert(response.value);
AjaxPro.dll为
var response=Web.Test.GetServerMethod();
alert(response.value);
ASP.NET动态文字图片水印特效
作者:techmango 日期:2009-08-08
现在有许多网站,为了保护着作权,通常需在图片上嵌入水印(水印的内容可以带文字及背景图片).通过GUI+编写程序来批量处理图片.但这这些方法都将破坏原始图片的完整性.本文将介绍这种方法,利用了HttpHandler处理Http请求的机制,只将要呈现在Web页上的图片嵌入水印, 而不会对文件系统中的原始图片做任何修改,有效地保证了原始图片的完整性。

相关技术
1. ASP.NET中处理Http请求是基于管道模型,这条管道由多个HttpModule 和一个HttpHandler组成,ASP.NET把Http请求依次传递给管道中各个HttpModule, 最终被HttpHandler处理,处理完成后,再依次经过管道中的HttpModule, 把结果 返回给客户端(如图).
Tags: ASP.NET 水印 HttpHandler HttpContext
ASP.NET中实现URL重写RewritePath
作者:techmango 日期:2009-08-05
URL重写技术已经被广泛运用在各大网站上,灵活的URL重写可以让你的网站网站更好地被搜索引擎收录。在本篇就将介绍如何在 ASP.NET中简单的实现URL重写,以及一些常见问题的解决办法。
什么是URL重写?
URL重写就是首先获得一个进入的URL请求然后把它重新写成网站可以处理的另一个URL的过程。举个例子来说,如果通过浏览器进来的URL是 “www.mysite.com/UserProfile/1.aspx”,那么它可以被重写成 “www.mysite.com/UserProfile.aspx?ID=1”这样的URL,这样的网址可以更好的被搜索引擎所阅读。
如何实现URL重写
URL重写可以通过编程的方式来实现。ASP.NET中的Contex.RewritePath()方法可以让你从程序中实现重写请求的URL。一旦重写后,系统将使用新的路径来继续执行这个请求。
在Global.asax文件的Application_BeginRequest()方法中,你需要增加代码来阅读进来的路径,然后根据一个或多个URL重写规则来成需要进一步处理的路径。下面的例子执行以下URL重写规则:
代码清单1:使用Contex.RewritePath()实现URL重写
void Application_BeginRequest(object sender, EventArgs e)
{
String path = Request.Url.ToString();
if (Regex.IsMatch(path, "/URLRewriting/OldUrl.aspx",
RegexOptions.IgnoreCase))
{
Context.RewritePath("/URLRewriting/NewUrl.aspx");
}
else if (Regex.IsMatch(path, "/URLRewriting/UserAccount/(.+).aspx",
RegexOptions.IgnoreCase))
{
String idString =
path.Substring(path.LastIndexOf('/') + 1,
path.Length - path.LastIndexOf('/') - 6);
Context.RewritePath("/URLRewriting/UserAccount.aspx?id=" +
idString);
}
}
在这个例子中,每次一个新的请求被处理的时候,它将首先查看这个Application_BeginRequest()。通过使用Request.Url 属性来获得输入的URL路径,然后通过正则表达式来应用网站URL重写规则,匹配到期望的输入网址后,将它们重写成你希望转向的网址。
Tags: ASP.NET URL重写 RewritePath
在ASP.NET中实现身份模拟Impersonation
作者:techmango 日期:2009-08-04

- 模拟IIS认证帐号
- 在某个ASP.NET应用程序中模拟指定的用户帐号
- 在代码中模拟IIS认证帐号
- 在代码中模拟指定的用户帐号
<IDENTITY impersonate="true" />
<IDENTITY impersonate="true" userName="accountname" password="password" />
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Insert your code that runs under the security context of the authenticating user here.
impersonationContext.Undo();
<%@ Page Language="C#"%>
<%@ Import Namespace = "System.Web" %>
<%@ Import Namespace = "System.Web.Security" %>
<%@ Import Namespace = "System.Security.Principal" %>
<%@ Import Namespace = "System.Runtime.InteropServices" %>
<SCRIPT runat="server">
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll", CharSet=CharSet.Auto)]
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]
public extern static int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
public void Page_Load(Object s, EventArgs e)
{
if(impersonateValidUser("username", "domain", "password"))
{
//Insert your code that runs under the security context of a specific user here.
undoImpersonation();
}
else
{
//Your impersonation failed. Therefore, include a fail-safe mechanism here.
}
}
private bool impersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if(LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
return true;
else
return false;
}
else
return false;
}
else
return false;
}
private void undoImpersonation()
{
impersonationContext.Undo();
}
</SCRIPT>
bool a = File.Exists("D:\\Share\\test.txt");
<IDENTITY impersonate="true" userName="FileExist" password="password" />
Tags: ASP.NET Impersonation
FCKEditor v2.6在ASP.NET下的配置和使用
作者:techmango 日期:2009-07-31
FCKEditor是一款开源的HTML编辑器控件,适合非常多的编程语言,如.Net,Java,Php等等.本文就介绍一下FCKEditor v2.6如何在ASP.NET下的配置和使用.
<add key="FCKEditor:BasePath" value="/fckeditor/"/>
<add key="FCKeditor:UserFilesPath" value="/userfiles/"/>
</appSettings>
ASP.NET中的缓存状态管理
作者:techmango 日期:2009-07-14
在asp.net中提供了的各种缓存管理方案。在web应该程序中,有时我们需要存储常用的数据到服务器内存,以避免每次请求都从数据库中获取数据或重复处理数据逻辑。用户请求相同的数据时将直接从内存获取,从而提高程序响应性能,缩短了用户访问时间。为了做到这点,我们需要将缓存保存到服务器端。
缓存能够帮忙我们实现3个重要方面的服务质量(QoS):
性能 - 缓存通过最小化数据获取及格式化逻辑来提高应用程序性能。
可扩展性-由于缓存最小化数据检索和格式化操作,降低了对服务器资源负荷,从而增强了可扩展性的应用。
可用性-由于应用使用数据缓存后,程式会在其他系统和数据库中避免了故障。
在web程序中,我们可以在服务器端或客户端缓存数据和页面 。让我们来看看asp.net提供的不同的选择,包括服务器及客户端来进行缓存。
服务器端缓存管理方式










