.Net Web ADF 应用中的安全技术
作者:Flyingis
任何Web应用都离不开安全性考虑,安全机制分为硬件安全和软件安全,前者一般指的是服务的硬件分层部署,硬件防火墙的设置,服务器的双机热备,后者离软件开发人员的距离更近,可以想到的有哪些呢——密钥、secure sockets layer(SSL)、权限设置等等,本文所谈到的就是这里面的一种,在arcgis server中通过权限来设定用户的访问内容。
乍一看上去似乎是很easy的事情,N多人N个应用里早就把这套机制运用的如火纯青、滚瓜烂熟,但是在ArcGIS Server中出现了这样的需求,mananger用户需要访问地图更多的图层内容,需要能够使用webgis更多的功能,staff用户只能查看其中一部分内容,拥有部分功能的使用权限。51ditu/mapbar这种大众化消费的电子地图可能不需要考虑这些,也不会让用户去考虑这些,因为他们提供的是具有良好用户体验的公众性服务,但是在企业应用中,需要根据用户需求定制多样化的服务内容,这就不得不让开发设计者去考虑这些问题了。
.Net Web ADF和ASP.Net可以有机结合在一起,这就让我们可以利用ASP.Net的登录安全机制来控制权限,当然在ADF中也可以编程实现另外一些内容,下面就开始一一分析。
ASP.Net开发者肯定非常熟悉这样的界面:
Web Site Administration Tool(WSAT)提供了两种安全设置:Internet和Local network,我们使用Internet方式并创建两个不同的用户组Managers和Staff,并创建了两个用户分别隶属于两个组manager1和staff1,manager相比staff可以多访问一个图层,多使用两个server功能(Indentify查询和一个QueryAttributeTask)。
在上面的if语句中,加入三个方法,分别处理:
HideLayer()//隐藏不需要被staff用户看到的图层
RemoveItemFromToolbar()//将Indentify查询从工具条上移除
RemoveTask()//将QueryAttributeTask从TaskManager中移除
HideLayer()
RemoveItemFromToolbar()
RemoveTask()
这样用户通过不同的身份登录就可以看到各自的内容信息。通过ASP.Net登录控件也可以实现部分效果,如LoginView,可以将QueryAttributeTask拖到LoginView上,对应着manager用户,这样存在一个弊端,就是不能在TaskManager中使用该Task。
思路就是这样了,你是不是也有这样的需求呢,试试吧。
任何Web应用都离不开安全性考虑,安全机制分为硬件安全和软件安全,前者一般指的是服务的硬件分层部署,硬件防火墙的设置,服务器的双机热备,后者离软件开发人员的距离更近,可以想到的有哪些呢——密钥、secure sockets layer(SSL)、权限设置等等,本文所谈到的就是这里面的一种,在arcgis server中通过权限来设定用户的访问内容。
乍一看上去似乎是很easy的事情,N多人N个应用里早就把这套机制运用的如火纯青、滚瓜烂熟,但是在ArcGIS Server中出现了这样的需求,mananger用户需要访问地图更多的图层内容,需要能够使用webgis更多的功能,staff用户只能查看其中一部分内容,拥有部分功能的使用权限。51ditu/mapbar这种大众化消费的电子地图可能不需要考虑这些,也不会让用户去考虑这些,因为他们提供的是具有良好用户体验的公众性服务,但是在企业应用中,需要根据用户需求定制多样化的服务内容,这就不得不让开发设计者去考虑这些问题了。
.Net Web ADF和ASP.Net可以有机结合在一起,这就让我们可以利用ASP.Net的登录安全机制来控制权限,当然在ADF中也可以编程实现另外一些内容,下面就开始一一分析。
ASP.Net开发者肯定非常熟悉这样的界面:
Web Site Administration Tool(WSAT)提供了两种安全设置:Internet和Local network,我们使用Internet方式并创建两个不同的用户组Managers和Staff,并创建了两个用户分别隶属于两个组manager1和staff1,manager相比staff可以多访问一个图层,多使用两个server功能(Indentify查询和一个QueryAttributeTask)。
private string fullyEnabledRole = "Managers";
if (!User.IsInRole(fullyEnabledRole))
{
// modify page content for role
}
if (!User.IsInRole(fullyEnabledRole))
{
// modify page content for role
}
在上面的if语句中,加入三个方法,分别处理:
HideLayer()//隐藏不需要被staff用户看到的图层
RemoveItemFromToolbar()//将Indentify查询从工具条上移除
RemoveTask()//将QueryAttributeTask从TaskManager中移除
HideLayer()
private void HideLayer(Map map, string layerName)
{
// 遍历所有Map Functionalities
foreach (IMapFunctionality mapFunct in map.GetFunctionalities())
{
string layerId = GetLayerId(layerName, mapFunct);
// 设置图层不可见
if (!String.IsNullOrEmpty(layerId))
mapFunct.SetLayerVisibility(layerId, false);
}
// 找到和Map关联的Toc
Toc tocCtrl = FindControlOfType(typeof(Toc), Page.Controls) as Toc;
if (tocCtrl != null && tocCtrl.BuddyControl == map.ID)
{
// 移除之前隐藏图层在Toc中的节点
foreach (TreeViewPlusNode resource in tocCtrl.Nodes)
{
TreeViewPlusNode nodeToRemove = null;
foreach (TreeViewPlusNode layerNode in resource.Nodes)
{
TreeViewPlusNode matchNode = FindNodeRecursive(layerNode, layerName);
if (matchNode != null)
{
nodeToRemove = matchNode;
break;
}
}
if (nodeToRemove != null)
nodeToRemove.Remove();
}
}
}
{
// 遍历所有Map Functionalities
foreach (IMapFunctionality mapFunct in map.GetFunctionalities())
{
string layerId = GetLayerId(layerName, mapFunct);
// 设置图层不可见
if (!String.IsNullOrEmpty(layerId))
mapFunct.SetLayerVisibility(layerId, false);
}
// 找到和Map关联的Toc
Toc tocCtrl = FindControlOfType(typeof(Toc), Page.Controls) as Toc;
if (tocCtrl != null && tocCtrl.BuddyControl == map.ID)
{
// 移除之前隐藏图层在Toc中的节点
foreach (TreeViewPlusNode resource in tocCtrl.Nodes)
{
TreeViewPlusNode nodeToRemove = null;
foreach (TreeViewPlusNode layerNode in resource.Nodes)
{
TreeViewPlusNode matchNode = FindNodeRecursive(layerNode, layerName);
if (matchNode != null)
{
nodeToRemove = matchNode;
break;
}
}
if (nodeToRemove != null)
nodeToRemove.Remove();
}
}
}
RemoveItemFromToolbar()
private void RemoveItemFromToolbar(Toolbar toolbar, string toolbarItemName)
{
for (int i=0; i<toolbar.ToolbarItems.Count; i++)
{
if (toolbar.ToolbarItems[i].Name == toolbarItemName)
{
toolbar.ToolbarItems.RemoveAt(i);
break;
}
}
}
{
for (int i=0; i<toolbar.ToolbarItems.Count; i++)
{
if (toolbar.ToolbarItems[i].Name == toolbarItemName)
{
toolbar.ToolbarItems.RemoveAt(i);
break;
}
}
}
RemoveTask()
private void RemoveTask(TaskManager taskManager, string taskName)
{
string menuId = "";
foreach (Control ctl in taskManager.Controls)
if (ctl.ID == taskToRemove)
{
FloatingPanel queryTask = ctl as FloatingPanel;
if (queryTask != null)
menuId = queryTask.Title;
// 从TaskManager中移除Task
taskManager.Controls.Remove(ctl);
}
Control mCtl = FindControlRecursive(taskManager.Page, taskManager.BuddyControl);
if (mCtl != null && mCtl is Menu)
{
Menu menu = (Menu)mCtl;
for (int i = 0; i < menu.Items.Count; i++)
{
if (menu.Items[i].Text == menuId)
{
menu.Items.RemoveAt(i);
break;
}
}
}
}
{
string menuId = "";
foreach (Control ctl in taskManager.Controls)
if (ctl.ID == taskToRemove)
{
FloatingPanel queryTask = ctl as FloatingPanel;
if (queryTask != null)
menuId = queryTask.Title;
// 从TaskManager中移除Task
taskManager.Controls.Remove(ctl);
}
Control mCtl = FindControlRecursive(taskManager.Page, taskManager.BuddyControl);
if (mCtl != null && mCtl is Menu)
{
Menu menu = (Menu)mCtl;
for (int i = 0; i < menu.Items.Count; i++)
{
if (menu.Items[i].Text == menuId)
{
menu.Items.RemoveAt(i);
break;
}
}
}
}
这样用户通过不同的身份登录就可以看到各自的内容信息。通过ASP.Net登录控件也可以实现部分效果,如LoginView,可以将QueryAttributeTask拖到LoginView上,对应着manager用户,这样存在一个弊端,就是不能在TaskManager中使用该Task。
思路就是这样了,你是不是也有这样的需求呢,试试吧。
Flyingis @ China
email: dev.vip#gmail.com
blog: http://flyingis.cnblogs.com/