# Wednesday, June 13, 2007

asp.net 2.0中引入的Membership机制给我们做web开发带来很多便利,使得我们在做很多项目开发时处理用户和角色及权限问题时减少了相当的工作量。不过我们开发中可能会碰到一个小小的问题如下:

我们知道MembershipUser中有如下重载的方法

  • MembershipUser.ResetPassword () :将用户密码重置为一个自动生成的新密码。
  • MembershipUser.ResetPassword (String passwordAnswer) :将用户密码重置为一个自动生成的新密码。

msdn中有如下描述:

ResetPassword 调用 ProviderName 属性所引用的成员资格提供程序的 MembershipProvider.ResetPassword 方法,以将成员资格用户的密码重置为自动生成的新密码。然后将该新密码返回到调用方。

如果 EnablePasswordReset 为 false,则成员资格提供程序将返回一个异常。

如果 RequiresQuestionAndAnswer 为 true,则必须使用以密码提示问题答案作为参数的 ResetPassword 重载方法,并提供成员资格用户的密码。如果需要密码答案并提供了不正确的密码答案,成员资格提供程序将引发 MembershipPasswordException。

而另外一个方法MembershipUser.ChangePassword(String oldPassword, String newPassword) 又必须提供原始密码,那么这里就产生了一个矛盾:我们希望用户能够通过安全问题和答案来作为找回密码,又希望管理员可以重置某用户的密码怎么办?上述方法均无法直接使用,要么使用MembershipUser.ResetPassword ()而无安全问题和答案验证,要么必须知道问题答案或者原始密码,我们知道这些安全相关的东西我们都是加密的,而且往往采用单向编码的方式,也是说我们不可能轻易的通过读取数据库数据知道用户的答案和旧密码!那么好,如何解决这个问题呢?下面我来提供一个小的解决方案:

Membership的数据库中包含有一个设置用户密码的存储过程:

CREATE PROCEDURE aspnet_Membership_SetPassword
(

 @ApplicationName nvarchar(256),

 @UserName nvarchar(256),

 @NewPassword nvarchar(128),

 @PasswordSalt nvarchar(128),

 @CurrentTimeUtc datetime,

 @PasswordFormat int = 0
)

返回值:成功返回 0;
用户不存在,返回 1;

那么ok,我们开始解决我们的需求吧!思路很简单我们先设置用户一个默认的密码,然后以该密码为旧密码使用MembershipUser.ChangePassword(String oldPassword, String newPassword) 修改用户的密码。下面的代码是在以DataAccess.RunProcedure方法是已经实现的执行存储过程的方法为前提编写的:

public class MembershipSafe
 {
     public static string ResetPassword(string username)
     {
         //将用户密码修改为8位且包含一个特殊符号的随机密码
         return ResetPassword(username, Membership.GeneratePassword(8,1));
    }
  
     public static string ResetPassword(string username, string newpassword)
     {
         //先将用户密码修改为123123
  
         SqlParameter[] _sp = {
                              new SqlParameter("@ApplicationName",Membership.ApplicationName)
                             ,new SqlParameter("@UserName",username)
                             ,new SqlParameter("@NewPassword","1M4h3eZLAKW1WbVTTwYJiJZa33w=")
                             ,new SqlParameter("@PasswordSalt","rcVy3pCccZ9tXW7NHp1Maw==")
                             ,new SqlParameter("@CurrentTimeUtc",DateTime.Now)
                             ,new SqlParameter("@PasswordFormat",1)
         };
         bool op = DataAccess.RunProcedure("aspnet_Membership_SetPassword", _sp) == 0;
         //以123123为原始密码,修改为新密码
         Membership.GetUser(username).ChangePassword("123123", newpassword);
         return newpassword;
     }
 }

注:以上代码仅做参考,不一定是符合您具体项目的需求,比如有人可能会继续问修改了密码怎么告诉用户啊,答案是发邮件或者电话通知啊,哈哈~~

推荐浏览:

posted on Wednesday, June 13, 2007 2:41:02 PM (China Standard Time, UTC+08:00)  #    Comments [0]
# Saturday, May 05, 2007

    最近不少Web技术圈内的朋友在讨论协议方面的事情,有的说web开发者应该熟悉web相关的协议,有的则说不用很了解。个人认为这要分层次来看待这个问题,对于一个新手或者刚入门的web开发人员而言,研究协议方面的东西可能会使得web开发失去趣味性、抹煞学习积极性,这类人应该更多的了解基本的Web技术使用。而对于在该行业工作多年的老鸟来说,协议相关的内容、标准相关内容应该尽量多些的了解,因为只有这样才能使得经手的web系统更加优秀(安全、漂亮、快速、兼容性好、体验好……)。本文我们来说一下MIME 协议的一个扩展Content-disposition。

    我们在开发web系统时有时会有以下需求:

  • 希望某类或者某已知MIME 类型的文件(比如:*.gif;*.txt;*.htm)能够在访问时弹出“文件下载”对话框
  • 希望以原始文件名(上传时的文件名,例如:山东省政府1024号文件.doc)提供下载,但服务器上保存的地址却是其他文件名(如:12519810948091234_asdf.doc)
  • 希望某文件直接在浏览器上显示而不是弹出文件下载对话框
  • ……………………

    要解决上述需求就可以使用Content-disposition来解决。第一个需求的解决办法是

Response.AddHeader "content-disposition","attachment; filename=fname.ext"
 
将上述需求进行归我给出如下例子代码:
public static void ToDownload(string serverfilpath,string filename)
{
    FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
    long fileSize = fileStream.Length;
    HttpContext.Current.Response.ContentType = "application/octet-stream";
    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + UTF_FileName(filename) + "\";");
    ////attachment --- 作为附件下载
    ////inline --- 在线打开
    HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
    byte[] fileBuffer = new byte[fileSize];
    fileStream.Read(fileBuffer, 0, (int)fileSize);
    HttpContext.Current.Response.BinaryWrite(fileBuffer);
    fileStream.Close();
    HttpContext.Current.Response.End();
}

public static void ToOpen(string serverfilpath, string filename)
{
    FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
    long fileSize = fileStream.Length;
    HttpContext.Current.Response.ContentType = "application/octet-stream";
    HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=\"" + UTF_FileName(filename) + "\";");
    HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
    byte[] fileBuffer = new byte[fileSize];
    fileStream.Read(fileBuffer, 0, (int)fileSize);
    HttpContext.Current.Response.BinaryWrite(fileBuffer);
    fileStream.Close();
    HttpContext.Current.Response.End();
}

private static string UTF_FileName(string filename)
{
    return HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8);
}

 

简单的对上述代码做一下解析,ToDownload方法为将一个服务器上的文件(serverfilpath为服务器上的物理地址),以某文件名(filename)在浏览器上弹出“文件下载”对话框,而ToOpen是将服务器上的某文件以某文件名在浏览器中显示/打开的。注意其中我使用了UTF_FileName方法,该方法很简单,主要为了解决包含非英文/数字名称的问题,比如说文件名为“衣明志.doc”,使用该方法客户端就不会出现乱码了。

 需要注意以下几个问题:

  1. Content-disposition是MIME协议的扩展,由于多方面的安全性考虑没有被标准化,所以可能某些浏览器不支持,比如说IE4.01
  2. 我们可以使用程序来使用它,也可以在web服务器(比如IIS)上使用它,只需要在http header上做相应的设置即可

可参看以下几篇文档:

posted on Saturday, May 05, 2007 3:03:14 AM (China Standard Time, UTC+08:00)  #    Comments [0]
# Friday, June 02, 2006
虽然 Apache 的名声可能比 IIS 好,但我相信用 IIS 来做 Web 服务器的人一定也不少。说实话,我觉得 IIS 还是不错的,尤其是 Windows 2003 的 IIS 6(马上 Longhorn Server 的 IIS 7 也就要来了,相信会更好),性能和稳定性都相当不错。但是我发现许多用 IIS 的人不太会设置 Web 服务器的权限,因此,出现漏洞被人黑掉也就不足为奇了。但我们不应该把这归咎于 IIS 的不安全。如果对站点的每个目录都配以正确的权限,出现漏洞被人黑掉的机会还是很小的(Web 应用程序本身有问题和通过其它方式入侵黑掉服务器的除外)。下面是我在配置过程中总结的一些经验,希望对大家有所帮助。
posted on Friday, June 02, 2006 1:13:14 PM (China Standard Time, UTC+08:00)  #    Comments [0]
# Tuesday, March 28, 2006

近一段时间一直忙于公司的项目,无暇来更新技术博客。最近几天将会做一些补充。
公司的服务器在近一个月的时间内时常崩溃,由于我们项目组开发的网站访问量远超过服务器上其他的网站,所以服务器管理员认为是我们的网站程序造成的系统崩溃。但是事实是怎么样的呢?请见以下描述:


服务器管理人员(管):你看服务器的负荷又被你们的网站占了99%,服务器崩溃了。你看一个w3wp.exe进程的cpu消耗是99%。其他客户的网站都是小型程序不可能是他们造成的,肯定是你们造成的。
:我们的网站是不好用了哦,难道真是我们的问题……我回去瞧瞧。(暗地在想,日访问量最多4万的站,不至于让我的程序这样吧)


回去后我不断的修改程序中隐藏的瑕疵,并尽量避免服务器在访问高峰更新程序,但是服务器仍然时常崩溃,频率逐渐提高,最常的时候竟然是一天3次。郁闷……什么原因呢?
今日,服务器管理人员又把我喊过去,说:"你们看看吧,服务器又崩了,你们看看怎么办?我心理就郁闷了,我说你怎么就那么肯定是我们程序的进程造成的呢?"……一阵子罗嗦后,我说:"你把我们的站点和进程池关闭,然后重新启动服务器"……几分钟后,服务器启动了,我们的网站处于关闭状态,结果服务器仍然有个w3wp.exe的cpu消耗居高不下,我说这肯定不是我们的问题了。他们也知道自己判断失误了,但是并没有道歉。我回办公室测试,发现网站的数据维护程序有个一直无法正常使用,因为cpu都被一个非我们网站的w3wp.exe给占了,怎么办?于是自己就开始研究如何处理,并与服务器管理人员一起合作查找那个w3wp.exe的真正归宿,可是任务管理器里只有pdi号没有办法直接看到所属的服务器进程池啊。怎么办?google一下。
找到了微软的文档:Iisapp.vbs:IIS 应用程序查询脚本 于是在服务器上运行iisapp.vbs脚本,并根据pid查出了对应的w3wp的进程池归属,发现是某个客户网站的程序造成的,但是由于早期管理人员并没有将客户网站适当分配进程池,百余个网站在一个默认进程池里,怎么办继续查吧,先按照一定的规则对现有客户网站适当分配进程池,然后利用iisapp.vbs查出是一个济南客户的网站程序造成的,先停掉再说,ok一切正常了。期间发现我们的w3wp.exe进程cpu使用率一直在0-1%之间,而内存消耗也不到130M,心里还是比较满意的。等项目的二期工程时,我们再好好修整一下程序,提高性能并尽量减少服务器负担,以免超大访问量时不至于死掉了,呵呵


相关文章:Iisapp.vbs:IIS 应用程序查询脚本

posted on Tuesday, March 28, 2006 4:15:53 PM (China Standard Time, UTC+08:00)  #    Comments [0]
# Wednesday, December 07, 2005

今天试用了一下MSN Search的Webservice,使用MSN搜索引擎做自己的搜索项目,还是蛮有趣的;-)

具体的SDK可以从http://search.msn.com/developer/default.aspx?FORM=PDDD2下载.

注意使用前需要先申请个AppID,SDK里包含了Sample,可以读一下,推荐之~.

在中文MSDN上有一篇《使用MSN Search Web Service开发搜索应用》:http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/msnsearch.mspx

posted on Wednesday, December 07, 2005 4:16:56 PM (China Standard Time, UTC+08:00)  #    Comments [1]
# Thursday, August 18, 2005
在 web.config 的 <system.web> 节中添加以下代码:
 
<webServices>
  <protocols>
   <add name="HttpGet" />
   <add name="HttpPost" />
   <add name="HttpPostLocalhost" />
   <add name="Documentation" />
  </protocols>
</webServices>
posted on Thursday, August 18, 2005 9:24:10 AM (China Standard Time, UTC+08:00)  #    Comments [4]
# Thursday, July 28, 2005

    在博客园管理员dudu以及博客堂开心就好宝玉的支持和帮助下,烟台.NET 俱乐部也成立啦.
    希望烟台、威海及其周边地区.NET爱好者能积极的加入.
    希望加入此团队的博客园成员可以在本文的评论中回复或EmailTo : qihangnet(AT)hotmail.com。
    请说明你的Blog帐号和所在城市,特长/兴趣(最好详细点)。

    继北京,上海,广州,杭州,郑州,济南等城市成立后。我们烟台也要努力了。
    Let's Do Our Best!

烟台.Net俱乐部博客园团队Blog:http://www.cnblogs.com/team/dotsail.html
烟台.NET俱乐部官方网站:http://qihang.net
烟台.NET俱乐部QQ群:6718824
烟台.NET俱乐部博客园聊天室:http://chat.cnblogs.com/CuteSoft_Client/CuteChat/CH_MainForm.Aspx?ChannelId=45f4536b-39fc-44d5-af07-1715e7b2097e

posted on Thursday, July 28, 2005 9:31:12 PM (China Standard Time, UTC+08:00)  #    Comments [1]
# Wednesday, March 23, 2005
DotNet专业词汇英中对照表,从微软MSDN的文档中转载过来的。希望能对各位DOTNET技术人员有用:)
posted on Wednesday, March 23, 2005 4:47:37 PM (China Standard Time, UTC+08:00)  #    Comments [3]