一 ASP.net 2.0
1. 机制
membership,成员身份服务,提供了用于创建和管理用户帐户。
Roles,角色
网站的具体权限是根据其角色来区分的。如Web.sitemap中根据角色区分不同的SiteMap数据源,在Web.config中配置不同角色对不同目录或页面的访问权限
可以通过Website->ASP.NET Congfiguration->Security->Roles来设置帐号所属的角色组。
权限设置可以Website->ASP.NET Congfiguration->Security->Roles中设置,或直接通过配置文件。
通过配置文件设置角色权限范例:
Web.sitemap:
<siteMapNode url="Admin/" title="Site Administration" roles="Administrators">
<siteMapNode url="Admin/Settings.aspx" title="My Profile" roles="Administrators" />
</siteMapNode>
Web.config:
<location path="Admin">
<system.web>
<authorization>
<allow roles="Administrators"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
另外,Website->ASP.NET Congfiguration->Security->Access Rules也可以设置目录级别的角色权限
2. 控件
Login,登陆控件
LoginView, 根据不同的登陆用户或不同的角色,显示不同的模版内容
LoginName, 登陆用户名
LoginStatus,根据不同的登陆状态显示不同的链接(如login, logout)
范例代码:
//如果登陆者属于Administrators,则只显示相应RoleGroup中的内容
<asp:LoginView ID="LoginView" runat="server">
<AnonymousTemplate>
<asp:HyperLink ID="LoginLink" runat="server" NavigateUrl="~/Login.aspx">Login</asp:HyperLink>
|
<asp:HyperLink ID="RegisterLink" runat="server" NavigateUrl="~/Register.aspx">Register</asp:HyperLink>
</AnonymousTemplate>
<LoggedInTemplate>
Welcome,
<asp:LoginName ID="MemberName" runat="server" />
|
<asp:LoginStatus ID="MemberLoginStatus" runat="server" />
</LoggedInTemplate>
<RoleGroups>
<asp:RoleGroup Roles="Administrators">
<ContentTemplate>
<asp:LoginName ID="LoginName2" runat="server" FormatString="You are logged in as {0}. "/>
</ContentTemplate>
</asp:RoleGroup>
</RoleGroups>
</asp:LoginView>
3. 身份验证和授权
3.1 概念
a. 身份验证 authentication 和 授权 authorization
身份验证是识别调用者或客户的身份,包括身份标识(ID)和密码的检查。身份验证通过后,通常会收到一个安全标记(securiry token),这样,以后其身份就不必再验了。
授权是检查某一特定身份可以使用多少实际资源的过程。
b. 标识 identity 和主体 principal
identity , 回答了”谁是用户?“
principal , 用户标识信息和多个依附于该用户的角色信息的组合体。角色信息通常与做某事的特定权限有关,回答了”用户能够做什么?“
有4种标识对象 FormIdentity GenericIdentity PassportIdentity WindowsIdentity
两种主体 GenericPrincipal WindowsPrincipal
3.2 相关类
a. 授权相关类
System.Security.Permissions.SecurityAttribute ,通过为类中的方法标注特性标签(attribute tag)的方式,来实施按角色划分级别的安全授权方案。要使用SecurityAttribute,必须定义可以调用受保护方法的用户或用户角色。同时为 CodeAccessSecurityAttribute 派生自的声明安全性指定基属性类。
System.Security.Permissions.PrincipalPermissionAttribute ,可用于以声明方式要求运行您的代码的用户属于指定的角色或者已经过身份验证。只能类、方法,而不能应用于程序集级别上。
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN/Administrators"]
public static void SecureMethod(){}
b. 标识对象
有4种标识对象 FormIdentity GenericIdentity PassportIdentity WindowsIdentity
c. 主体类
两种主体 GenericPrincipal WindowsPrincipal
WindowsPrincipal 是个特殊的 GenericPrincipal ,只能和 WindowsIdentity 一起工作。 WindowsPrincipal 可以利用已存在的诸如活动目录等Windows安全机制,来获得指定用户的角色信息。
WindowsPrincipal 可以通过提供 WindowsIdentity 对象,自动从用户账户库中提取资格信息。而 GenericPrincipal 必须显式的提供用户的角色信息队列。
GenericPrincipal ...{GenericIdentity gID = new GenericIdentity("Mike");
string[] roles = new String[3]...{"Users", "Managers", "Administrators"};
GenericPrincipal gPrincipal = new GenericPrincipal(gID, roles);
if (gPrincipal.IsInRole("Administrator"))...{Console.WriteLine("super user!");}
}
WindowsPrincipal ...{WindowsIdentity wID = WindowsIdentity.GetCurrent();
WindowsPrincipal wPrincipal = new WindowsPrincipal(wID);
if (wPrincipal.IsInRole(@"MyDomainAdministrator"))...{Console.WriteLine("super user!");}
}
4. 其他相关代码
在当前进程中用另外一个用户登陆,和活动目录查询角色组
[DllImport(@"advapi32.dll")]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out System.IntPtr phToken);
sample...{
bool loggedOn = LogonUser(
// User name.
userName,
// Computer or domain name.
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
// The user token for the specified user is returned here.
out token);
if (loggedOn == false)
...{
throw new System.Security.SecurityException(userName + " logon failed" );
}
}
<ADDirectoryEntry>WinNT://mylocalcomputer,computer</ADDirectoryEntry>
public bool IsInRole(string role)
...{
StringCollection groupCollection = new StringCollection();
DirectoryEntry obEntry = new DirectoryEntry(searchQuery);
//search on the user name. if user doesn't exist, an exception will be thrown
DirectoryEntry obUser = obEntry.Children.Find(identity.Name,"user");
//retrieve the group information for the given user
object groups = obUser.Invoke("Groups");
//loop through each group object to retrieve the group name
foreach (object o in (IEnumerable)groups)
...{
DirectoryEntry group= new DirectoryEntry(o);
groupCollection.Add(group.Name);
}
//check if the role is part of the groups the user belongs to.
return groupCollection.Contains(role);
}
二. dot net 1.1的授权代码片段
1 FormsAuthentication
在验证过后(数据库检查等),设置Cookie: FormsAuthentication.SetAuthCookie(username,persist);
查询是否通过验证:HttpContext.Current.Request.IsAuthenticated
获取当前用户名:HttpContext.Current.User.Identity.Name
注销:
HttpContext.Current.Response.Cookies.Clear();
System.Web.Security.FormsAuthentication.SignOut();
2 Windows 验证
构造请求:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("Login.aspx");
webRequest.Credentials = new NetworkCredential(User, Pwd);
获取验证成功后的COOKIE:
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
authenticateCookieText = webResponse.Headers.Get("Set-Cookie");
把验证信息附带到COOKIE中发送出去:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Set("Accept-Encoding","gzip");
webRequest.CookieContainer = new CookieContainer();
webRequest.CookieContainer.SetCookies(webRequest.Address, authenticateCookieText);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();