会员
众包
新闻
博问
闪存
赞助商
HarmonyOS
Chat2DB
所有博客
当前博客
我的博客
我的园子
账号设置
会员中心
简洁模式
...
退出登录
注册
登录
韩星
学习交流.Net、Java、PHP、Linux、Android相关知识
技术不是工作的全部,工作不是生活的全部,用技术改变生活!
博客园
首页
新随笔
联系
订阅
管理
[转][.NET 基于角色安全性验证] 之一:基础知识
.NET 基于角色安全性验证的核心是主体(Principal)和标识(Identity)对象,其中主体负责角色或者组的验证,标识对象封装有关正在验证的用户或实体的信息。角色安全性验证通过生成可供当前线程使用的主体信息来支持授权,其中主体用关联的标识进行构造。
public
interface
IPrincipal
{
//
Methods
bool
IsInRole(
string
role);
//
Properties
IIdentity Identity
{
get
; }
}
public
interface
IIdentity
{
//
Properties
string
AuthenticationType
{
get
; }
bool
IsAuthenticated
{
get
; }
string
Name
{
get
; }
}
在 .NET Framework 中提供了两组 Principal
/
Identity 类型,分别是基于 Windows 操作系统账户的 WindowsPrincipal
/
WindowsIdentity,以及用来进行自定义验证的 GenericPrincipal
/
GenericIdentity。
主体(Principal)对象在应用程序域(AppDomain)中绑定到调用上下文(CallContext)对象,缺省情况下,应用程序域会自动创建采取默认安全策略的 GenericPrincipal
/
GenericIdentity对象,同时主体(Principal)对象引用从创建线程自动复制到新线程的调用上下文(CallContext)中。我们可以通过 Thread.CurrentPrincipal 获得缺省主体(Principal)和标识(Identity)对象信息。
Console.WriteLine(Thread.CurrentPrincipal);
Console.WriteLine(Thread.CurrentPrincipal.Identity);
接下来,我们使用 WindowsPrincipal
/
WindowsIdentity 做一些简单的验证,同时为了进一步理解基于角色安全性验证的用途。
static
void
Test()
{
Console.WriteLine(
"
Test
"
);
}
static
void
Main(
string
[] args)
{
Test();
}
我们修改上面这段代码,要求 Test() 方法必须是拥有管理员权限才能调用。
1
. 我们使用 System.Security.Permissions.PrincipalPermissionAttribute 特性为 Test 方法加上角色验证标记,要求调用用户(Windows 操作系统登录用户)必须是
"
Administrators
"
组成员。
2
. 在 Main 方法中设置线程的主体和标识对象。WindowsIdentity.GetCurrent() 用来获取当前登录用户的标识对象,如果登录用户属于 Adminstrators 组,则 Test() 方法正常调用,否则会触发 SecurityException 异常(我们可以使用 WindowsIdentity.GetAnonymous() 获取匿名用户标识对象来触发该异常)。
[PrincipalPermission(SecurityAction.Demand, Role
=
"
Administrators
"
)]
static
void
Test()
{
Console.WriteLine(
"
Test
"
);
}
static
void
Main(
string
[] args)
{
Thread.CurrentPrincipal
=
new
WindowsPrincipal(WindowsIdentity.GetCurrent());
Test();
}
我们还可以使用其他的方法来做到这一点。
1
. 使用 PrincipalPermission 对象替换 PrincipalPermissionAttribute,我们就可以使用动态权限验证,可以将用户名或者角色参数写入配置文件中。
2
. 使用 AppDomain.CurrentDomain.SetThreadPrincipal 设置主体对象和 Thread.CurrentPrincipal 作用相同。我们还可以直接使用 AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal) 让系统自动使用当前登录用户名创建 WindowsPrincipal
/
WindowsIdentity。
static
void
Test()
{
new
PrincipalPermission(
null
,
"
Administrators
"
).Demand();
Console.WriteLine(
"
Test
"
);
}
static
void
Main(
string
[] args)
{
AppDomain.CurrentDomain.SetThreadPrincipal(
new
WindowsPrincipal(WindowsIdentity.GetCurrent()));
Test();
}
或者
static
void
Test()
{
new
PrincipalPermission(
null
,
"
Administrators
"
).Demand();
Console.WriteLine(
"
Test
"
);
}
static
void
Main(
string
[] args)
{
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
Test();
}
上面的例子都是基于角色或者组的验证,当然我们还可以基于用户进行验证。
[PrincipalPermission(SecurityAction.Demand, Name
=
"
YUHEN\\q.yuhen
"
)]
new
PrincipalPermission(
"
YUHEN\\q.yuhen
"
,
null
).Demand();
当然,我们还可以同时用 role 和 name。PrincipalPermission 对象比 PrincipalPermissionAttribute 更加灵活,我们可以使用它进行多个权限的并集运算,以及进行 xml 转换等。
下面是使用 GenericPrincipal
/
GenericIdentity 改写的代码。
//
[PrincipalPermission(SecurityAction.Demand, Name="q.yuhen", Role="admins")]
static
void
Test()
{
new
PrincipalPermission(
null
,
"
Administrators
"
).Demand();
Console.WriteLine(
"
Test
"
);
}
static
void
Main(
string
[] args)
{
//
创建自定义用户标识对象。
GenericIdentity identity
=
new
GenericIdentity(
"
q.yuhen
"
);
//
创建主体对象,并指定所拥有的角色数组。
string
[] roles
=
new
string
[]
{
"
admins
"
}
;
GenericPrincipal principal
=
new
GenericPrincipal(identity, roles);
//
设定主体。
AppDomain.CurrentDomain.SetThreadPrincipal(principal);
Test();
}
除了使用上述方法外,某些时候我们并不希望触发 SecurityException 异常,我们希望能给出另外的执行策略,那么可以直接使用 Principal.InRole 以及 Identity.Name 了。
static
void
Test()
{
if
(Thread.CurrentPrincipal.IsInRole(
"
admins
"
)
&&
Thread.CurrentPrincipal.Identity.Name
==
"
q.yuhen
"
)
{
Console.WriteLine(
"
Test
"
);
}
else
{
Console.WriteLine(
"
您没有执行权限!
"
);
}
}
总结一下,基于角色的安全检查有三种方法。
1
. 使用命令式安全检查。该方法主要是通过 PrincipalPermission.Demand() 方法进行。
2
. 使用声明性安全检查。通过 PrincipalPermissionAttribute 特性指定运行所需角色和用户名。
3
. 直接访问 Principal 对象。访问 Thread.CurrentPrincipal 属性获得当前主体和标识对象,并调用其相关方法和属性进行进一步验证。
有关细节可参考 MSDN 文档,角色验证主要用于 ASP.NET 环境,雨痕将在后续 Blog 中做进一步说明。
posted @
2008-06-11 22:22
wenanry
阅读(
433
) 评论(
0
)
收藏
举报
刷新页面
返回顶部
公告