纯技术视点

PTV-Pure Technology View
随笔 - 216, 评论 - 2626, 引用 - 95

导航

关于

标签

每月存档

最新留言

广告

【第1页/共15页,216条】
首页
前页
1
...
2009年12月13日

在用 Deep Zoom Composer 生成内容后,传到 SharePoint Server 2007 中后,发现不能浏览,仔细检查发现 Deep Zoom Composer 生成的很多以 _files 的目录,传到 SharePoint Server 2007 中后,目录被改了名字,自动在最后加了下划线 "_",导致不能正常访问。

此处详细介绍了此问题。

 

posted on 2009-12-13 12:45:29 by moslem  评论(1) 阅读(1646)

 
2008年06月09日

虽然几乎所有文档都在提醒操作人员在修改注册表的时候,都要进行备份,但实际上,这并不是大多数人的必备步骤。

如果你不慎修改或删除了 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet 中的很多东西,而且也不知道这些东西是做什么用的,那么在重新安装整个操作系统和应用软件之前,可以尝试如下方法看能否恢复:

1. 先把 HKEY_LOCAL_MACHINE\SYSTEM 的各个子键备份一下

2. 不要马上重启机器,不当修改这个子键,最常见的结果就是系统不能启动,或者反复重启

3. 如果你能接触到机器的控制台,那么重启,按 F8,选择“已知最近正确模式”(LastKnownGood)进入 Windows,这样能避免上次的不当修改。

4. 如果不能接触机器的控制台(适用于访问机房中的虚拟机、托管在IDC的托管机等),按不了 F8 ,那该怎么办呢? 两个办法:

1) 在 Boot.ini 中加入 /lastknowngood 参数,然后重启(此功能和F8类似),正常重启并登录后,再把 boot.ini 中的此参数去掉

2) 在HKEY_LOCAL_MACHINE\SYSTEM\Select 子键下,将 Current 的值修改为和 LastKnownGood 的值一样,此法和按 F8 的作用也是类似的

以上经验来自于一次重要的服务器恢复过程。

 

posted on 2008-06-09 22:11:45 by moslem  评论(1) 阅读(5534)

 
2008年01月06日

最近在实施项目时,发现 System Center Operation Manager 2007 (OpsMgr)真是个好东西。监控的最主要功能包括:

  • 网络设备
  • Operating System(磁盘、重要性能计数器、网卡)
  • SQL Server
  • DNS
  • AD
  • Terminal Service
  • NLB
  • Cluster Service
  • BizTalk Server
  • SMS
  • DHCP
  • Web Application
  • 自定义分布式应用程序
  • ......

最后这个得多说一下,大家开发过比较复杂系统都知道,如果用户反映系统出现故障,一步一步去确定系统的各个环节是否有问题是非常麻烦,检查交换机和路由器、Ping 操作系统、检查数据库服务器、检查数据库是否正常(如日志已满)、检查 IIS 及 App Pool 是否异常、检查自定义的 Socket 程序是否正常等...

通过自定义分布式应用程序,可以把以上所有内容整合在一起,系统会自动监控每个环节,如果有问题,会以图形化的方式及时显示系统状况,这个视频中有介绍,真的很 Cool ,不骗你。

 

posted on 2008-01-06 17:45:00 by moslem  评论(2) 阅读(6722)

 
2007年04月10日

平时白天使用中国建设银行个人网上银行系统并不多,今天由于要做一笔转帐,在下午登录个人网银系统并输入正确的身份信息后,竟然显示这样一条比较有意思的错误信息:

"超流量拒绝"还真是个新词,不知道是建设银行发明的,还是网银系统的平台厂商 IBM 发明的,难道是 QoS ?

此外也觉得"拒绝"二字有点生硬,即使不是谦语,也难道不能有更人性一点的提示吗?

posted on 2007-04-10 16:47:00 by moslem  评论(17) 阅读(7889)

 
2007年02月12日

在过去一两个月内,我身边感染“熊猫烧香”病毒的人非常多,远在新疆伊犁家中的一台电脑也未能幸免。病毒的破坏性已经让人非常头疼,病毒作者不思悔改,反倒不停地推出新版本,并在程序中的一些故意预留一些信息,何其猖狂。

今天看到新闻,总算有所安慰,希望这次事件能够让现在这些无法无天的病毒、流氓软件的作者/公司警醒,网络空间不能为所欲为,危害中国数量庞大的计算机用户的结果一定是法律的严惩。

posted on 2007-02-12 20:33:00 by moslem  评论(6) 阅读(7813)

 
2006年12月09日

今天偶然发现 Vista 中自带一个截图工具,可以方便地截取任意格式、矩形、窗口或全屏幕,截取之后可以直接存储为 JPG、PNG等格式,而且能够进行一些批注,同时也能够直接发送电子邮件。不过遗憾的是,在直接存储成 JPG 时,截图工具和画笔一样,都会使图形失真,还是先保存成其他格式,然后再转换成 JPG 。

此工具的截图如下所示:

 

posted on 2006-12-09 20:48:00 by moslem  评论(19) 阅读(13991)

 
2006年11月09日

号称“国内最火热的IT 产业资讯站点太平洋产业资讯”(地址:http://www.pconline.com.cn/news

看看其页面源码:

<title>|&gt;&lt;| 国内最火热的IT产业资讯站点--太平洋产业资讯</title>
<META NAME="description" CONTENT="国内最火热的IT新闻频道,最多IT业界内幕的新闻频道,扎根市场深入渠道的IT新闻报道,全方位透视IT业界,联系消费者与业界人士的IT新闻频道。">
<META NAME="keywords" CONTENT="googleCEO网络,名人,财报,思科,SUN,微软,网络,三星,甲骨文,oracle,microsoftoffice,riaa盗版,色情,裸体歌星,影星排行,联想,苹果,宽带,资费,adsl,电影,音乐,破产,收购,liunx,开源,共享,网络,垃圾邮件,网站,itunes,cnnic,3721,百度,IBM,windows,p2p黑客,破解,病毒,、为,小灵通,UT斯达康,3G">

为了搜索结果,道德和脸面都不要了。

posted on 2006-11-09 11:25:00 by moslem  评论(24) 阅读(10107)

 
2006年11月05日

在 ASP.NET 2.0 中,GridView 支持修改/删除记录,但却不支持新增记录的功能(个人感觉是 GridVew 的一大缺憾,估计在下一版本中会加入此功能),大多数人建议用 FormView 来完成增加记录的功能,但是 FormView 和 GridView 不是同一个表格,所以无法在同一个页面的同一个表格中显示。如果故意将 FormView 或自己的一堆于用新增功能的控件使用普通的表格组装起来,那么会碰到一个很麻烦的问题,即两个表格的列宽如何协调一致,大多数情况下,大家在做表格的时候,表格中各列的宽度都是自动调整的,所以强行指定宽度在很多情况下并不适用。

通过实践,想出了一种办法,主要步骤如下所示:

1) 在 GridView 的 EmptyDataView 中,放置一个普通的Html Table,以便在GridView绑定的数据源中无数据时依旧显示表头(如果数据源为返回的数据行数为0,GridView默认是不显示表头的),假设 ID 为 tbHeader,它的作用是下面用于新增功能的 tbForm 的各列控件提供说明(充当表头);

2)在 GridView 下面,放置一个普通的 HTML 表格,其列数和 GridView 中定义的列数保持一致,但行数只有一行,然后在此表格的各列中放入用于新增功能的各个控件(如 TextBox等),假设此表格的 ID 为 tbForm

3)在页面中加入一段客户端脚本,以便使页面展示到客户端时,利用 Javascript 将两个表格强行合并到一起,这样就可以将只有一行的 tbForm 合并到 GridView中,因此 GridView 的最下面多出一行,其中有 tbForm 表格中定义的输入控件和“添加”链接(按钮),主要代码(JavaScript)如下:

function MergeTable(source,dest)
{
    var row;
    var cell;
    var sourceTb = document.all(source);
    var destTb = document.all(dest);
    for (var i=0; i<sourceTb.rows.length; i++)
   {
         row = document.createElement("TR");
         for (var j=0; j<sourceTb.rows(i).cells.length; j++)
        {
             cell = document.createElement("TD");
             row.appendChild(cell);
             //复制对象
             for(k=0;k<sourceTb.rows(i).cells(j).all.length;k++)
                 cell.appendChild(sourceTb.rows(i).cells(j).all.item(k));
        }
        destTb.tBodies(0).appendChild(row);
    }
    for (var i=sourceTb.rows.length-1; i>=0; i--)
    {
        sourceTb.deleteRow(i)
    }
}

function ChangeTableLayout()
{
     if(document.all('tbHeader') == null)
        MergeTable('tbForm','<%=myGridView.ClientID %>');
    else
        MergeTable('tbForm','tbHeader');
}

ChangeTableLayout();

如果 GridView 绑定时没有数据,将不显示其中定义的各列,而只显示 EmptyDataView 中的 tbHeader,这时要合并 tbHeader 和 tbForm。如果 GridView 绑定时包含数据,则不会显示 EmptyDataView(当然也不会显示其中的 tbHeader),但这时会显示 GridView 中定义的各个列,因此只需将 GridView 本身和 tbForm 合并即可。 GridView 的客户端ID可以用GridView.ClientID来获取。

在服务器端很容易知道 GridView 绑定后是否包含数据,但对于客户端来说,不容易检查,一个简单的作法就是检查页面中有没有 tbHeader 对象(如果有,则说明表格没有数据,如果无此对象,表示 GridView 中包含数据... 好啰嗦)

4)如果是 AJAX 环境,上述脚本有可能不被执行,可以调用 Sys.Application.load.add ( JavaScriptFunction) 来强制执行脚本,来合并表格,主要代码如下(C#):

ScriptManager myScriptManager = ScriptManager.GetCurrent(Page);
if (myScriptManager.IsInPartialRenderingMode)
{
    Page.ClientScript.RegisterStartupScript(this.GetType(), "ShowFullTable1", "ChangeTableLayout();\n", true);
}
else
{
    Page.ClientScript.RegisterStartupScript(this.GetType(), "ShowFullTable2", "Sys.Application.load.add (ChangeTableLayout);\n", true);
}

注:上述代码中的 ChangeTableLayout 为客户端脚本函数的名称,其中调用第3步骤中的代码,上述代码在 Atlas 中通过,在 ASP.NET AJAX Beta 上尚末测试。

另:为了更能说明上文代码的效果,我抓了一个截图,图中包括表头在内的前三行就是 GridView,最下面一行其实来自于另一个表格,在客户端强制合并后,显示效果就是这样,看起来象是一个表格。

感谢大家的意见,我对原文中的表述不明确的地方进行了更改。

posted on 2006-11-05 22:19:00 by moslem  评论(78) 阅读(22242)

 
2006年10月25日

授权管理器(AzMan)是 Windows Server (2000、2003、Longhorn Server...)中自带的、能够和AD紧密集成的、供应用程序使用的授权检查引擎,它实现了完整的基于角色的授权管理框架,利用它,可以在应用程序中大大简化与授权有关的代码编写与实现。

在目前版本中,授权策略信息有两种存储方式:

  • XML
  • 目录(如活动目录-AD或ADAM)

上述两类三种存储方式的适用场景分别如下:

  • 简单的小型应用可以直接使用XML,在这种方式中,不用设置/扩展 AD/ADAM 的 Schema,非常方便
  • 如果基础域环境不好(如应用程序不便访问DC、存在多个Domain)等情况时,可以使用 ADAM
  • 如果基础域环境较好,且应用程序的身份完全与AD集成,最好使用AD

在 Vista 中,AzMan 又增加了一种存储方式:SQL Server,这样对于应用程序来说,又多了一种更实用的选择,而且即然能存在 SQL Server中,估计通过一些手段,这些信息也能存储到其他类型的数据库中,如Access、Oracle等,现在 ASP.NET 2.0中的一些 Provider 不也是公开源代码了,并且实现了其他数据库类型的 Provider 了嘛。

不过,AD/ADAM 具有复制功能,可以方便地实现多个实例之间的目录同步,而SQL Server 不具有此功能,另外 AD/ADAM 在查询方面具有性能优势(AzMan的绝大多数请求是查询),所以到底要使用哪一种存储方式,还是要综合评估。

关于 AzMan 的更多信息,可以参考 AzMan MSDN Blog

posted on 2006-10-25 16:34:00 by moslem  评论(7) 阅读(7736)

 
2006年10月17日

我们在编写基于 ASP.NET 的应用程序时,如果代码执行出错或检测到异常,一般会提示用户“返回”或“回退”,或者在多步操作、列表/详细的查看界面中,也会给用户提供回退到上一页面的链接,对于这种情况,大家很快就会想到的简单做法就是利用 Javascript 来实现,即 history.go(-1) ,但是由于 ASP.NET 页面的 PostBack 机制,所以 history.go(-1) 可能还是当前页面,而不能真正回退到上一页面。

在 Classifieds Site Starter Kit 中,学习到一种不错的关于回退的处理方法,可以分别在客户端和服务器控件中实现页面的回退,代码如下:

1)首先在页面中增加两个属性

//记录上一个页面的信息
private string UrlReferrer { get { return ViewState["UrlReferrer"] as string; } set { ViewState["UrlReferrer"] = value; } } //记录 PostBack 的次数 public int NumPostBacks { get { if (ViewState["NumPostBacks"] != null) return (int)ViewState["NumPostBacks"]; else { ViewState["NumPostBacks"] = 0; return 0; } } set { ViewState["NumPostBacks"] = value; } }
 

2)在 Page_Load 事件记录上一页面地址、更新 Postback 次数、设置回退链接的地址

// 记录上一页面的信息或更新 PostBack 的次数 protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { if (Request.UrlReferrer != null) this.UrlReferrer = Request.UrlReferrer.ToString(); } else NumPostBacks++; int goBackSteps = NumPostBacks + 1; BackLink.NavigateUrl = String.Format("javascript:history.go(-{0});", goBackSteps); }

 

3)直接在代码中处理回退操作(如 Back_Click),可以直接调用如下方法

//在代码中回退 protected void ReturnToPreviousPage() { string referrer = UrlReferrer; if (referrer != null) Response.Redirect(referrer); else Response.Redirect("~/default.aspx", true); }

posted on 2006-10-17 22:03:00 by moslem  评论(18) 阅读(10048)

 
2006年10月16日

近期帮别人在 ASP.NET 中实现简捷的安全/权限控制,于是进行了相关研究与内容搜集,并整理成代码,已在实际的项目中运用,效果突出,比 .NET 中的代码访问安全性(CAS)和 ASP.NET 中的相关安全控制机制更为灵活。

于是把其中实现的内容和主要代码共享出来,但内容较多,放在在随笔里会干扰大家查看首页的视线,所以归到文章里,感兴趣者可以在这里http://blog.joycode.com/moslem/articles/85194.aspx)查看。

本文及其中的代码主要介绍了以下内容:

  • 如何在 C# 中简捷/方便地进行 AOP 编程
  • 如何利用 AOP 来透明地在业务逻辑对象中进行权限检查
  • 如何实现完整的基于角色的访问控制模型
  • 如何在UI上针对不同的用户权限对控件进行设置(如禁止或隐藏)
  • 如何设置 Attribute,如何利用反射获取程序集中所有的、指定类型的 Attribute 定义
  • 其他相关内容

posted on 2006-10-16 00:40:00 by moslem  评论(3) 阅读(10704)

 

一. 背景

  1. .NET 平台上没有完整的 RBAC 机制,.NET 中的安全模型(代码访问安全性:CAS)只是实现到 Role 层次,没有细化到 Task 层次,ASP.NET 2.0 中的诸多安全机制,如 Membership、Web.Config 的安全配置,都只能针对 Role 进行设置,大家在利用这些安全机制,往往需要在程序/代码硬编码(HardCode)角色,这样就无法实现在运行期自定义角色的功能
  2. Windows 2000/2003 中自带的 Authorization Manager 虽然实现了较为完整的RBAC模型,但一般只适用于 Windows 用户,而且也需要手动去进行权限检查(调用 AccessCheck方法)
  3. 权限检查是一个通用操作,最好的实现方式就是面向方面的编程(AOP)

二、相关主题介绍

  1. RBAC模型的要素:三个实体:用户、角色、任务(或操作)(User、Role、Task),其稳定性逐渐增强,两个关系,User<->Role、Role<->Task,其中:
    • User 是日常管理运行时建立
    • Role 是部署/交付建立
    • Task 是开发时确定
    • User<->Role 是日常管理运行时建立
    • Role<->Task 是部署/交付时建立
  2. 一般来说,Task是固定的,是和应用程序紧密绑定的,即使对之进行硬编码,也没有关系
  3. User/Role 部分比较容易实现,例如ASP.NET 2.0中 Membership 的实现

三、具体实现

注:本文中实现 AOP 的思路主要来自于如下文章:Aspect Oriented Programming using .NET - AOP in C# (http://www.developerfusion.co.uk/show/5307/3/) ,这是我看到的、在.NET 上实现 AOP最简捷/方便的方法,它不便提供了原理介绍,也提供了 Visual Studio 2005 的 Sample Project ,其中有 Security Check 和 Logging 的 AOP 功能。它的优点在于,在实现 AOP 的同时,不需要再去建立接口(这是很多人的做法),直接在原有类上进行少量改动,即可实现完整的 AOP 功能。

1. 定义描述“Task”(任务)的 Attribute

using System;

namespace BusinessLogic.Security
{
    /// 
    /// 用于定义系统中的操作
    /// 
    [AttributeUsage(AttributeTargets.All,AllowMultiple=false,Inherited=true)]
    public sealed class Task : Attribute
    {
        private string _name,_description;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public string Description
        {
          get { return _description; }
          set { _description = value; }
        }
        
        public Task(string name,string description)
        {
            _name = name;
            _description = description;
        }

        public Task()
        {
        }
    }
}

2. 编写权限检查的 AOP 类 SecurityAspect,完成权限检查的功能

using System; using System.Diagnostics; using System.Reflection; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Activation; namespace BusinessLogic.Security { //消息接收器 internal class SecurityAspect : IMessageSink { //内部变量 private IMessageSink m_next; //构造方法 internal SecurityAspect(IMessageSink next) { m_next = next; } IMessageSink 实现 自定义的 AOP 方法 } public class PermissionCheckProperty : IContextProperty, IContributeObjectSink { IContributeObjectSink 实现,将 AOP 类加入消息处理链 IContextProperty 实现 } //特性定义,用于 Consumer [AttributeUsage(AttributeTargets.Class)] public class PermissionCheckAttribute : ContextAttribute { public PermissionCheckAttribute() : base("PermissionCheck") { } public override void GetPropertiesForNewContext(IConstructionCallMessage ccm) { ccm.ContextProperties.Add(new PermissionCheckProperty()); } } }

?

3. 定义用于权限检查的两个类:AzMan、AzHelper

这两个类的功能是从 XML 配置文件中读入 Role 和 Task 的映射关系,以确定 Role 中是否包含 Task 的引用,从而确定当前 Role 是否具有对此 Task 的权限。

注:这里可根据项目的实际情况,如果你的 Role 和 Task 的映射关系是存放在 Windows 的授权管理器(Authorizatiom Manager)或数据库中,你可以使用自已
的方法来替换下列类。

在本例中,我的 Role 和 Task 的关系是存放在 XML 文件中,XML文件的格式如下所示:

<?xml version="1.0" encoding="utf-8"?> <ACL> <Tasks> <Task Name="AddItem" Description="增加" /> <Task Name="ModifyItem" Description="修改" /> <Task Name="RemoveItem" Description="删除" /> <Task Name="ListItem" Description="获取列表" /> </Tasks> <Roles> <Role Name="Manager"> <Task Name="AddItem" /> <Task Name="ModifyItem" /> <Task Name="RemoveItem" /> <Task Name="ListItem" /> </Role> </Roles> </ACL>

AzMan.cs 完成角色/任务映射关系的检查

using System; using System.Collections.Generic; using System.Text; using System.Xml; namespace BusinessLogic.Security { public class AzMan { public static bool AccessCheck(string taskName, string[] roles, XmlDocument aclDoc) { XmlNode rootNode = aclDoc.DocumentElement; XmlNodeList roleNodes,taskNodes; bool IsPermissiable = false; for (int i = 0; i < roles.Length; i++) { roleNodes = rootNode.SelectNodes("Roles/Role[@Name='" + roles[i] + "']"); if (roleNodes != null) { taskNodes = roleNodes.Item(0).SelectNodes("Task[@Name='" + taskName + "']"); if (taskNodes.Count != 0) { IsPermissiable = true; break; } } } return IsPermissiable; } } }

AzHelper.cs 助手类,协助其他类,更好地调用 AzMan 类的方法,以及基于性能考虑,对Role<-->Task的XML配置文件进行缓存:

using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Web; using System.Web.Security; using System.Diagnostics; using System.Reflection; using System.Web.Caching; namespace BusinessLogic.Security { public class AzHelper { /// /// 检查当前用户是否具有执行当前任务的权限,如果有权限,则不做任何处理 /// 如果不具有权限,则引发异常 /// public static void PermissionCheck(string taskName) { if (HttpContext.Current != null) { XmlDocument aclDoc = (XmlDocument)HttpContext.Current.Cache["ACLDoc"]; if (aclDoc == null) { CacheXml(); aclDoc = (XmlDocument)HttpContext.Current.Cache["ACLDoc"]; } string[] roles = Roles.GetRolesForUser(); if (!AzMan.AccessCheck(taskName, roles, aclDoc)) throw new UnauthorizedAccessException("访问被拒绝,当前用户不具有操作此功能的权限!"); } } /// /// 检查当前用户是否具有执行指定任务的权限 /// /// 任务名称 /// True/False 是否允许执行 public static bool IsPermissible(string taskName) { if (HttpContext.Current != null) { XmlDocument aclDoc = (XmlDocument)HttpContext.Current.Cache["ACLDoc"]; if (aclDoc == null) { CacheXml(); aclDoc = (XmlDocument)HttpContext.Current.Cache["ACLDoc"]; } string[] roles = Roles.GetRolesForUser(); aclDoc.Load(HttpContext.Current.Server.MapPath("~/App_Data/ACL.xml")); return AzMan.AccessCheck(taskName, roles, aclDoc); } else return true; } /// /// 缓存 XML 文件 /// private static void CacheXml() { string fileName = HttpContext.Current.Server.MapPath("~/App_Data/ACL.xml"); XmlDocument aclDoc = new XmlDocument(); aclDoc.Load(fileName); HttpContext.Current.Cache.Insert("ACLDoc", aclDoc, new CacheDependency(fileName)); } } }


4. 业务逻辑类的实现

由于大多数工作都在 AOP 中实现了,所以业务逻辑类的实现较为简单,主要分为以下几个步骤:

  • 在类的层次定义要求 AOP 方式权限检查的 Attribute: [PermissionCheck()]
  • 使类继承自 ContextBoundObject 对象
  • 在方法层次上利用 Task Attribute 来定义其对应的操作(注:多个方法可以定义为同一个 Task)

例如:ItemManager.cs

namespace BusinessLogic { [PermissionCheck()] public class ItemManager : ContextBoundObject { [Task("AddItem","增加")] public void AddItem(Item item) { //... } } }

这样就可以了,CLR 会在运行时检查类的 PermissionCheck?Attribute,然后寻找方法上的 Task ,取出当前用户对应的 Role ,再去进行匹配检查,如果不能执行此操作,会抛出 UnauthorizedAccessException 的异常,在外部进行处理即可(如在 ASP.NET 中增加 ErrorPage 等)

5. 其他相关功能的实现

Q:如果我写程序时,在各个业务逻辑类定义了大量的 Task ,如果统一提取出来?

A:利用反射可取出程序集中定义的所有 Task ,代码如下:

List<string> dic = new List<string>(); StringBuilder sXml = new StringBuilder(""); string curDir = this.GetCurrentPath(); Assembly ass = Assembly.LoadFile(curDir + "\\AppFramework.BusinessLogic.dll"); foreach (Type t in ass.GetTypes()) { MethodInfo[] mis = t.GetMethods(); foreach (MethodInfo mi in mis) { object[] attrs = mi.GetCustomAttributes(false); if (attrs.Length > 0) { foreach (object attr in attrs) { if (attr.GetType().ToString().IndexOf("Task") >= 0) { Task ta = (Task)attr; //检查重复的 Task if (dic.IndexOf(ta.Name) < 0) { dic.Add(ta.Name); sXml.Append(string.Format("\r\n ", ta.Name, ta.Description)); } } } } } //这就是所有的 Task 定义 sXml.Append("\r\n"); }

此段代码是将 Task 定义保存到 XML 文件中,如果你想保存到 SQL Server/Authorzatiom Manager 中,对代码稍加修改即可。

Q:程序中的 Role 如何实现?

A:如果是 ASP.NET 应用程序,可以直接利用其中的 MemberShip Role 机制,还是比较简单的

Q:如果我想在界面上预先实现一些控制,如某用户不能进行某项操作,则直接将其对应的 Button 禁止或隐藏(Disable/Invisible)掉,如何做?

A:这可以利用 ASP.NET 2.0 中的表达式功能,直接检查当前用户的角色是否可以执行 Task ,如果不行,则利用返回的 Bool 值直接设置 Button 等控件的属性,做法如下:

1)在 App_Code 下定义表达式类 PermissionCheckExpressionBuilder.cs

[ExpressionEditor(typeof(PermissionCheckExpressionBuilderEditor))] [ExpressionPrefix("PermissionCheck")] public class PermissionCheckExpressionBuilder : ExpressionBuilder { public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { string taskName = entry.Expression; return new CodePrimitiveExpression(AzHelper.IsPermissible(taskName)); } } public class PermissionCheckExpressionBuilderEditor : System.Web.UI.Design.ExpressionEditor { public override object EvaluateExpression(string expression, object parseTimeData, Type propertyType, IServiceProvider serviceProvider) { //return expression + ":" + parseTimeData + ":" + propertyType + ":" + serviceProvider; string taskName = expression; return AzHelper.IsPermissible(taskName); } }


2)在 Web.Config 中加入上述表达式定义,以便可以直接在页面上引用

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <expressionBuilders> <add expressionPrefix="PermissionCheck" type="PermissionCheckExpressionBuilder"/> expressionBuilders> configuration>

3)直接在页面控件的相应属性上绑定表达式,如:

  • 如果能执行此操作则显示,否则则隐藏
    <asp:Button ID="Button1" runat="server" Text="AddItem" Visible="<%$ PermissionCheck:AddItem %>" />
  • 如果能执行此操作则启用,否则则禁止
    <asp:Button ID="Button2" runat="server" Text="AddItem" Enabled="<%$ PermissionCheck:AddItem %>" />

4)如果想在代码中自行检查权限,可以直接调用相应方法,如:

protected void Button1_Click(object sender, EventArgs e) { AzHelper.PermissionCheck("AddItem"); //..其他操作 }

5)如何建立 User<-->Role 的映射,Role<-->Task的映射

前者较为简单,ASP.NET 2.0 中就已经具有此功能,当然你也可以利用其 API 来实现自己的定义界面。

对于 Role-Task 的映射来说,首先利用上面的代码从程序集中取出所有 Task ,保存在 XML 文件中,然后在进行配置时,可以显示 Role 和 Task ,来进行映射。

如下图所示:

角色与任务的映射


用户与角色的映射

posted on 2006-10-16 00:05:00 by moslem  评论(49) 阅读(11405)

 
2006年10月15日

今年以来,网上银行安全事件层出不群,闹得沸沸扬扬,据网易财经:网银危机(http://finance.163.com/special/002521GA/ebank.html)上公布的信息,受害者近千人,损失资金金额也近千万元。

如果你在银行的科技部门,就知道这些事件带来的波动效应有多大,几乎所有银行的网上银行都极大的关注这些案件,从上至下,进行安全自查,封闭可能漏洞,关闭风险等级较高的功能,以最大限度地提高系统的安全性,降低客户的资金风险,当然,我也被折腾的够呛。可以说,工行此次事件不但给工行的声誉和上市进程造成了严重影响,而且几乎给所有其它银行的电子银行业务都带来很大的冲击和负面影响,我身边的好多人在了解到这些情况后,有的直接关闭了网上银行的功能,有的则坚定了不相信网上银行系统安全、而且决不开通网上银行功能的想法。

就整个事件反思,个人认为:

1) 工行的对整个事件的态度确实存在问题

在网上银行出了安全事件后,不分青红皂白,一律推到受害人身上,按“工行网银受害者联盟”(www.ak.cn)网站上事件相关人的描述,工行把受害人“妖魔化为弱智群体,然后把我们一脚踢到公安机关;甚至工行还混淆其商业银行的企业身份,对我们肆意诬蔑和打压”。

可以说,工行的这种态度是很多大型国有企业(包括其他行业)的通病,丝毫不出人意外,大家在日常生活中碰到这样的店大欺店案例并不鲜见。在最新一期的《新金融》杂志上,仍看见工商银行电子银行部的主管领导在推脱责任,说问题全出在用户身上。

个人对此也深有感触,有一位同学在工行数据中心,我们在聊起此事时,他仍坚称:整个事件仍是“别有用心”的人在夸大其辞,即使其中真有受害人,那也是他自己太笨。个人以为目前在中国,没有人敢公开地对中国工商银行这样的大目标“别有用心”,所以我宁愿相信,www.ak.cn 上公布的受害人,不存在造假的可能。

态度决定一切,国家足球队原主主教练米卢这话说得没错,我相信,如果工行不是始终独善其身、推脱责任的态度,事件也不会闹到如此地步。

回过头来看看招行,能够在网站上开通论坛,专门收集网友的反馈,来不断地更改和升级系统,印证了其“因您而变”的企业口号,其他哪家银行能有些魄力开这样一个论坛? 当然了,以现在这种系统的水平,最好还是不要开,会被口水淹没的。


2) 工行的系统确实存在问题

据我个人估计,这次大面积暴发的网上银行安全事件的主要原因就是出在工商银行网上银行系统登录页面的安全控件上,工行最早的网上银行系统使用的是普通的 HTML 控件,而且也没有使用验证码,后来,在系统升级时,加入了图片验证码,也加入了安全控件,但这个所谓“安全控件”的安全性并不高,不但不能防止大部分键盘记录软件(KeyLogger)的截获,也没有对数据进行加密(详见于2004年我对此进行的分析:网上银行“安全登录控件”分析),再后来,他们再次对安全控件进行了升级,对数据进行了加密,也能够防止大部分 KeyLogger 的截获,但据了解内情的人员透露,仍然存在漏洞,工行也在考虑进行进一步的升级。

有人也许会说,工行的系统管不了用户机器上的木马,但是,系统安全是一个整体的概念(信息安全领域的“木桶理论”),光做到银行端的安全是没有用的,黑客不会找最安全的地方来进攻的,即然网上银行系统的页面扩展到了用户端,那么银行就有责任地保护这部分应用(最薄弱的部分)的安全。

3)工行的安全事件响应机制存在问题

按照中国人民银行和银监会(它们在此次事件中也有监管缺失的问题)有关要求,商业银行在开办网上银行时,一定要建立安全事件响应机制。但就此次事件来看,没看出来他们的响应机制在哪里,首先是没有积极地帮助受害人锁定帐户,其次是没有积极与公安机关配合,尽早对所有事件统一分析,统一处理,而只是在事件闹得沸沸扬扬的时候,才“正面回应”,结果仍是“工行回应网银资金失窃案 称系统不存在漏洞”(http://news.tom.com/2006-08-18/000N/78413992.html)。

按说对于网上银行这种安全性要求非常高的系统来说,系统务必要记录访问客户端的所有细节,不但应包括最重要的客户端 IP 地址,还应该包括 HTTP 请求(Request)中的所有变量,如远程主机名、User_Agent、HTTP_REFERER、Accept-Language/Encoding等数据,这些数据将对追踪访问人、电子取证、案例侦破提供提供非常有力的证据,很多系统会记录 IP 地址,但往往会忽视其它一些特征数据的记录,而通过对这些数据的分析,有助于对那些通过代理来进行犯罪的黑客进行证据搜集。据个人分析,这些重要数据很可能被工行的网上银行系统所忽视,以至于影响了有效的响应过程。

其次,以工行的这样的大型企业来说,在事件发生时,完全有能力直接与最高级别的公安机关对话,对整个事件统一立案,集中力量统一侦破,相信很快会有结果,但是据了解,工行直到最近才把这事做起来,但这里,大好的时机都错过了。

4)客户所承担的安全成本太高

这不仅是工行的问题,几乎其他所有银行的网上银行系统都存在此问题,个人以为,在 USB-Key(工行称之为 U 盾)上赚客户的钱,纯属利令智昏之举,有的银行甚至以此来做为利润科目,实在是一大耻辱,这就和CCTV以送台大熊猫起名的时机敛财、欺骗全国人民感情的恶举如出一辙(年初起的名,现在还没有送过去),自己图名利,别人来买单。

既然是你系统提供的安全认证手段,费用就应该你自己负责,如果 USB-Key 收费,那是不是设置帐户/卡的口令也要收费? 即使收费,收点成本成不? 现在 1G 的U盘才多少钱,你那个 USB-Key 要收近百元?

除此之外,包括工行在内的多家银行收取所谓的“网上银行年费”,说的不客气,纯属脑子进水,想不明白确定收费的这些决策人员到底有没有了解网上银行业务对于网点/柜台减负所带来的成本节约?

我相信,USB-Key 的代价较高是绝大多数用户没有选择它的原因所在,工行现在推动态口令卡,依我看没必要,把 USB-Key 取消/少量收费即可。

还有一些小细节:大家现在访问一下工行网上银行系统,在登录页面上,仍然没有一些醒目的安全提示,登录页面那么大,就容不下一段关于防止身份盗用的说明? 看看页面源码,很多数据检查/校验的机制仍光溜溜地用 JavaScript 显示在那里,在看看进入系统时的这个地址:http://www.icbc.com.cn/wangyin_xitong/alert.jsp(网银_系统),不能起一个好一点、专业一点的目录名吗?(此网站上诸多目录都是以中文拼音命名)

=========================================================

回顾这个尚未结束的事件,可以认为它是对工商银行在网上银行系统安全保护不够完善的一个教训,也是对其他银行的一个警示,未尝不是坏事,亡羊补牢未晚也。当然了,要说推脱,工行还是有些理由的,毕竟它的网银用户数量在国内是最大的,因此黑客会选择攻击它的用户(这和微软的软件最常被攻击的原因类似),但是,只要扎扎实实地、全面地、负责任地做好安全工作,不要老喊口号而未真正地付诸行动,相信前景还是美好的,网上银行业发展的大潮仍是浩浩荡荡不可挡。

个人以此事件为启发,就网上银行系统的安全性来说,提出一些以后需要关注的问题:

1)降低客户所承担的安全成本,如 USB-Key 费用的降低,大力推广数字证书的应用;

2)学习招商银行(这似乎让很多大银行很没有面子),发展基于浏览器的专用客户端,不但功能更为强大、操作更为快捷方便,而且能够有效避免假网站、木马型病毒的攻击。我们看看欧美地区,大多数的较大的银行都支持OFX(开放金融协议),通过 Microsoft Money 等专用客户端可以直接连接到它们的系统中,个人认为这也是国内网上银行系统的发展方向;

3)改变目前系统中这种通过用户+密码的传统认证方式,只要使用用户名/密码,就有可能受到键盘记录木马的威胁,要彻底的解决此问题,必须
使用全新的身份鉴别技术。例如在 .NET Framework 3.0 中新推出的 CardSpace 技术(内置在 Windows Vista 中,可以安装在 Windows XP 上),就可以彻底地避免键盘记录软件、通讯侦听软件对身份鉴别过程的威胁;

4)进一步加强应用的安全性,在事前、事中、事后各个环节提高可控性,例如:可疑交易的确认(类似于信用卡的可疑消费确认),用户可自行设置登录时段、登录位置(如只限于北京地区)、进行风险等级较高的操作时,能够及时发送短消息通知用户,能够快速定位交易对手(转出时的目标帐户)的相关信息,能够快速锁定可疑账户,能够更完全面的记录客户端的信息,能够进行行为分析;

5)继续有策略、有技巧、持之以恒地加强用户安全教育,这在目前中国的互联网界流氓软件满天飞、普通用户极端受害的情况下,是非常非常有必要的。

posted on 2006-10-15 00:19:00 by moslem  评论(42) 阅读(18732)

 
2006年10月14日

在 ASP.NET 2.0 中,大多数控件都可以直接“自动套用格式”,以便设置一些内置的配色方案,能够方便地设计多姿多彩、色彩丰富的页面,除些之外,ASP.NET 2.0 还提供了网站和页面的主题(Theme)和Skin的功能,可以在网页或网站层次设定各种控件的显示风格,以便统一站点的外观。

在实际开发中,实际上大家可能不会过多地采用内置的“自动套用格式”的功能,而是自己来设定控件的色彩、字体等,当然也有可能是通过 Theme/Skin 来进行的,但是,以我的实践来看,实现机制是很好,但结果往往另人不满意,主要原因是缺乏色彩方面的感觉,往往会设计出来色彩冲突、不协调,甚至在很多情况下相当不好看的界面 ...

即然有这么好的实现机制,肯定会有人实现/共享很好的 Theme/Skin ,Google 了一下,找到一组 Theme,看起来还是相当不错的,可以直接应用的项目开发中,当然了,这组 Theme 也有一些小瑕疵,即某些对比色的过于接近而比较模糊。

 Theme预览:http://www.dotnettreats.com/SampleThemes/Default.aspx
 Theme下载:http://www.dotnettreats.com/tools/Default.aspx

posted on 2006-10-14 22:08:00 by moslem  评论(15) 阅读(15347)

 
2006年10月12日

首先看看 CodeProject 上的两个东西

1、The Freeze Pane DataGridhttp://www.codeproject.com/aspnet/FreezePaneDatagrid.asp

利用文章中提到做法及代码,可以实现在 ASP.NET 1.1 上的、支持横向滚动与纵向滚动的表格,基本上是使用 CSS 实现的,比较简单。

在 ASP.NET 2.0 上,由于文档 HTML DOCKTYPE 发生了变化(HTML->XHTML),所以在使用原文中的横向滚动条会出现问题,但是使用纵向滚动条和锁定表头没有问题。

这种做法没有考虑页面 PostBack 时记录表格的滚动位置,使得用户不得不重新去寻找刚才选中/编辑的那条记录,这比较的不人性化。

2、ScrollingGrid: A cross-browser freeze-header two-way scrolling DataGridhttp://www.codeproject.com/aspnet/ScrollingGrid.asp

此文章利用 Panel 控件和 DataGrid 控件实现了 ASP.NET 1.1 下的完整的、可实现双向滚动、表头锁定的表格,而且它实现了可以记录表格的滚动位置,页面 PostBack 后,表格仍能自动滚动到原有位置。这个控件的一个最大优点是能够适应多种浏览器,如 Internet Explorer 、FireFox 等。

在 ASP.NET 平台上,由于 DataGrid 控件已经升级为 GridView ,所以此控件已不能使用,按照文章下面的讨论,作者声称会尽快升级控件,但似乎在实现时碰到一些麻烦(如何确实表头各列的宽度),目前还没有结果。

目前我的做法:

  1. 参照文章1中提到的作法,利用 CSS 来实现锁定表头的功能
  2. 利用 Panel 控件,设置 ScrollBar 为 Vertical,再在其中放入 GridView 控件 ,可以实现竖向滚动条的功能
  3. 利用 Atlas ,将上述 Panel 再放入 UpdatePanel ,以透明实现保持滚动条位置的功能

示例代码:

<h1>滚动条表格演示h1> <style type="text/css">... th {...}{ border-right: 1px solid silver; position:relative; top: expression(this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.scrollTop-2); /**//*IE5+ only*/ } style> <atlas:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True"> atlas:ScriptManager> <br /> <asp:Panel ID="GridPanel" runat="server" Height="250px" ScrollBars="Auto" Width="562px"> <atlas:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" SkinID="GridView" Width="434px"> </asp:GridView> </ContentTemplate> </atlas:UpdatePanel> </asp:Panel>

这样能基本上实现一个能够锁定表头、竖向滚动、能够在页面PostBack时保持滚动位置的表格,能够满足大部分应用需要。

posted on 2006-10-12 10:16:00 by moslem  评论(8) 阅读(11144)

 
【第1页/共15页,216条】
首页
前页
1
...

Powered by: Joycode.MVC引擎 0.5.2.0